Spring-Security-文档笔记之认证组件

1. 认证组件列表

  • SecurityContextHolder
    存储认证过的用户的详细信息
  • SecurityContext
    包含在SecurityContextHolder中, 存储当前已认证用户的信息(Authentication对象)
  • Authentication
    提供给AuthenticationManager以提供用户凭证(密码), 或者当前用户
  • GrantedAuthority
    授予用户的权限.
  • AuthenticationManager
    决定调用哪个身份认证过滤器
  • ProviderManager
    AuthenticationManager最常用的实现.
  • AuthenticationEntryPoint
    用来向客户端请求凭证(如重定向到登录页面, 或返回一个www-authenticate响应)
  • AbstractAuthenticationProcessingFilter
    用于进行认证的基本Filter.

2. SecutiryContextHolder

SecutiryContextHolder用于存储已认证用户的信息, 它不关心用户是如何通过认证的, 只要包含一个值, 则这个值将被用来作为一个已认证用户. 这是一个jvm设置, 因此其所有方法都是静态的.

通过配置指定相关策略. 其实现被委托给 SecurityContextHolderStrategy. 策略指定有两种方法, 一种是系统属性, 一种是调用静态方法.

其策略有三种:

  • ThreadLocal:
    默认, 使用一个ThreadLocal来存储用户信息, 因此在同一个线程中可以获取到用户信息.
  • InheritableThreadLocal:
    使用一个InheritableThreadLocal存储用户信息, 可以当前线程创建的子线程中也可以获取到用户信息.
  • Global:
    全局共享一个SecurityContext.

获取用户信息:

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();
Object principal = authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

类图:


image.png

3. SecurityContext

存储Authentication对象.

4. Authentication

在成功调用AuthenticationManager.authenticate(Authentication)方法后, 用于存储已认证用户的信息.
如果其authenticated属性值为false, Spring Security都将会对其进行验证.

Collection<? extends GrantedAuthority> getAuthorities()用于获取授予认证主体的权限, 当没有权限时应返回空集合,而不是null.

Object getDetails()方法用于存储认证请求信息, 如IP地址, 凭证序列号等.

Object getPrincipal() : 在使用用户名和密码登录验证的请求中, 在认证成功之前, 这通常是用户名, 认证成功后, 这通常是一个UserDetails对象.

boolean isAuthenticated(): 用于指示AbstractSecurityInterceptor是否将当前的Authentication对象传递给AuthenticationManager进行身份验证.

5. GrantedAuthority

用于表示用户所获取的权限, 如角色. 如果使用用户名密码认证, 权限应由UserDetailsService加载.
它用字符串来表示, 以便能进行精确匹配.

6. AuthenticationManager

用于处理认证请求. 认证后会将用户信息存储到SecurityContext中. 其最常用的实现为ProviderManager.

必须对以下异常进行验证:

  • 如果用户被禁用,则应抛出DisabledException.
  • 如果用户被锁定, 则应抛出LockedException.
  • 如果凭证错误, 则必须抛出badcredentialexception。

Authentication authenticate(Authentication authentication) throws AuthenticationException: 如果调用成功则返回一个完全填充(包含了较全面的用户信息)的Authentication对象.

7. ProviderManager

最常用的AuthenticationManager实现. 它包含一个AuthenticationProvider集合. 每个provider对应一种身份验证方式, 因此通过AuthenticationManager可以支持多种身份验证方式. 如果请求没有相应的provider, 则将抛出ProviderNotFoundException.

image.png

ProviderManager遍历每个provider, 如果有一个provider返回非null结果, 则将不再调用后续未调用的provider.

此外, ProviderManager还可以配置一个parent, 当ProviderManager无法进行认证时, 可以调用这个parent. 这样可以在有多个ProviderManager实例时, 通过parent来处理公共认证方式. parent可以是任何AuthenticationManager实例, 但通常为ProviderManager.

ProviderManager还负责在认证成功后清除用户凭证(密码). 其eraseCredentialsAfterAuthentication属性值默认为true. 这对于通过缓存用户信息再进行认证的场景可能有影响(因为密码被清除了). 解决方式是设置eraseCredentialsAfterAuthentication为false.

认证事件
可通过AuthenticationEventPublisher来发布认证事件(成功,失败). 默认是一个Null实现(不发布事件). 因此如果需要发布事件,则需要注入对应的bean(DefaultAuthenticationEventPublisher). ProviderManager的parent通常不需要配置publisher, 因为manager可以对parent的认证结果发布相应的事件, 从而造成事件 的重复发布.

AuthenticationManager类图:


image.png

7. AuthenticationProvider

定义认证方式.

8. AuthenticationEntryPoint

ExceptionTranslationFilter中用来定义认证方案. 即返回给客户端响应以要求客户端提供何种方式的认证.

类图:


image.png

9. AbstractAuthenticationProcessingFilter

身份验证的一个基础Filter.


image.png
  1. 用户提交认证请求后, 它将从请求中获取相关参数并创建一个Authentication对象(对象类型取决于其实现类).
  2. Authentication对象被传递给AuthenticationManager进行验证处理.
  3. 如果验证不通过, 将清除SecurityContextHolder; 调用RememberMeService.loginFail(如果配置了remeberme); 调用AuthenticationFailureHandler. 如果验证通过, 通知SessionAuthenticationStrategy有一个新的登录; 存储AuthenticationSecurityContextHolder, SecurityContextPersistenceFilter保存这个SecurityContextHttpSession; 如果配置了remeberme, 调用RemeberMeService.loginSuccess; ApplicationEventPublisher发布一个InteractiveAuthenticationSuccessEvent, 调用AuthenticationSuccessHandler.

类图:


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容