1.导入坐标
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency> <version>5.0.5.RELEASE</version> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </dependency> <version>5.0.5.RELEASE</version> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> </dependency> <version>5.0.5.RELEASE</version>
2.在web.xml中配置spring提供的用于整合第三方框架的DelegatingFilterProxy,整合Spring Security。
<filter> <!-- DelegatingFilterProxy用于整合第三方框架 整合Spring Security时过滤器的名称必须为springSecurityFilterChain, 否则会抛出NoSuchBeanDefinitionException异常 --> <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.编写spring-security.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!-- http:用于定义相关权限控制 指定哪些资源不需要进行权限校验,可以使用通配符. --> <!--<security:http security="none" pattern="/pages/a.html"/> <security:http security="none" pattern="/pages/**"/>--> <!--配置自定义登陆页面不进行权限校验--> <security:http security="none" pattern="/login.html"/> <!--样式,图片,插件等不校验(登录页面或许会用到,加上权限也没有意义)--> <security:http security="none" pattern="/css/**"/> <security:http security="none" pattern="/img/**"/> <security:http security="none" pattern="/js/**"/> <security:http security="none" pattern="/plugins/**"/> <!-- auto-config:自动配置,如果设置为true,表示自动应用一些默认配置,比如框架会提供一个默认的登录页面 use-expressions:是否使用spring security提供的表达式来描述权限,即hasRole('权限角色名')等,如果配置为false, 在access中配置 '权限角色名' 就可以. --> <security:http auto-config="true" use-expressions="true"> <!--设置在页面可以通过iframe标签访问受保护的页面,spring security默认为不允许访问此标签src对应的页面--> <security:headers> <security:frame-options policy="SAMEORIGIN"/> </security:headers> <!--配置拦截规则,/** 表示拦截所有请求 pattern:描述拦截规则 asscess:指定所需的访问角色或者访问权限 --> <!--只要认证通过就可以访问--> <!--Tips:login页面不在pages包下,在webapp包下,没拦截,可以直接访问.--> <security:intercept-url pattern="/pages/**" access="isAuthenticated()"/> <!--自定义表单的登录信息 form-login login-page:需要加载的自定义的登录页面,需配置不进行权限校验.<security:http security="none" pattern=""/> username-parameter:与自定义登陆页面中的用户名的name属性一致 password-parameter:与自定义登陆页面中的密码的name属性一致 login-processing-url:与登陆页面form表单中的action一致,框架会拦截此路径,进行权限认证. default-target-url:默认跳转的认证成功页面 authentication-failure-url:认证失败页面 --> <security:form-login login-page="/login.html" username-parameter="username" password-parameter="password" login-processing-url="/login.do" default-target-url="/pages/main.html" authentication-failure-url="/login.html" /> <!--csrf:对应CsrfFilter过滤器,disabled:是否启用CsrfFilter过滤器, 如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用403 --> <security:csrf disabled="true"/> <!-- logout:退出登录 logout-url:退出登录操作对应的请求路径 logout-success-url:退出登录后的跳转页面 invalidate-session=true:销毁session --> <security:logout logout-url="/logout.do" logout-success-url="/login.html" invalidate-session="true" /> </security:http> <!--认证管理器,用于处理认证信息--> <security:authentication-manager> <!--认证提供方,执行具体的认证逻辑 (user-service-ref指定spring容器帮我们管理的服务类对象,用注解方式,不用配置<bean>), 在我们创建的服务类SpringSecurityUserService上加上@component交给spring管理,这里爆红 是因为idea工具认为这个类没有,其实这个类已经存在于spring容器中. --> <security:authentication-provider user-service-ref="springSecurityUserService"> <!--指定配置好的密码加密对象策略--> <security:password-encoder ref="passwordEncoder"/> </security:authentication-provider> </security:authentication-manager> <!--配置密码加密对象,利用bcrypt进行加密(常见的加密方式3DES、AES、DES,MD5、SHA1) bean对象配置好后要在认证提供方进行指定 --> <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <!-- 使用注解的方式进行配置 注解配置权限更精细,可以配置到方法上(配置在@requestMapping下) 例如://@PreAuthorize("hasAnyAuthority('add')"),其中hasAnyAuthority表示的是拥有权限.--> <!--****开启注解方式权限控制****--> <security:global-method-security pre-post-annotations="enabled"/> </beans>
4.编写springSecurityUserService接口,实现UserDetailsService,
不用编写controller,由框架完成,username为框架获取前台输入的用户名
@Component public class SpringSecurityUserService implements UserDetailsService { @Autowired private StaffInfoService staffInfoService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //根据用户名获取用户对象 StaffInfoDTO user = staffInfoService.findByUsername(username); //用户为空时返回null if (user == null) { return null; } //创建一个用于存储角色和密码的list授权集合 List<GrantedAuthority> list = new ArrayList<>(); //根据用户得到角色集合 Set<Role> roles = user.getRoles(); //遍历角色集合得到每一个角色 for (Role role : roles) { //将每个角色的关键字加入授权集合中 list.add(new SimpleGrantedAuthority(role.getKeyword())); } //将参数交给spring的User对象中 org.springframework.security.core.userdetails.User securityUser = new org.springframework.security.core.userdetails.User(username, "{noop}" + user.getPassword(), list); return securityUser; } }
//Tips:{noop}表示密码明文显示,一般用于在数据库中是明文保存的密码,没尽兴任何加密.
这时spring-security中的配置文件也要修改,删去加密配置
以上配置的是用户用由不同角色,可以访问的页面不同.需要建立用户表user和角色表role,并建立中间关系表,user_role>另外user.java要建立与角色对象role.java的对应关系,
private Set<Role> roles;//角色集合
对于配置不同权限的用户访问不同方法的需求如下:
@PreAuthorize("hasAnyAuthority('add')")
需要在数据库中建立权限表permission,配置角色拥有那些权限,然后再方法上加上改注释即可.
需要在role.java中建立与role的对应关系
private Set<permission> permissions;//权限集合