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的更多相关文章

  1. SpringSecurity 自定义用户 角色 资源权限控制

    SpringSecurity 自定义用户 角色 资源权限控制 package com.joyen.learning.security; import java.sql.ResultSet; impor ...

  2. SpringSecurity 自定义表单登录

    SpringSecurity 自定义表单登录 本篇主要讲解 在SpringSecurity中 如何 自定义表单登录 , SpringSecurity默认提供了一个表单登录,但是实际项目里肯定无法使用的 ...

  3. Spring-Security 自定义Filter完成验证码校验

    Spring-Security的功能主要是由一堆Filter构成过滤器链来实现,每个Filter都会完成自己的一部分工作.我今天要做的是对UsernamePasswordAuthenticationF ...

  4. SpringSecurity自定义AuthenticationProvider和AuthenticationFilter

    AuthenticationProvider 默认实现:DaoAuthenticationProvider 授权方式提供者,判断授权有效性,用户有效性,在判断用户是否有效性,它依赖于UserDetai ...

  5. SpringSecurity自定义过滤器

    applicationContext-security.xml: <beans:beans xmlns="http://www.springframework.org/schema/s ...

  6. SpringSecurity自定义登陆页面和跳转页面

    如果我们不用form-login说明登陆界面,springsecurity框架将自动为我们生成登陆界面 现在我们不想用自动生成的登陆界面了,而想使用自定义的漂亮的登陆界面 则需要使用<secur ...

  7. springSecurity自定义认证配置

    上一篇讲了springSecurity的简单入门的小demo,认证用户是在xml中写死的.今天来说一下自定义认证,读取数据库来实现认证.当然,也是非常简单的,因为仅仅是读取数据库,权限是写死的,因为相 ...

  8. SpringSecurity自定义注解和处理器

    登录功能 添加一个配置类 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Reso ...

  9. Spring-Security自定义登录页&inMemoryAuthentication验证

    Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架.框架下内容比较多,可以做到按照角色权限对请求路径进行限制.今天主要验证自定义登录页,在内存用户存储中进行请求 ...

随机推荐

  1. Mac如何前往文件夹 修改hosts文件 显示隐藏文件 Mac如何查看剪切板

    Mac 如何前往文件夹 首先,回到桌面,或者点击Finder(访达) 然后输入快捷键 ⌘ Command + ⇧ Shift + G 或者在Finder上方状态栏中点击‘前往’>>> ...

  2. java后端开发面经 数据库相关

    小姐姐:怎么理解感情中的付出和回报? 你答:有这样一个故事,讲的是一个小男孩和一个小女孩,这个小男孩呢,用很多好玩石头,而这个小女孩呢,有好多好吃的糖果,有一天,他们相互约定:小男孩用所有的石头交互小 ...

  3. 解决多字段联合逻辑校验问题【享学Spring MVC】

    每篇一句 不要像祥林嫂一样,天天抱怨着生活,日日思考着辞职.得罪点说一句:"沦落"到要跟这样的人共事工作,难道自己身上就没有原因? 前言 本以为洋洋洒洒的把Java/Spring数 ...

  4. div css float布局用法

    float的应用与用法 想要知道float的用法,首先你要知道float在网页中的用处. 浮动的目的就是为了使得设置的对象脱离标准文档流. 什么是标准文档流? 网页在解析的时候,遵循于从上向下,从左向 ...

  5. spring全家桶的pom的基本配置

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  6. FaceNet人脸识别研究

    https://github.com/WindZu/facenet_facerecognition (代码) https://segmentfault.com/a/1190000015917420?u ...

  7. IDEA实用教程(一)

    IDEA实用教程 一. IDEA简介 简介 IDEA 全称IntelliJ IDEA,是java语言开发的集成环境. IDEA是JetBrains公司的产品. JetBrains官网 : https: ...

  8. egret之弹幕

    要实现弹幕功能,首先需要将弹幕配置成配置表.然后代码随机生成. /**生成单个弹幕 */ private showCaptionAnim(captionText: string) { egret.lo ...

  9. Codeforces 1008D/1007B

    题意略. 思路: 由于这个长方体是可以翻转的,所以我们不必考虑小长方体3个维度的出处,反正3条边一定有长有短能分出大小. 现在我们来考虑A,B,C三个数字,如果它们3个产生的因子互不相同,分别产生了a ...

  10. 《Java 8 in Action》Chapter 9:默认方法

    传统上,Java程序的接口是将相关方法按照约定组合到一起的方式.实现接口的类必须为接口中定义的每个方法提供一个实现,或者从父类中继承它的实现. 但是,一旦类库的设计者需要更新接口,向其中加入新的方法, ...