一.spring security的最基本配置
###1.引入spring security的依赖
<dependencies>
<!-- ... other dependency elements ... -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
</dependencies>
2.spring security的核心模块
- org.springframework.security.core–>核心
- org.springframework.security.access–>访问,即authorization 的作用
- org.springframework.security.authentication–>验证
- org.springframework.security.provisioning–>配置
除此之外,还有LDAP、CAS、ACL等模块
3.创建基本的过滤器
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
重写configure方法(注意是AuthenticationManagerBuilder参数)
4.注册过滤器
这个类的作用相当于在web.xml中注册spring security的filter
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
初始化WebSecurity,加载WebSecurityConfigurers
public class MvcWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class };
}
}
二.配置表单登录
1.配置流程
首先创建自定义登录页面login.html,并放在resources/template目录下(springboot),并加入themeleaf模板引擎
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
yml配置文件中:
spring:
mvc:
view:
prefix: /
suffix: .html
然后创建SecurityConfig类:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/index.html").permitAll() //访问index.html不要权限验证
.anyRequest().authenticated() //其他所有路径都需要权限校验
.and()
.csrf().disable() //默认开启,这里先显式关闭
.formLogin() //内部注册 UsernamePasswordAuthenticationFilter
.loginPage("/login.html") //表单登录页面地址
.loginProcessingUrl("/login") //form表单POST请求url提交地址,默认为/login
.passwordParameter("password") //form表单用户名参数名
.usernameParameter("username") //form表单密码参数名
.successForwardUrl("/success.html") //登录成功跳转地址
.failureForwardUrl("/error.html") //登录失败跳转地址
//.defaultSuccessUrl() //如果用户没有访问受保护的页面,默认跳转到页面
//.failureUrl()
//.failureHandler(AuthenticationFailureHandler)
//.successHandler(AuthenticationSuccessHandler)
//.failureUrl("/login?error")
.permitAll(); //允许所有用户都有权限访问登录页面
}
}
下面对上面的configure方法来介绍
2.configure(HttpSecurity http)方法简介
####(1)formLogin()方法
这个方法的作用是在spring security注册一个UsernamePassowrdAuthenticationFilter,用于对用户表单中提交的用户名/密码参数来进行校验
在UsernamePasswordAuthenticationFilter中,指定了form表单的method属性必须为post,同时指定了form的action属性值默认/login。当用户表单提交时
####(2)loginPage方法
在前面的配置中,直接指定了一个静态页面login.html作为登录页面,同时,也可以定义一个controller,返回一个view视图来代表登录页面,name这个loginPage的参数就是这个controller的RequestMapping
####(3)usernameParameter、passwordParameter方法
这两个方法主要是用来定义提交表单的参数名称
formLogin()
.usernameParameter("user")
.passwordParameter("pwd")
如果改成这样,那么在login.html中:
<input type='text' name='user'/>
<input type='text' name='pwd'/>
(4)loginProcessingUrl方法
修改表单提交的地址
formLogin()
.loginProcessingUrl("/auth/login")
(5)successForwardUrl,failureForwardUrl,defaultSuccessUrl方法
FormLoginConfigurer的successForwardUrl、failureForwardUrl方法分别用于定义登录成功和失败的跳转地址
.formLogin()
.successForwardUrl("/success.html")
.failureForwardUrl("/error.html")
默认逻辑:
-
如果用户没有访问受保护的资源,例如通过地址栏直接访问登录页面,那么登录后,就默认跳转到首页。
-
用户在访问一个受保护的页面时(称之为目标页面:target page),如果需要验证,就跳转到登录页面。如果登录成功,那么就久直接跳转到目标页面,如果登录失败,还继续停留在登录页面。
三.请求授权
1.configure(HttpSecurity http )方法
protected 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()方法有很多子方法,每个子匹配器将会按照声明的顺序起作用。
-
指定用户可以访问的多个url模式。特别的,任何用户可以访问以"/resources"开头的url资源,或者等于"/signup"或about
-
任何以"/admin"开头的请求限制用户具有 "ROLE_ADMIN"角色。你可能已经注意的,尽管我们调用的hasRole方法,但是不用传入"ROLE_"前缀
-
任何以"/db"开头的请求同时要求用户具有"ROLE_ADMIN"和"ROLE_DBA"角色。
-
任何没有匹配上的其他的url请求,只需要用户被验证。
2.ant风格路径语法
Path | Description |
---|---|
/app/*.x | 匹配(Matches)所有在app路径下的.x文件 |
/app/p?ttern | 匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern |
/**/example | 匹配(Matches) /app/example, /app/foo/example, 和 /example |
/app/**/dir/file. | 匹配(Matches) /app/dir/file.jsp, /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java |
/**/*.jsp | 匹配(Matches)任何的.jsp 文件 |
3.注销处理
当使用 WebSecurityConfigurerAdapter,注销功能将会被自动应用,也就是说,就算不写也有用。默认情况下访问/logout将会将用户注销,包含的内容有:
-
使HttpSession失效
-
清空已配置的RememberMe验证
-
清空 SecurityContextHolder
-
重定向到 /login?success
自定义注销:
protected void configure(HttpSecurity http) throws Exception {
http
.logout() 1
.logoutUrl("/my/logout") 2
.logoutSuccessUrl("/my/index") 3
.logoutSuccessHandler(logoutSuccessHandler) 4
.invalidateHttpSession(true) 5
.addLogoutHandler(logoutHandler) 6
.deleteCookies(cookieNamesToClear) 7
.and()
...
}
下面对序号标注的进行说明:
1、提供注销支持,当使用 WebSecurityConfigurerAdapter时这将会被自动应用
2、触发注销操作的url,默认是/logout。如果开启了CSRF保护(默认开启),那么请求必须是POST方式。
3、注销操作发生后重定向到的url,默认为 /login?logout。
4、让你指定自定义的 LogoutSuccessHandler。如果指定了, logoutSuccessUrl() 将会被忽略。
5、指定在注销的时候是否销毁 HttpSession 。默认为True。
6、添加一个 LogoutHandler。默认情况下, SecurityContextLogoutHandler 被作为最后一个 LogoutHandler 。
7、允许指定当注销成功时要移除的cookie的名称。这是显式店家 CookieClearingLogoutHandler 的一种快捷处理方式
4.多个HttpSecurity
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
1、按照正常的方式配置验证
2、创建一个包含 @Order的 WebSecurityConfigurerAdapter实例来指定哪一个 WebSecurityConfigurerAdapter应该被首先考虑。
3、 http.antMatcher表明这个 HttpSecurity 只适用于以 /api/开头的URL。
4、创建另一个 WebSecurityConfigurerAdapter实例。如果URL没有以 /api/开头,这个配置将会被使用。这个配置在 ApiWebSecurityConfigurationAdapter 之后生效,因为其含有一个 @Order值为1.没有 @Order默认是最后一个生效。