spring-security详解
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
WebSecurityConfigurerAdapter在configure(HttpSecurity http)方法中提供了一个默认的配置,看起来和下面类似:
@Configuration
@EnableWebSecurity
//@EnableWebSecurity完成的工作便是加载了WebSecurityConfiguration,AuthenticationConfiguration这两个核心配置类,也就此将spring security的职责划分为了配置安全信息,配置认证信息两部分。
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() 1⃣️
.anyRequest().authenticated()
.and()
.formLogin() 2⃣️
.and()
.httpBasic(); 3⃣️
}
1⃣️authorizeRequests()配置路径拦截,表明路径访问所对应的权限,角色,认证信息。
2⃣️formLogin()对应表单认证相关的配置
3⃣️httpBasic()可以配置basic登录
上述是一个使用Java Configuration配置HttpSecurity的典型配置,其中http作为根开始配置,每一个and()对应了一个模块的配置(等同于xml配置中的结束标签)
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and();
}
*除了“/”,”/home”(首页),”/login”(登录),”/logout”(注销),之外,其他路径都需要认证。
指定“/login”该路径为登录页面,当未登录的用户尝试访问任何受保护的资源时,都会跳转到“/login”。
防止CSRF攻击
Session Fixation protection
Security Header(添加一系列和Header相关的控制)
HTTP Strict Transport Security for secure requests
集成X-Content-Type-Options
缓存控制
集成X-XSS-Protection.aspx)
X-Frame-Options integration to help prevent Clickjacking(iframe被默认禁止使用)
*
@EnableWebSecurity是一个组合注解,查看源码
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = { java.lang.annotation.ElementType.TYPE })
@Documented
@Import({ WebSecurityConfiguration.class,
SpringWebMvcImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
/**
* Controls debugging support for Spring Security. Default is false.
* @return if true, enables debug support with Spring Security
*/
boolean debug() default false;
}
@Import是springboot提供的用于引入外部的配置的注解,可以理解为:@EnableWebSecurity注解激活了@Import注解中包含的配置类。
<1> SpringWebMvcImportSelector的作用是判断当前的环境是否包含springmvc,因为spring security可以在非spring环境下使用,为了避免DispatcherServlet的重复配置,所以使用了这个注解来区分。
<2> WebSecurityConfiguration顾名思义,是用来配置web安全的
<3> @EnableGlobalAuthentication注解的源码如下
@Import(AuthenticationConfiguration.class)
@Configuration
public @interface EnableGlobalAuthentication {
}
@EnableWebSecurity完成的工作便是加载了WebSecurityConfiguration,AuthenticationConfiguration这两个核心配置类,也就此将spring security的职责划分为了配置安全信息,配置认证信息两部分。
WebSecurityConfiguration是spring security的核心过滤器(使用了代理模式来实现安全过滤)
@Configuration
public class WebSecurityConfiguration {
public Filter springSecurityFilterChain() throws Exception {
boolean hasConfigurers = webSecurityConfigurers != null
&& !webSecurityConfigurers.isEmpty();
if (!hasConfigurers) {
WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
.postProcess(new WebSecurityConfigurerAdapter() {
});
webSecurity.apply(adapter);
}
return webSecurity.build();
}
}
2018-10-15 19:56:45.480 INFO 7690 --- [main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1,
[org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1fd73dcb,
org.springframework.security.web.context.SecurityContextPersistenceFilter@5ab70df7,
org.springframework.security.web.header.HeaderWriterFilter@c0a8787,
org.springframework.security.web.authentication.logout.LogoutFilter@1d86b636,
org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5a3d52a0,
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3f31cf8f,
org.springframework.security.web.authentication.AnonymousAuthenticationFilter@54c697c,
org.springframework.security.web.session.SessionManagementFilter@72e9f0f7,
org.springframework.security.web.access.ExceptionTranslationFilter@52f71d2,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor@5fdff4f1]
启动springboot项目,从启动日志发现spring security已经开启了上述过滤器。主要解析下UsernamePasswordAuthenticationFilter这个过滤器的源码
UsernamePasswordAuthenticationFilter过滤器主要对表单提交的username与password封装为token,并进行一系列的认证。继承了AbstractAuthenticationProcessingFilter类。
- UsernamePasswordAuthenticationFilter构造方法生成了一个url为/login,提交方式为post的表单。
- attemptAuthentication方法吧username与password封装成一个UsernamePasswordAuthenticationToken。这个方法在AbstractAuthenticationProcessingFilter这个类的doFilter里调用,主要作用是在身份验证发生时执行HTTP会话相关功能,如果身份验证失败,则抛出SESSIDENTICEATION异常。
部分内容摘自http://blog.didispace.com。