Authentication(Spring Security 认证笔记)
这篇文章是对Spring Security的Authentication模块进行一个初步的概念了解,知道它是如何进行用户认证的
考虑一个大家比较熟悉的标准认证过程:
1.用户使用username和password登录
2.系统验证这个password对于该username是正确的
3.假设第二步验证成功,获取该用户的上下文信息(如他的角色列表)
4.围绕该用户建立安全上下文(security context)
5.用户可能继续进行的一些操作被一个验证控制机制潜在的管理,这个验证机制会根据当前用户的安全上下文来验证权限。
认证过程就是又前三项构成的。在Spring Security中是这样处理这三部分的:
1.username和password被获得后封装到一个UsernamePasswordAuthenticationToken(Authentication接口的实例)的实例中
2.这个token被传递给AuthenticationManager进行验证
3.成功认证后AuthenticationManager将返回一个得到完整填充的Authentication实例
4.通过调用SecurityContextHolder.getContext().setAuthentication(...),参数传递authentication对象,来建立安全上下文(security context)
可以从一个示例代码中观察整个过程(完整代码参考Spring-Security文档9.3.1节):
public class AuthenticationExample {
private static AuthenticationManager am = new SampleAuthenticationManager();
public static void main(String[] args) throws Exception {
String name = "";
String password = "";
try {
// request就是第一步,使用name和password封装成为的token
Authentication request = new UsernamePasswordAuthenticationToken(name, password);
// 将token传递给Authentication进行验证
Authentication result = am.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
break;
} catch (AuthenticationException e) {
System.out.println("认证失败:" + e.getMessage());
}
System.out.println("认证成功,Security context 包含:" + SecurityContextHolder.getContext().getAuthentication());
}
}
// 自定义验证方法
class SimpleAuthenticationManager implements AuthenticationManager {
static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
// 构建一个角色列表
static {
AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
}
// 验证方法
public Authentication authenticate(Authentication auth) throws AuthenticationException {
// 这里我们自定义了验证通过条件:username与password相同就可以通过认证
if (auth.getName().equals(auth.getCredentials())) {
return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), AUTHORITIES);
}
// 没有通过认证则抛出密码错误异常
throw new BadCredentialsException("Bad Credentials");
}
}
通常不需要像上边这样写代码,这些过程都是内部自动进行的。当SecurityContextHolder包含一个完整填充的Authentication对象,用户就是验证通过了。
Web Application
考虑一个典型的Web应用认证过程:
1.访问首页,随便点击一个链接
2.发送一个请求到服务器,服务器判断你是否在访问一个收到保护的资源
3.此时你还没有进行认证,服务器会返回一个响应告诉你必须先通过认证。这个响应可以是一个HTTP响应码或者是重定向到指定的web页面
4.根据认证机制,你的浏览器可能会重定向到一个登录页面,或者通过某种方式恢复你的身份(通过一个基础的认证对话框,cookie,X.509证明等)
5.浏览器回应服务器。这可以是一个HTTP POST请求,包含你所填写的表单信息,也可以是一个HTTP请求头,包含你的认证详情
6.接下来服务器会判定提交的凭证是否通过认证。如果认证通过,那么继续下一步。如果没有通过认证,那么重新进行上边的步骤
7.你在认证之前,原始的请求(即触发认证的请求)将会重新发起。
Spring Security已经实现了上述的大多数过程。主要有ExceptionTranslationFilter,AuthenticationEntryPoint和一个认证机制,负责调用上面讨论过的AuthenticationManager。
ExceptioTranslationFilter
ExceptionTranslationFilter是用来检测Spring Security抛出的任何异常的过滤器。
AuthenticationProvider和UserDetails
There is often some confusion about UserDetailsService. It is purely a DAO for user data and performs no other function other than to supply that data to other components within the framework. In particular, it does not authenticate the user, which is done by the AuthenticationManager. In many cases it makes more sense to implement AuthenticationProvider directly if you require a custom authentication process.
AuthenticationManager
用来处理一个认证请求。只有一个authentication(Authentication authentication)函数。
尝试去认证传入的Authentication对象,如果认证成功,返回一个完整填充的Authentication对象(包括授予的权限)。
一个AuthenticationManager必须处理以下异常:
- DisabledException:当一个账户被禁用且AuthenticationManager可以检测出来这个状态,要抛出该异常
- LockedException:当一个账户被锁且AuthenticationManager可以检测这个状态,要抛出该异常
- BadCredentialsException:当账户认证失败,必须抛出该异常。(一个AuthenticationManager必须检测这个状态)
这些异常应该按照顺序抛出,(比如如果一个账户被锁定,那么不进行账户认证)。
AuthenticationProvider
用来处理一个指定的认证。有一个authenticate(Authentication authentication)函数和一个supports(Class<?> authentication)函数。
其中authenticate函数的用法与AuthenticationManager的authenticate一样。
supports函数用来指明该Provider是否适用于该类型的认证,如果不合适,则寻找另一个Provider进行验证处理。
ProviderManager
通过AuthenticationProviders迭代认证请求。
AuthenticationProviders通常按照顺序尝试,知道返回一个不为null的响应。非空响应代表provider可以提供认证并且不会继续请求下一个provider。如果后边的provider成功进行了验证,那么前边provider抛出的异常将被忽略。
Authentication(Spring Security 认证笔记)的更多相关文章
- SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证
整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...
- SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能
在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...
- Spring Security学习笔记
Spring Web Security是Java web开发领域的一个认证(Authentication)/授权(Authorisation)框架,基于Servlet技术,更确切的说是基于Servle ...
- Spring Security认证配置(三)
学习本章之前,可以先了解下上篇Spring Security认证配置(二) 本篇想要达到这样几个目的: 1.登录成功处理 2.登录失败处理 3.调用方自定义登录后处理类型 具体配置代码如下: spri ...
- Spring security学习笔记(二)
对比两种承载认证信息的方式: session vs token token验证方案: session验证方案: session即会话是将用户信息保存在服务端,根据请求携带的session_id,从服务 ...
- spring security 认证源码跟踪
spring security 认证源码跟踪 在跟踪认证源码之前,我们先根据官网说明一下security的内部原理,主要是依据一系列的filter来实现,大家可以根据https://docs.sp ...
- SpringBoot + Spring Security 学习笔记(二)安全认证流程源码详解
用户认证流程 UsernamePasswordAuthenticationFilter 我们直接来看UsernamePasswordAuthenticationFilter类, public clas ...
- Authentication讲解(Spring security认证)
标准认证过程: 1.用户使用username和password登录 2.系统验证这个password对于该username是正确的 3.假设第二步验证成功,获取该用户的上下文信息(如他的角色列表) 4 ...
- Spring Security 入门(1-4-2)Spring Security - 认证过程之AuthenticationProvider的扩展补充说明
1.用户信息从数据库获取 通常我们的用户信息都不会向第一节示例中那样简单的写在配置文件中,而是从其它存储位置获取,比如数据库.根据之前的介绍我们知道用户信息是通过 UserDetailsService ...
随机推荐
- 11Java网络编程
十一.网络编程 11.1 网络通信协议 网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信.这就好比在道路中行驶的汽车一定要遵守交通规则一样,协议中对 ...
- python day4 ---------------文件的基本操作
1.能调用方法的一定是对象,比如数值.字符串.列表.元组.字典,甚至文件也是对象,Python中一切皆为对象. str1 = 'hello' str2 = 'world' str3 = ' '.joi ...
- BZOJ2442 Usaco2011 Open修剪草坪(动态规划+单调队列)
显然可以dp.显然可以单调队列优化一下. #include<iostream> #include<cstdio> #include<cmath> #include& ...
- 【BZOJ1228】[SDOI2009]E&D(博弈论)
[BZOJ1228][SDOI2009]E&D(博弈论) 题面 BZOJ 洛谷 题解 这种打表找规律的题目真的不知道可以说什么好啊... #include<iostream> #i ...
- NOIP2018 Day0 回首向来萧瑟处,也无风雨也无晴
回首向来萧瑟处,也无风雨也无晴 NOIP2018 Day0 感想 by HGOI ljc20020730 Back ground: /* HGOI 陈功杰让我们写初赛总结?! (考这么烂还要写总结? ...
- 包学会之浅入浅出Vue.js:开学篇(转)
包学会之浅入浅出Vue.js:开学篇 蔡述雄,现腾讯用户体验设计部QQ空间高级UI工程师.智图图片优化系统首席工程师,曾参与<众妙之门>书籍的翻译工作.目前专注前端图片优化与新技术的探研. ...
- C#创建基本图表(Chart Controls)
在.NET环境下微软提供了强大了图表控件,并给多了很多实例,关于图表的基本元素如下: 并且MSDN给出了创建图表的示例步骤,原文地址:http://msdn.microsoft.com/en-us/l ...
- SHOW_PAGE_TRACE
入口文件开启APP_DEBUG配置文件里添加了'SHOW_PAGE_TRACE' => true,控制器中显示模板在页面右下角也有trace图标但是鼠标放上面不显示手型光标,还是箭头,点不动但是 ...
- 多线程(模拟买票)-----java基础知识总结
这次的的问题引入的比较深入,如果看了这篇博客,不看下一篇,你会很懵逼. 代码: package com.day13.math; /** * 类说明 :模拟三个窗口同时售票 * @author 作者 : ...
- JavaScript--Dom间接选择器
一.Dom间接选择器 间接查找的属性 parentNode // 父节点 childNodes // 所有子节点 firstChild // 第一个子节点 lastChild // 最后一个子节点 n ...