赞
踩
概念
权限管理,这是每个软件系统都会涉及到的,而且权限管理的需求本质往往都是一样,不同的角色拥有不同的权限,只要你充当了某个角色,你就拥有了相对应的功能。
RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。
简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。
这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般都是多对多的关系
简介
https://docs.spring.io/spring-security/site/docs/4.2.10.RELEASE/guides/html5/helloworld-xml.html
SpringSecurity融合Spring技术栈,提供JavaEE应 用的整体安全解决方案;
Spring Security为基于Java EE的企业软件应用提供全面的安全服务。
Spring Security只需要少量配置,就能构建一个强大的安全的应用系统。
目前市面上受欢迎的两个安全框架:Apache Shiro、SpringSecurity;
SpringSecurity可以无缝整合Spring应用,具有强大的自动化web安全管控功能。而Shiro是一个轻量级强大的安全框架,可以脱离web应用来提供安全管控,但是对于web的一些定制安全需要手动编写;SpringBoot底层默认整合SpringSecurity作为安全框架,所以我们推荐web应用使用SpringSecurity来控制安全;
概念
认证
authentication:身份验证
“身份验证”是指建立主体(principal)的过程,主体就是他们声称是谁(“主体”通常指用户、设备或在应用程序中可以执行动作的其他系统)。也就是“证明你是谁”
授权
authorization:授权
“授权”是指确定主体(principal)是否被允许执行系统中某个动作的过程。 也就是“你能做什么!”
为了达到“授权”决策(安全框架决定你是否有权限做此事),“身份验证”(authentication)过程已经建立了主体的身份(Principal)
细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器, 并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
1.在parent中添加spring security的依赖
- <!-- spring-security依赖包 -->
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-web</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-config</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-taglibs</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
2.在web.xml中配置spring Security的过滤器进行控制
- <filter>
- <filter-name>springSecurityFilterChain</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- </filter>
-
- <filter-mapping>
- <filter-name>springSecurityFilterChain</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
3.填写config配置类
- package com.atguigu.atcrowdfunding.config;
-
- import java.io.IOException;
-
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.access.AccessDeniedException;
- import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
- import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.web.access.AccessDeniedHandler;
-
- @Configuration // 把该类当成配置文件
- @EnableWebSecurity // 开启SpringSecurity
- @EnableGlobalMethodSecurity(prePostEnabled=true)//开启细粒度权限
- public class AtcrowdfundingSecurityConfig extends WebSecurityConfigurerAdapter {
-
- @Autowired
- private UserDetailsService userDetailsService;
-
- // 认证与授权
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.userDetailsService(userDetailsService);
-
- }
-
- // 配置信息
- @Override
- protected void configure(HttpSecurity http) throws Exception {
-
- http.authorizeRequests()
- // 放行的请求
- .antMatchers("/static/**", "/welcome.jsp", "/login", "/index").permitAll()
- // 剩下的请求必须验证
- .anyRequest().authenticated();
-
- // 自定义登录页面
- http.formLogin().loginPage("/login")
- .usernameParameter("loginacct").
- passwordParameter("userpswd")// 登录参数的属性名称
- .loginProcessingUrl("/doLogin")// 登录的跳转路径
- .defaultSuccessUrl("/main");// 跳转的页面
-
- // 禁用csrf
- http.csrf().disable();// 暂时
-
- // //出现异常显示的页面
- http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
-
- @Override
- public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
- String header = request.getHeader("X-Requested-With");
- if("XMLHttpRequest".equals(header)) {
- response.getWriter().print("403");
- }else {
- request.getRequestDispatcher("/WEB-INF/jsp/error/error403.jsp").forward(request, response);;
- }
- }
- });
-
- }
-
- }
4.实现查询数据库进行用户权限认证:
-
- import java.util.HashSet;
- import java.util.List;
- import java.util.Set;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.authority.SimpleGrantedAuthority;
- import org.springframework.security.core.userdetails.User;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
- import org.springframework.stereotype.Component;
-
- import com.atguigu.atcrowdfunding.bean.TAdmin;
- import com.atguigu.atcrowdfunding.bean.TAdminExample;
- import com.atguigu.atcrowdfunding.bean.TAdminExample.Criteria;
- import com.atguigu.atcrowdfunding.bean.TPermission;
- import com.atguigu.atcrowdfunding.bean.TRole;
- import com.atguigu.atcrowdfunding.mapper.TAdminMapper;
- import com.atguigu.atcrowdfunding.mapper.TPermissionMapper;
- import com.atguigu.atcrowdfunding.mapper.TRoleMapper;
-
- //实现查询数据库的用户权限的认证
- @Component
- public class MyUserDetailsService implements UserDetailsService{
-
- @Autowired
- private TAdminMapper tAdminMapper;
-
- @Autowired
- private TRoleMapper tRolemapper;
-
- @Autowired
- private TPermissionMapper tPermissionMapper;
-
- //查询用户的角色和权限数据
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- TAdminExample example=new TAdminExample();
- Criteria criteria = example.createCriteria();
- criteria.andUsernameEqualTo(username);
- //根据用户名查询用户的信息
- List<TAdmin> list = tAdminMapper.selectByExample(example);
- TAdmin tAdmin=null;
- if(list!=null&&list.size()==1) {
- tAdmin=list.get(0);
- }
-
- //查询用户的角色
- List<TRole> roleList=tRolemapper.queryRoleByAdminId(tAdmin.getId());
- List<TPermission>permissionList=tPermissionMapper.queryPermissionByAdminId(tAdmin.getId());
-
- //查询用户的角色对应的权限
- //List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_初级程序员","ROLE_中级程序员");
-
- Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
- for (TRole role : roleList) {
- authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getName()));
- }
- for (TPermission permission : permissionList) {
- authorities.add(new SimpleGrantedAuthority(permission.getName()));
- }
-
- return new User(tAdmin.getLoginacct(), tAdmin.getUserpswd(), authorities);
- }
-
- }
6.对权限控制进行细粒度控制:(添加注解).
@EnableWebSecurity:开启 Spring Security 注解
@EnableGlobalMethodSecurity(prePostEnabled=true):开启全局的细粒度方法级别权限控制功能
@PreAuthorize:方法执行前检查
hasRole是角色,hasAuthority是具体的操作,这两个都可以是多个,细粒度控制可以具体到每一个角色的具体操作步骤。动态的不影响项目代码的逻辑结构。
在使用Springsecurity的细粒度控制时由于Springsecurity是被Spring扫描的,而controller是被SpringMVC扫描的,父不能访问子容器中的内容,所以细粒度注解不能生效,需要在web.xml中更改配置
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。