/*
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.security.web.authentication; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert; /**
* Processes an authentication form submission. Called
* {@code AuthenticationProcessingFilter} prior to Spring Security 3.0.
* <p>
* Login forms must present two parameters to this filter: a username and password. The
* default parameter names to use are contained in the static fields
* {@link #SPRING_SECURITY_FORM_USERNAME_KEY} and
* {@link #SPRING_SECURITY_FORM_PASSWORD_KEY}. The parameter names can also be changed by
* setting the {@code usernameParameter} and {@code passwordParameter} properties.
* <p>
* This filter by default responds to the URL {@code /login}.
*
* @author Ben Alex
* @author Colin Sampaleanu
* @author Luke Taylor
* @since 3.0
*/ /**
* 当用户登录的时候 当前的过滤器会被调用
*/
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { //表单提交的 用户名
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username"; // 说明 如果用户想增强当前类的功能可以创建一个当前类的子类 在子类的构造方法中 修改SPRING_SECURITY_FORM_USERNAME_KEY和SPRING_SECURITY_FORM_PASSWORD_KEY
// 并且增加到过滤器链中 使用 addfilterAt(new 子类, 当前类.class)
//表单提交的 密码 必须以SPRING_SECURITY_FORM_PASSWORD_KEY 为主
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password"; // 规定请求路径 以及请求方式
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/login",
"POST"); // 用户名 传递参数解析的Key
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
// 密码 传递参数解析的Key
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY; // 哪一种方式的登录请求 - 仅限于POST
private boolean postOnly = true; // 初始化
public UsernamePasswordAuthenticationFilter() {
super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
} /**
* 初始化
* @param authenticationManager 认证管理器
*/
public UsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager) {
super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
} /*
当用户调用 /login 时会被调用
此方法为重新父类方法。 用户可以继承父类实现自定义的表单登录方法
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
// 如果不是POST调用的话那么抛出 授权服务 异常
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
// 解析获取username
String username = obtainUsername(request);
// 如果user 不为空的话 放入内存并且返回
// 下次在其他用户调用的时候 直接返回而不是重新生成。 这里可能是考虑的用户ID可能会出现多次调用的时候对内存的优化
username = (username != null) ? username.trim() : "";
// 与上述但是直接返回
String password = obtainPassword(request);
password = (password != null) ? password : "";
/**
* UsernamePasswordAuthenticationToken 是在用户登录时 loadUserByUsername 返回的对象一致。用户可以在当前
* 处理自己的登录逻辑
* 由于此处我这里是 使用的oauth 所以在默认的登录中是未授权的 用户
* 至于为什么这里写的这么详细呢 ? 是因为有些课程中老师的习惯是重写这个接口实现用户的登录
* 有的老师是重写的loadUserByUsername 两者皆可 避免混淆
*/
UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,
password); // Allow subclasses to set the "details" property
setDetails(request, authRequest);
//返回
return this.getAuthenticationManager().authenticate(authRequest);
} /**
* Enables subclasses to override the composition of the password, such as by
* including additional values and a separator.
* <p>
* This might be used for example if a postcode/zipcode was required in addition to
* the password. A delimiter such as a pipe (|) should be used to separate the
* password and extended value(s). The <code>AuthenticationDao</code> will need to
* generate the expected password in a corresponding manner.
* </p>
* @param request so that request attributes can be retrieved
* @return the password that will be presented in the <code>Authentication</code>
* request token to the <code>AuthenticationManager</code>
*/ // 从http请求获取password
@Nullable
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(this.passwordParameter);
} /**
* Enables subclasses to override the composition of the username, such as by
* including additional values and a separator.
* @param request so that request attributes can be retrieved
* @return the username that will be presented in the <code>Authentication</code>
* request token to the <code>AuthenticationManager</code>
*/
// 从http请求获取username
@Nullable
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(this.usernameParameter);
} /**
* Provided so that subclasses may configure what is put into the authentication
* request's details property.
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details
* set
*/
//设置信息 子类可访问
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
} /**
* Sets the parameter name which will be used to obtain the username from the login
* request.
* @param usernameParameter the parameter name. Defaults to "username".
*/ // 自定义登录的解析参数
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.usernameParameter = usernameParameter;
} /**
* Sets the parameter name which will be used to obtain the password from the login
* request..
* @param passwordParameter the parameter name. Defaults to "password".
*/
//设置密码的解析Parame 表单的name属性
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
this.passwordParameter = passwordParameter;
} /**
* Defines whether only HTTP POST requests will be allowed by this filter. If set to
* true, and an authentication request is received which is not a POST request, an
* exception will be raised immediately and authentication will not be attempted. The
* <tt>unsuccessfulAuthentication()</tt> method will be called as if handling a failed
* authentication.
* <p>
* Defaults to <tt>true</tt> but may be overridden by subclasses.
*/ public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
} public final String getUsernameParameter() {
return this.usernameParameter;
} public final String getPasswordParameter() {
return this.passwordParameter;
} }

