SpringSecurity自定义UsernamePasswordAuthenticationFilter
UsernamePasswordAuthenticationFilter介绍
UsernamePasswordAuthenticationFilter是AbstractAuthenticationProcessingFilter针对使用用户名和密码进行身份验证而定制化的一个过滤器。其添加是在调用http.formLogin()时作用,默认的登录请求pattern为"/login",并且为POST请求。当我们登录的时候,也就是匹配到loginProcessingUrl,这个过滤器就会委托认证管理器authenticationManager来验证登录。
自定义UsernamePasswordAuthenticationFilter
这里我的需求是通过自定义UsernamePasswordAuthenticationFilter实现对前端传过来的密码进行RSA私钥解密,并且因为登录地址不是"/login",所以继承的是AbstractAuthenticationProcessingFilter,如果登录地址为默认,那么可直接继承UsernamePasswordAuthenticationFilter重写attemptAuthentication方法即可。
public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private boolean postOnly = true;
private String privateKey = "xxxxxxxxxxxxxxxxxxx";
public MyUsernamePasswordAuthenticationFilter() {
super(new AntPathRequestMatcher("/oauth/token", "POST"));
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
try {
password = RSAUtil.decrypt(password, privateKey);
} catch (Exception e) {
e.printStackTrace();
}
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return super.getAuthenticationManager().authenticate(authRequest);
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter).replaceAll(" ", "+");
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.usernameParameter = usernameParameter;
}
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
this.passwordParameter = passwordParameter;
}
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getUsernameParameter() {
return usernameParameter;
}
public final String getPasswordParameter() {
return passwordParameter;
}
}
把自定义 MyUsernamePasswordAuthenticationFilter 添加到 Filter Chain 过滤器链中
在 SpringSecurity 的配置类中使用 http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) 把自定义的过滤器放在UsernamePasswordAuthenticationFilter 的位置,并为其设置认证成功和失败的处理方法以及认证管理器AuthenticationManager
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired
private AuthenticationSuccessHandler appLoginInSuccessHandler; @Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
AuthenticationManager manager = super.authenticationManagerBean();
return manager;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().httpBasic().and()
.cors().disable().headers().frameOptions().sameOrigin();// 解决iframe无法访问
http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
} @Bean
MyUsernamePasswordAuthenticationFilter myAuthenticationFilter() throws Exception {
MyUsernamePasswordAuthenticationFilter filter = new MyUsernamePasswordAuthenticationFilter();
filter.setAuthenticationManager(authenticationManagerBean());
filter.setAuthenticationSuccessHandler(appLoginInSuccessHandler);
filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSON.toJSONString(Respon.failed("登录失败!")));
}
});
return filter;
}
}
自定义UsernamePasswordAuthenticationFilter的运用
除了上面的例子,还常用于修改表单登录变为使用Json格式登录,登录验证码等等,需要注意的地方是UsernamePasswordAuthenticationFilter的默认登录地址为

SpringSecurity自定义UsernamePasswordAuthenticationFilter的更多相关文章
- SpringSecurity 自定义用户 角色 资源权限控制
SpringSecurity 自定义用户 角色 资源权限控制 package com.joyen.learning.security; import java.sql.ResultSet; impor ...
- SpringSecurity 自定义表单登录
SpringSecurity 自定义表单登录 本篇主要讲解 在SpringSecurity中 如何 自定义表单登录 , SpringSecurity默认提供了一个表单登录,但是实际项目里肯定无法使用的 ...
- Spring-Security 自定义Filter完成验证码校验
Spring-Security的功能主要是由一堆Filter构成过滤器链来实现,每个Filter都会完成自己的一部分工作.我今天要做的是对UsernamePasswordAuthenticationF ...
- SpringSecurity自定义AuthenticationProvider和AuthenticationFilter
AuthenticationProvider 默认实现:DaoAuthenticationProvider 授权方式提供者,判断授权有效性,用户有效性,在判断用户是否有效性,它依赖于UserDetai ...
- SpringSecurity自定义过滤器
applicationContext-security.xml: <beans:beans xmlns="http://www.springframework.org/schema/s ...
- SpringSecurity自定义登陆页面和跳转页面
如果我们不用form-login说明登陆界面,springsecurity框架将自动为我们生成登陆界面 现在我们不想用自动生成的登陆界面了,而想使用自定义的漂亮的登陆界面 则需要使用<secur ...
- springSecurity自定义认证配置
上一篇讲了springSecurity的简单入门的小demo,认证用户是在xml中写死的.今天来说一下自定义认证,读取数据库来实现认证.当然,也是非常简单的,因为仅仅是读取数据库,权限是写死的,因为相 ...
- SpringSecurity自定义注解和处理器
登录功能 添加一个配置类 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Reso ...
- Spring-Security自定义登录页&inMemoryAuthentication验证
Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架.框架下内容比较多,可以做到按照角色权限对请求路径进行限制.今天主要验证自定义登录页,在内存用户存储中进行请求 ...
随机推荐
- Mac如何前往文件夹 修改hosts文件 显示隐藏文件 Mac如何查看剪切板
Mac 如何前往文件夹 首先,回到桌面,或者点击Finder(访达) 然后输入快捷键 ⌘ Command + ⇧ Shift + G 或者在Finder上方状态栏中点击‘前往’>>> ...
- java后端开发面经 数据库相关
小姐姐:怎么理解感情中的付出和回报? 你答:有这样一个故事,讲的是一个小男孩和一个小女孩,这个小男孩呢,用很多好玩石头,而这个小女孩呢,有好多好吃的糖果,有一天,他们相互约定:小男孩用所有的石头交互小 ...
- 解决多字段联合逻辑校验问题【享学Spring MVC】
每篇一句 不要像祥林嫂一样,天天抱怨着生活,日日思考着辞职.得罪点说一句:"沦落"到要跟这样的人共事工作,难道自己身上就没有原因? 前言 本以为洋洋洒洒的把Java/Spring数 ...
- div css float布局用法
float的应用与用法 想要知道float的用法,首先你要知道float在网页中的用处. 浮动的目的就是为了使得设置的对象脱离标准文档流. 什么是标准文档流? 网页在解析的时候,遵循于从上向下,从左向 ...
- spring全家桶的pom的基本配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- FaceNet人脸识别研究
https://github.com/WindZu/facenet_facerecognition (代码) https://segmentfault.com/a/1190000015917420?u ...
- IDEA实用教程(一)
IDEA实用教程 一. IDEA简介 简介 IDEA 全称IntelliJ IDEA,是java语言开发的集成环境. IDEA是JetBrains公司的产品. JetBrains官网 : https: ...
- egret之弹幕
要实现弹幕功能,首先需要将弹幕配置成配置表.然后代码随机生成. /**生成单个弹幕 */ private showCaptionAnim(captionText: string) { egret.lo ...
- Codeforces 1008D/1007B
题意略. 思路: 由于这个长方体是可以翻转的,所以我们不必考虑小长方体3个维度的出处,反正3条边一定有长有短能分出大小. 现在我们来考虑A,B,C三个数字,如果它们3个产生的因子互不相同,分别产生了a ...
- 《Java 8 in Action》Chapter 9:默认方法
传统上,Java程序的接口是将相关方法按照约定组合到一起的方式.实现接口的类必须为接口中定义的每个方法提供一个实现,或者从父类中继承它的实现. 但是,一旦类库的设计者需要更新接口,向其中加入新的方法, ...