前言
Spring Security之前有学习过,但是没有做什么笔记,现在要使用感觉又忘得差不多了,今天做一个简单的使用笔记。
初体验
创建一个Springboot项目,并引入Spring Security依赖。
提供一个接口用于测试:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
启动项目:
控制台输出的那条字符串为默认登录密码,默认登录用户名为user
启动项目并访问/hello
接口,需要登录才能访问:
输入用户名跟控制台输出的字符串密码后就可以正常访问接口。
配置用户名密码
默认的登录用户名为user
,密码为控制台输出的那一串,我们也可以自己自定义配置登录用户名密码,配置方式有以下两种:
- application配置文件配置
- java配置在内存中
- 通过java从数据库加载(这里暂不演示)
application配置文件配置:
spring.security.user.name=pikachues
spring.security.user.password=123
配置完成后重启项目,访问对应接口,用配置的用户名密码登录后即可正常访问。
java配置在内存中:
首先创建一个Security配置文件,并继承WebSecurityConfigurerAdapter
接口
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 认证管理
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("pikachues").roles("ADMIN").password("$2a$10$puj8ZUyTaNOrU8WAOVKTWORh9RxgE38iJHTCw0HX1Q6LJrwkT1bNa")
.and()
.withUser("admin").roles("USER").password("$2a$10$puj8ZUyTaNOrU8WAOVKTWORh9RxgE38iJHTCw0HX1Q6LJrwkT1bNa");
}
}
上面的configure
方法配置了两个用户,用户的密码都是加密之后的字符串(明文123),从 Spring5
开始,强制要求密码要加密,如果非不想加密,可以使用一个过期的 PasswordEncoder
的实例 NoOpPasswordEncoder,但是不建议这么做,毕竟不安全。
Spring Security
中提供了 BCryptPasswordEncoder
密码编码工具,可以非常方便的实现密码的加密加盐,相同明文加密出来的结果总是不同,这样就不需要用户去额外保存盐的字段了,这一点比 Shiro
要方便很多。
WebSecurityConfigurerAdapter
中其他两个经常被重写的方法:
/**
* 安全过滤器链,用的最多
* 一般用于处理登录逻辑
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
}
/**
* 核心过滤器,
* 使用较多的其ignoring() 方法用来忽略 Spring Security 对静态资源的控制。
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
}
HttpSecurity 常用方法
方法 | 说明 |
---|---|
openidLogin() | 用于基于 OpenId 的验证 |
headers() | 将安全标头添加到响应,比如说简单的 XSS 保护 |
cors() | 配置跨域资源共享( CORS ) |
sessionManagement() | 允许配置会话管理 |
portMapper() | 允许配置一个PortMapper(HttpSecurity#(getSharedObject(class))),其他提供SecurityConfigurer的对象使用 PortMapper 从 HTTP 重定向到 HTTPS 或者从 HTTPS 重定向到 HTTP。默认情况下,Spring Security使用一个PortMapperImpl映射 HTTP 端口8080到 HTTPS 端口8443,HTTP 端口80到 HTTPS 端口443 |
jee() | 配置基于容器的预认证。 在这种情况下,认证由Servlet容器管理 |
x509() | 配置基于x509的认证 |
rememberMe | 允许配置“记住我”的验证 |
authorizeRequests() | 允许基于使用HttpServletRequest限制访问 |
requestCache() | 允许配置请求缓存 |
exceptionHandling() | 允许配置错误处理 |
securityContext() | 在HttpServletRequests之间的SecurityContextHolder上设置SecurityContext的管理。 当使用WebSecurityConfigurerAdapter时,这将自动应用 |
servletApi() | 将HttpServletRequest方法与在其上找到的值集成到SecurityContext中。 当使用WebSecurityConfigurerAdapter时,这将自动应用 |
csrf() | 添加 CSRF 支持,使用WebSecurityConfigurerAdapter时,默认启用 |
logout() | 添加退出登录支持。当使用WebSecurityConfigurerAdapter时,这将自动应用。默认情况是,访问URL”/ logout”,使HTTP Session无效来清除用户,清除已配置的任何#rememberMe()身份验证,清除SecurityContextHolder,然后重定向到”/login?success” |
anonymous() | 允许配置匿名用户的表示方法。 当与WebSecurityConfigurerAdapter结合使用时,这将自动应用。 默认情况下,匿名用户将使用org.springframework.security.authentication.AnonymousAuthenticationToken表示,并包含角色 “ROLE_ANONYMOUS” |
formLogin() | 指定支持基于表单的身份验证。如果未指定FormLoginConfigurer#loginPage(String),则将生成默认登录页面 |
oauth2Login() | 根据外部OAuth 2.0或OpenID Connect 1.0提供程序配置身份验证 |
requiresChannel() | 配置通道安全。为了使该配置有用,必须提供至少一个到所需信道的映射 |
httpBasic() | 配置 Http Basic 验证 |
addFilterBefore() | 在指定的Filter类之前添加过滤器 |
addFilterAt() | 在指定的Filter类的位置添加过滤器 |
addFilterAfter() | 在指定的Filter类的之后添加过滤器 |
and() | 连接以上策略的连接器,用来组合安全策略。实际上就是”而且”的意思 |
自定义登录
我们上面有介绍,我们处理登录一般都是通过configure(HttpSecurity http)方法实现。默认HttpSecurity 提供了三种登录方式:
formLogin()
普通表单登录oauth2Login()
基于OAuth2.0
认证/授权协议openidLogin()
基于OpenID
身份认证规范
我们这里以表单登录举例,表单登录的常用配置方法如下:
permitAll(boolean permitAll)
form 表单登录是否放开loginPage(String loginPage)
: 登录页面而并不是接口,对于前后分离模式需要我们进行改造 默认为/login
。loginProcessingUrl(String loginProcessingUrl)
实际表单向后台提交用户信息的 Action,再由过滤器- UsernamePasswordAuthenticationFilter 拦截处理,该 Action 其实不会处理任何逻辑。usernameParameter(String usernameParameter)
用来自定义用户参数名,默认username
。passwordParameter(String passwordParameter)
用来自定义用户密码名,默认password
failureUrl(String authenticationFailureUrl)
登录失败后会重定向到此路径, 一般前后分离不会使用它。
failureForwardUrl(String forwardUrl)
登录失败会转发到此, 一般前后分离用到它。 可定义一个 Controller (控制器)来处理返回值,但是要注意 RequestMethod。defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse)
默认登陆成功后跳转到此 ,如果 alwaysUse 为 true 只要进行认证流程而且成功,会一直跳转到此。一般推荐默认值 falsesuccessForwardUrl(String forwardUrl)
效果等同于上面defaultSuccessUrl
的alwaysUse
为 true 但是要注意RequestMethod
。successHandler(AuthenticationSuccessHandler successHandler)
自定义认证成功处理器,可替代上面所有的 success 方式failureHandler(AuthenticationFailureHandler authenticationFailureHandler)
自定义失败处理器,可替代上面所有的 failure 方式