一直以来我都想写一写Spring Security系列的文章,可是整个Spring Security体系强大却又繁杂。陆连续续从最开始的guides打仗它,到项目中看了一些源码,到最近这个月为了写一写这个系列的文章,阅读了好几遍文档,最终规划实验一下,写一个较为完整的系列文章。
较为简朴可能体量较小的技能,完全可以参考着demo直接上手,但系统的进修一门技能则否则。以我的认知,一般的文档大抵有两种气势气魄:Architecture First和Code First。前者致力于让读者先相识整体的架构,利便我们对本身的认知有一个宏观的把控,尔后者以特定的demo共同讲授,可以让读者在办理问题的进程中顺便把握一门技能。存眷过我博客可能公家号的伴侣会发明,我之前先容技能的文章,大大都是Code First,提出一个需求,先容一个思路,办理一个问题,阐明一下源码,大多如此。而进修一个别系的技能,我推荐Architecture First,正如本文标题所言,这篇文章是我Spring Security系列的第一篇,主要是按照Spring Security文档选择性翻译整理而成的一个架构概览,共同本身的一些注释利便各人领略。写作本系列文章时,参考版本为Spring Security 4.2.3.RELEASE。
1 焦点组件
这一节主要先容一些在Spring Security中常见且焦点的Java类,它们之间的依赖,构建起了整个框架。想要领略整个架构,最起码得对这些类眼熟。
1.1 SecurityContextHolder
SecurityContextHolder用于存储安详上下文(security context)的信息。当前操纵的用户是谁,该用户是否已经被认证,他拥有哪些脚色权限…这些都被生存在SecurityContextHolder中。SecurityContextHolder默认利用ThreadLocal 计策来存储认证信息。看到ThreadLocal 也就意味着,这是一种与线程绑定的计策。Spring Security在用户登录时自动绑定认证信息到当前线程,在用户退出时,自动排除当前线程的认证信息。但这一切的前提,是你在web场景下利用Spring Security,而假如是Swing界面,Spring也提供了支持,SecurityContextHolder的计策则需要被替换,鉴于我的初志是基于web来先容Spring Security,所以这里以及后续,非web的相关的内容都一笔带过。
获取当前用户的信息
因为身份信息是与线程绑定的,所以可以在措施的任那里所利用静态要领获取用户信息。一个典范的获取当前登任命户的姓名的例子如下所示:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { String username = ((UserDetails)principal).getUsername(); } else { String username = principal.toString(); }
getAuthentication()返回了认证信息,再次getPrincipal()返回了身份信息,UserDetails即是Spring对身份信息封装的一个接口。Authentication和UserDetails的先容在下面的小节详细讲授,本节重要的内容是先容SecurityContextHolder这个容器。
1.2 Authentication
先看看这个接口的源码长什么样:
package org.springframework.security.core;// <1> public interface Authentication extends Principal, Serializable { // <1> Collection<? extends GrantedAuthority> getAuthorities(); // <2> Object getCredentials();// <2> Object getDetails();// <2> Object getPrincipal();// <2> boolean isAuthenticated();// <2> void setAuthenticated(boolean var1) throws IllegalArgumentException; }
<1> Authentication是spring security包中的接口,直接担任自Principal类,而Principal是位于java.security包中的。可以见得,Authentication在spring security中是第一流此外身份/认证的抽象。
<2> 由这个顶级接口,我们可以获得用户拥有的权限信息列表,暗码,用户细节信息,用户身份信息,认证信息。
还记得1.1节中,authentication.getPrincipal()返回了一个Object,我们将Principal强转成了Spring Security中最常用的UserDetails,软件开发,这在Spring Security中非经常见,接口返回Object,利用instanceof判定范例,强转成对应的详细实现类。接口具体解读如下:
Spring Security是如何完成身份认证的?
1 用户名和暗码被过滤器获取到,封装成Authentication,凡是环境下是UsernamePasswordAuthenticationToken这个实现类。
2 AuthenticationManager 身份打点器认真验证这个Authentication