2- 用户登录表单拦截 UsernamePasswordAuthenticationFilter的更多相关文章

  1. Spring Security默认的用户登录表单 页面源代码

    Spring Security默认的用户登录表单 页面源代码 <html><head><title>Login Page</title></hea ...

  2. Html登录表单阻止自动填充

    设置属性 autocomplete="off" 阻止浏览器从cache获取数据填充登录表单. <input type="text" name=" ...

  3. 9款大气实用的HTML5/CSS3注册登录表单

    1.HTML5/CSS3仿Facebook登录表单 利用CSS3制作的登录表单的确很漂亮,我们在html5tricks网站上也分享过几款了,比如CSS3密码强度验证表单可以显示密码的强度,这款纯CSS ...

  4. yii YII小部件 创建登录表单表单 Login表单

    YII框架必须遵循其表单的创建方法 登录模型错做与数据库操作模型是一致的,不同的是不跟数据库交互 ,用的是小部件,在创建表单之前,要在用户控制模块完成以下代码 protected --models - ...

  5. Yii创建前台和后台登录表单和通过扩展 CWebUser 增加信息到 Yii::app()->user

    我参考了这篇文章来构建项目的前台和后台的目录结构.感谢Andy的这篇文章.按照所有的步骤,您将有单独的前台和后台面板,如: http://localhost/index.php // 前台 http: ...

  6. CSS3/HTML5实现漂亮的分步骤注册登录表单

    分步骤的登录注册表单现在也比较多,主要是能提高用户体验,用户可以有选择性的填写相应的表单信息,不至于让用户看到一堆表单望而却步.今天和大家分享的就是一款基于HTML5和CSS3的分步骤注册登录表单,外 ...

  7. xml实现登录表单验证

    定义: XML(eXtended Markup Language,可扩展标记语言)提供了一套跨平台.跨网络.跨程序的语言的数据描述方式,使用XML可以方便地实现数据交换.系统配置.内容管理等常见功能. ...

  8. AngularJS学习之 登录表单 清爽验证(边学边更新)

    注册过程的确好多需要验证的,但是注册成功之后的登录就简单多了, 只要用户 输入 用户名和密码, ajax向后台提交登录请求, 根据返回的结果确定用户名或者密码是否正确即可登录. 所以这个登录表单的验证 ...

  9. Vue + ElementUI的电商管理系统实例01 登录表单

    效果图: 1.首先来根据Element网站实现布局: <template> <div class="login_container"> <div cl ...

  10. wordpress 自定义登录表单

    wordpress 有很多插件支持自定义登录表单,本文讨论无插件形式. 自定义登录表单又分为两种 自定义登录表单 在前端创建一个登录页面

随机推荐

  1. 创建型模式 - 抽象工厂模式AbstractFactory

    学习而来,代码是自己敲的.也有些自己的理解在里边,有问题希望大家指出. 模式的定义与特点 抽象工厂模式.是一种为访问类提供一个创建一组相关或相关一类对象的接口,且访问类无需指定所要的产品的具体类,就能 ...

  2. 双缓冲技术解决MFC绘制闪烁问题

    闪烁的根源:OnEraseBkgnd一擦一写造成了图象颜色的反差导致闪烁 如何避免:首先要做的是屏蔽背景刷新.背景刷新其实是在响应WM_ERASEBKGND消息.我们在视类中添加对这个消息的响应 BO ...

  3. 芯片下载相关-CH32系列芯片下载方式汇总及教程

    一.CH32Fx系列芯片下载 1.ISP下载: 2.SWD下载 3.脱机烧录器下载: 二.CH32Vx系列芯片下载 1.ISP下载: 2.SWD下载: 3.脱机烧录器下载: 4.CH32V003下载注 ...

  4. python学习第二周总结

    上周内容概要 基本数据类型之布尔值 基本数据类型至元组 基本数据类型之集合 与用户交互 格式化输出 基本运算符 常用运算符 逻辑运算符 成员运算符 身份运算符 垃圾回收与机制 流程控制理论 流程控制之 ...

  5. IDEA翻译插件translate

    1.打开File->Setting 2.plugins->Browse repositories 3.输入"translate",选择排序"Downloads ...

  6. .net core 读取配置文件的几种方式

    一.Json配置文件 1.这里的配置文件指的是下图 2.json配置文件示例 { "Logging": { "LogLevel": { "Defaul ...

  7. 郁金香逆向 2.便利怪物对象数组 纯C写法

    读取基础地址 获取节点数量 打印怪物列表 进行遍历 环环相扣

  8. JZOJ 4253.QYQ在艾泽拉斯

    \(\text{Problem}\) 有向不联通图,求每个子图至多选出一条最大权值和的路径,求前 \(k+1\) 个 \(\text{Solution}\) 显然将每个子图缩点后 \(dp\),排序 ...

  9. [专题总结]Gridea快速免费搭建个人博客

    介绍 或许你很想把你所知道的问题写出来,或许你文思泉涌,想给大家分享.我相信,你一定能写好博客,只要坚持,就可以了. 或许大家会不理解,为什么不用大平台的博客呢?或许你稍微了解就会知道,现在的博客平台 ...

  10. HTTP/2 VS HTTP/3

    HTTP(Hypertext Transfer Protocol)超文本传输协议是万维网中应用最广泛的应用层传输协议.HTTP起源于80年代末,最初构想是一个基于单行文本的的协议,第一个协议版本是HT ...