1、配置是在WebSecurityConfigurerAdapter中的configure(HttpSecurity http)方法中提供一个默认的配置
1 | protected void configure(HttpSecurity http) throws Exception { |
上面的默认配置:
- 确保我们应用所有请求都需要用户被认证
- 允许用户进行基于表单的认证
- 允许用户使用http基本验证进行认证
与xml命名配置对比1
2
3
4
5<http>
<intercept-url pattern = "/**" access = "authenticated" />
<form-login />
<http-basic />
</http>
在java中的and()方法相当于xml的标签关闭
2、java配置和表单登录
配置类中需要更新前面配置1
2
3
4
5
6
7
8
9protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login") //*1
.permitALl(); //*2
}
- 指定登录页的路径
- 允许表单登录的所有用户访问登录界面
页面
我们需要创建一个表单,action跳转登录接口。记住loginPage里面配置是我们跳转登录界面,需要的只是get请求。而页面配置的action跳转的接口,是post请求,只要跟登录接口保持一致即可
登录参数和密码如果你没有配置的话。 需要命名为username和password
3、验证请求
当我们需要进行身份验证并且在应用程序的每个url这样做,我们可以通过给http.authorizeRequests()添加多个及诶单来指定多个定制需求到url中1
2
3
4
5
6
7
8
9
10
11protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() //1
.antMatchers("/resources/**", "/signup", "/about").permitAll() //2
.antMatchers("/admin/**").hasRole("ADMIN") //3
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") 4
.anyRequest().authenticated() //5
.and()
// ...
.formLogin();
}
- http.authorizeRequests()天剑antMatchers多个节点
- 指定多个url,可以让任何用户都可以访问的url,以resources开头的,还有”/signup”, “/about”
- admin开头的url只能拥有roleAdmin角色的用户进行访问
- 任何以db开头的需要同时具备admin 和dba角色才能访问
- 尚未匹配的任何 URL 要求用户进行身份验证
4、处理登出
当使用WebSecurityConfigurerAdapter时 注销功能会被自动用上,默认是通过访问/logout,这个操作指定一下动作:
- 使session失效
- 清除所有已经配置的rememberMe认证
- 清除SecurityContextHolder
- 跳转到login?success
当然你也可以定制注销功能
1 | protected void configure(HttpSecurity http) throws Exception { |
- 提供注销支持,使WebSecurityConfigurerAdapter是会自动被应用
- 设置触发注销操作的url,如果csrf保护被启动(默认启动)的话这个请求的方式被限定为post请求
- 注销之后跳转的url,默认是/login?logout
- 定制logoutSuccessHandler,如果指定了,那么logoutSuccessUrl()的设置会被忽略
- 指定是否在注销时让httpSession无效,默认true
- 添加一个logoutHandler,默认是SecurityContextLogoutHandler,会被添加为最后一个 logouthandler
- 允许指定注销成功时将移除cookie
LogoutHandler
流式API提供了一个调用相应的LogoutHandler实现的快捷方式,而不用直接提供LogoutHandler的实现
例如:deleteCookies()允许指定注销成功时要删除的一个或者多个cookie。不应该抛出异常
LogoutSuccessHandler
LogoutSuccessHandler 被LogoutFiler在成功注销后调用,用来进行重定向或者转发相应的目的地。可以抛出异常
5、验证
内存中的身份验证
配置多个用户的例子1
2
3
4
5
6
7@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
JDBC验证
下面的例子假设你已经在应用程序中定义好了DateSource , jdbc-jc示例提供了一个完整的基于JDBC的验证1
2
3
4
5
6
7
8
9
10
11
12@Autowired
private DataSource dataSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource)
.withDefaultSchema()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
6、多个HttpSecurity
可以配置多个HttpSecurity实例,多WebSecurityConfigurationAdapter进行多次扩展
1 | @EnableWebSecurity |
- 配置正常的验证
- 创建一个WebSecurityConfigurerAdapter,包含一个@Order注解,用来指定哪个优先
- http.antMatcher指出,这个HttpSecurity只应用的到以/api开头的url上
- 创建另外一个WebSecurityConfigurerAdapter实例,用于不以/api开头的url,这个顺讯会在ApiWebSecurityConfigurationAdapter之后,因为没有指定@Order值
7、方法安全
EnableGlobalMethodSecurity
我们可以在任何使用@Configuration的实例上是哟好难过@EnableGlobalMethodSecurity注解来启用基于注解的安全性
1 | @EnableGlobalMethodSecurity(securedEnabled = true) |
添加一个注解到一个方法会限制对相应方法的访问
Spring Security的原生注解支持定义一套用户该方法的属性,这些将被传递到AccessDecisionManager来做实际决定
1 | public interface BankService { |
使用如下代码启用JSR-250注解的支持
1 | @EnableGlobalMethodSecurity(jsr250Enabled = true) |
这些都是基本标准,并允许应用简单的基于角色的约束,但是没有spring Security的本地注解的能力。要使用新的基本表达式的语法,可以使用
1 | @EnableGlobalMethodSecurity(prePostEnabled = true) |
和响应java代码
1 | public interface BankService { |
GlobalMethodSecurityConfiguration
有时候需要制定一些比@EnableGlobalMethodSecurity 注解允许的更复杂的操作,我们可以扩展GlobalMethodSecurityConfiguration确保@EnableGlobalMethodSecurity注解出现在你的 子类中
1 | @EnableGlobalMethodSecurity(prePostEnabled = true) |
已配置对象的后续处理
Spring Security的Java配置没有公开每个配置对象的每一个属性,这简化了广大用户的配置。毕竟如果要配置每一个属性,用户可以使用标准的Bean配置。
虽然有一些很好的理由不直接暴露所有属性,用户可能任然需要更多高级配置,为了解决这个Spring Security引入了 ObjectPostProcessor 概念,用来修改或替换Java配置的对象实例。例如:如果你想在FilterSecurityInterceptor里配置filterSecurityPublishAuthorizationSuccess属性,你可以像下面一样:
1 | @Override |















