UsernamePasswordAuthenticationFilter介绍

UsernamePasswordAuthenticationFilter是AbstractAuthenticationProcessingFilter针对使用用户名和密码进行身份验证而定制化的一个过滤器。其添加是在调用http.formLogin()时作用,默认的登录请求pattern为"/login",并且为POST请求。当我们登录的时候,也就是匹配到loginProcessingUrl,这个过滤器就会委托认证管理器authenticationManager来验证登录。

自定义UsernamePasswordAuthenticationFilter

这里我的需求是通过自定义UsernamePasswordAuthenticationFilter实现对前端传过来的密码进行RSA私钥解密,并且因为登录地址不是"/login",所以继承的是AbstractAuthenticationProcessingFilter,如果登录地址为默认,那么可直接继承UsernamePasswordAuthenticationFilter重写attemptAuthentication方法即可。

  1. public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
  2. public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
  3. public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
  4. private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
  5. private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
  6. private boolean postOnly = true;
  7. private String privateKey = "xxxxxxxxxxxxxxxxxxx";
  8.  
  9. public MyUsernamePasswordAuthenticationFilter() {
  10. super(new AntPathRequestMatcher("/oauth/token", "POST"));
  11. }
  12.  
  13. public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
  14. throws AuthenticationException {
  15. if (postOnly && !request.getMethod().equals("POST")) {
  16. throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
  17. }
  18. String username = obtainUsername(request);
  19. String password = obtainPassword(request);
  20. try {
  21. password = RSAUtil.decrypt(password, privateKey);
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. }
  25.  
  26. if (username == null) {
  27. username = "";
  28. }
  29.  
  30. if (password == null) {
  31. password = "";
  32. }
  33.  
  34. username = username.trim();
  35.  
  36. UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
  37.  
  38. // Allow subclasses to set the "details" property
  39. setDetails(request, authRequest);
  40.  
  41. return super.getAuthenticationManager().authenticate(authRequest);
  42. }
  43.  
  44. public void setAuthenticationManager(AuthenticationManager authenticationManager) {
  45. super.setAuthenticationManager(authenticationManager);
  46. }
  47.  
  48. protected String obtainPassword(HttpServletRequest request) {
  49. return request.getParameter(passwordParameter).replaceAll(" ", "+");
  50. }
  51.  
  52. protected String obtainUsername(HttpServletRequest request) {
  53. return request.getParameter(usernameParameter);
  54. }
  55.  
  56. protected void setDetails(HttpServletRequest request,
  57. UsernamePasswordAuthenticationToken authRequest) {
  58. authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
  59. }
  60.  
  61. public void setUsernameParameter(String usernameParameter) {
  62. Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
  63. this.usernameParameter = usernameParameter;
  64. }
  65.  
  66. public void setPasswordParameter(String passwordParameter) {
  67. Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
  68. this.passwordParameter = passwordParameter;
  69. }
  70.  
  71. public void setPostOnly(boolean postOnly) {
  72. this.postOnly = postOnly;
  73. }
  74.  
  75. public final String getUsernameParameter() {
  76. return usernameParameter;
  77. }
  78.  
  79. public final String getPasswordParameter() {
  80. return passwordParameter;
  81. }
  82.  
  83. }

把自定义 MyUsernamePasswordAuthenticationFilter 添加到 Filter Chain 过滤器链中

在 SpringSecurity 的配置类中使用 http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) 把自定义的过滤器放在UsernamePasswordAuthenticationFilter 的位置,并为其设置认证成功和失败的处理方法以及认证管理器AuthenticationManager

  1. @Configuration
  2. @EnableWebSecurity
  3. @EnableGlobalMethodSecurity(prePostEnabled = true)
  4. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  5.  
  6. @Autowired
  7. private AuthenticationSuccessHandler appLoginInSuccessHandler;
  8.  
  9. @Bean
  10. @Override
  11. public AuthenticationManager authenticationManagerBean() throws Exception {
  12. AuthenticationManager manager = super.authenticationManagerBean();
  13. return manager;
  14. }
  15. @Override
  16. protected void configure(HttpSecurity http) throws Exception {
  17. http.authorizeRequests().anyRequest().authenticated()
  18. .and().httpBasic().and()
  19. .cors().disable().headers().frameOptions().sameOrigin();// 解决iframe无法访问
  20. http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
  21. }
  22.  
  23. @Bean
  24. MyUsernamePasswordAuthenticationFilter myAuthenticationFilter() throws Exception {
  25. MyUsernamePasswordAuthenticationFilter filter = new MyUsernamePasswordAuthenticationFilter();
  26. filter.setAuthenticationManager(authenticationManagerBean());
  27. filter.setAuthenticationSuccessHandler(appLoginInSuccessHandler);
  28. filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
  29. @Override
  30. public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
  31. response.setContentType("application/json;charset=utf-8");
  32. response.getWriter().write(JSON.toJSONString(Respon.failed("登录失败!")));
  33. }
  34. });
  35. return filter;
  36. }
  37. }

自定义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. 关于int的范围以及溢出问题

    最近在练一些算法题目的时候恰巧碰到了几道关于int范围与溢出相关的问题,于是就整理一下. 1.原码.补码 在计算机中数值都是用补码表示和存储的(正数补码与原码一致,负数补码是原码符号位不变,其余位取反 ...

  2. Appium+python自动化(三十二)- 代码写死一时爽,框架重构火葬场 - PageObject+unittest(超详解)

    简介 江湖有言:”代码写死一时爽,框架重构火葬场“,更有人戏言:”代码动态一时爽,一直动态一直爽

  3. (二十)c#Winform自定义控件-有后退的窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  4. 上传文件时 重新载入页面以获取源代码 http://*/upload.php

    今天做一个处理上传文件的接口时碰到这样一个问题, 用的是element-ui的上传组件,但是上传失败, 抓包一看返回的是 重新载入页面以获取源代码 http://*/upload.php 网上搜了一下 ...

  5. 从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧

    视觉 Vs. IMU 小白:师兄,好久没见到你了啊,我最近在看IMU(Inertial Measurement Unit,惯性导航单元)相关的东西,正好有问题求助啊 师兄:又遇到啥问题啦? 小白:是这 ...

  6. 如何使用python records 库优雅的操作数据库

    今天要介绍的这个python第三方库非常厉害,完美操作各种数据库.名字叫 records, 在网上很少有这个库的相关资料,但是在开源社区可是很火热的哦.如果这还不能打消你的顾虑,再告诉你一件事:如果你 ...

  7. 使用base64编码把背景添加到CSS文件中

    最近博客背景图片的外链挂了,没办法,只好另找办法. 在博客园后台,有一个“文件”菜单,可以上传自己的文件,我就打算把图片传到里面.但却发现了一个很反人性的设置:不允许上传jpg,png文件,允许上传的 ...

  8. Okhttp3源码解析(4)-拦截器与设计模式

    ### 前言 回顾: [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析](htt ...

  9. 完结撒花!129 集 21 个小时,松哥自制的 Spring Boot2 系列视频教程杀青啦!

    松哥的 Spring Boot 教程分为几个阶段. 2016 松哥最早在 2016 年底的时候开始写 Spring Boot 系列的教程,记得当时在广州上班,年底那段时间在深圳出差,在深圳人生地不熟, ...

  10. Leetcode之回溯法专题-46. 全排列(Permutations)

    Leetcode之回溯法专题-46. 全排列(Permutations) 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3, ...