JavaEE安全框架源码剖析与整合-SpringSecurity篇
安全框架简介
javaEE⽣态中,关于安全的框架主要有两种,Shiro和SpringSecurity,两者之间区别还有很⼤,Shiro是⼀个轻量级框架,可定制化程度较⾼,相对来说使⽤⽐较灵活,新⼿配置起来⽐较复杂,⽽SpringSecurity是Spring⽣态系列的顶级框架,跟Springboot天然集成,整合起来最容易,所以就先学习SpringSecurity的简单整合和使⽤
SpringSecurity整合
项⽬引⼊Spring Security依赖
第⼀步先导⼊SpringSecurtiy的pom依赖,以及跟thymeleaf的整合包
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>as</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
⾃定义Security核⼼配置类
WebSecurityConfigurerAdapter是SpringSecurity的核⼼配置类,Spring的最⼤的特点就是AOP,⾯向切⾯编程,所以在不改变原来的代码上,直接注⼊⼀个bean,从⽽来使⽤框架,所以这⾥创建⼀个配置类SecurityConfig继承⾃WebSecurityConfigurerAdapter,然后项⽬SpringBoot就天然⽆缝集成了SpringSecurity
package fig.securityconfig;
import com.zjy.service.security.CustomUserService;
import com.zjy.utils.MD5Util;
import t.annotation.Bean;
import t.annotation.Configuration;
import org.fig.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.fig.annotation.web.builders.HttpSecurity;
import org.fig.figuration.WebSecurityConfigurerAdapter;
import org.userdetails.UserDetailsService;
import org.pto.password.PasswordEncoder;
/**
* Describe: security 配置
*/
@Configuration
//@EnableWebSecurity
//AOP :
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
UserDetailsService customUserService(){
return new CustomUserService();
}
/**
*  配置认证⽅式
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth)throws Exception {
auth.userDetailsService(customUserService())
//启动密码MD5加密
.passwordEncoder(new PasswordEncoder(){
.passwordEncoder(new PasswordEncoder(){
MD5Util md5Util =new MD5Util();
@Override
public String encode(CharSequence rawPassword){
de((String)rawPassword);
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword){
return encodedPassword.de((String)rawPassword));
}
});
}
/**
*  配置授权规则
* @param http
* @throws Exception
适合新手的spring boot
*/
@Override
protected void configure(HttpSecurity http)throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/index").hasAnyRole("USER","ADMIN")
.antMatchers("/manager").hasRole("ADMIN")
.
antMatchers("/staff").hasRole("USER")
.and()
//loginPage和logoutUrl都是post请求
.formLogin().loginPage("/login_register").failureUrl("/login_register?error").defaultSuccessUrl("/faceCheck")
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/login_register");
//        http.csrf().disable();
//没有权限默认会到登录页⾯
//        http.formLogin();
}
}
这⾥有个细节要格外注意⼀下,在SpringBoot2.1.5以后,SpringSecurtity5.0+之后的新版本中增加了很多的加密⽅式,存在密码加密编码问题,没有配置这个可以会出现问题
然后就是http.formLogin(),SpringSecurity集成页⾯,没有权限的时候会默认跳转到登录页⾯,账号和密码在application.propertis的配置⽂件中配置
spring.sercurity.user.name=admin
spring.sercurity.user.password=123456
忽略拦截
实现忽略拦截只需在上⾯的类中注⼊⼀个bean,并重写源码默认规则
/**
* 忽略拦截
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web)throws Exception {
// 设置拦截忽略url - 会直接过滤该url - 将不会经过Spring Security过滤器链
web.ignoring().antMatchers("/getUserInfo");
// 设置拦截忽略⽂件夹,可以对静态资源放⾏
web.ignoring().antMatchers("/css/**","/js/**");
}
登录业务
public UserDetails loadUserByUsername(String phone){
User user = userRepository.findByPhone(phone);
if(user == null){
throw new UsernameNotFoundException("⽤户不存在");
}
List<SimpleGrantedAuthority> authorities =new ArrayList<>();
for(Role role : Roles()){
authorities.add(new Name()));
System.out.Name());
}
return new org.userdetails.Phone(), Password(), authorities);
}
SpringSecurity源码剖析
说了这么多,其实⼀切都在源码中,如过会看源码的话,这些配置都不是问题,下⾯简单来说下,SpringSecurity中主要的类
记住⼏个类:
WebSecurityConfigurerAdapter ⾃定义Security策略
AuthenticationManagerBuilder: ⾃定义认证策略
@EnableWebSecurity: 开启WebSecurity模式
Spring Security的两个主要⽬标是“认证Authentication”和”授权Authorization“(访问控制),这个概念在所有的安全框架中是互通的
WebSecurityConfigurerAdapter类中有以下⽅法:
在 WebSecurityConfigurerAdapter 这个类⾥⾯可以完成上述流程图的所有配置,主要使⽤就是继承上述⽅法
Spring Security 过滤器链
SpringSecurity 采⽤的是责任链的设计模式,它有⼀条很长的过滤器链。现在对这条过滤器链的各个进⾏说明: WebAsyncManagerIntegrationFilter:将 Security 上下⽂与 Spring Web 中⽤于处理异步请求映射的 WebAsyncManager 进⾏集成。
SecurityContextPersistenceFilter:在每次请求处理之前将该请求相关的安全上下⽂信息加载到 SecurityContextHolder 中,然后在该次请求处理完成之后,将SecurityContextHolder 中关于这次请求的信息存储到⼀个“仓储”中,然后将 SecurityContextHolder 中的信息清除,例如在Session中维护⼀个⽤户的安全信息就是这个过滤器处理的。
HeaderWriterFilter:⽤于将头信息加⼊响应中。
CsrfFilter:⽤于处理跨站请求伪造。
LogoutFilter:⽤于处理退出登录。
UsernamePasswordAuthenticationFilter:⽤于处理基于表单的登录请求,从表单中获取⽤户名和密码。默认情况下处理来⾃ /login 的请求。从表单中获取⽤户名和密码时,默认使⽤的表单 name 值为 username 和 password,这两个值可以通过设置这个过滤器的usernameParameter 和 passwordParameter 两个参数的值进⾏修改。
DefaultLoginPageGeneratingFilter:如果没有配置登录页⾯,那系统初始化时就会配置这个过滤器,并且⽤于在需要进⾏登录时⽣成⼀个登录表单页⾯。BasicAuthenticationFilter:检测和处理 http basic 认证。
RequestCacheAwareFilter:⽤来处理请求的缓存。
SecurityContextHolderAwareRequestFilter:主要是包装请求对象request。
AnonymousAuthenticationFilter:检测 SecurityContextHolder 中是否存在 Authentication 对象,如果不存在为其提供⼀个匿名 Authentication。SessionManagementFilter:管理 session 的过滤器
ExceptionTranslationFilter:处理 AccessDeniedException 和 AuthenticationException 异常。
FilterSecurityInterceptor:可以看做过滤器链的出⼝。
RememberMeAuthenticationFilter:当⽤户没有登录⽽直接访问资源时, 从 cookie ⾥出⽤户的信息, 如果 Spring Security 能够识别出⽤户提供的remember me cookie, ⽤户将不必填写⽤户名和密码, ⽽是直接登录进⼊系统,该过滤器默认不开启。
SpringSecurity 流程图
先来看下⾯⼀个 Spring Security 执⾏流程图,只要把 SpringSecurity 的执⾏过程弄明⽩了,这个框架就会变得很简单:
流程说明

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。