欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

Spring Security学习笔记(一)基础介绍I

来源:本站整理 作者:佚名 时间:2019-03-06 TAG: 我要投稿

Spring Security 5.1.4 RELEASE
对于使用Java进行开发的同学来说,Spring算是一个比较热门的选择,包括现在流行的Spring Boot更是能快速上手,并让开发者更好的关注业务核心的开发,而免去了原来冗杂的配置过程。从Spring 4开始推荐使用代码进行配置,更是降低了配置的难度,远离了让人看得头大的xml配置文件。
这篇文章主要想系统的介绍一下Spring Security这个框架。当需要进行一些认证授权的开发时,常用的Java安全框架主要有Apache Shiro和Spring Security。两者相比,Shiro更为轻量化,简单易用,而Spring Security作为Spring的亲儿子,功能更强大,和Spring项目的结合度更好,而使用的学习成本相较于Shiro会略高一些。
在讲代码之前,想先介绍一下Spring Security中的一些基本组件及服务,以便于更好理解后文的代码。基本架构的介绍,主要来自于官方文档,进行了选择性的翻译,参考的版本是Spring Security 5.1.4 RELEASE,感兴趣的同学也可以直接前往阅读英文原文。
 
1 基本架构
1.1 核心组件
从Spring Security 3.0开始,组件spring-security-corejar包中的内容进行了精简,不再包含任何web应用安全,LDAP或命名空间配置的代码。
SecurityContextHolder
最基本的对象,用来存储当前的安全上下文(security context),包含了当前登录的用户信息。默认使用ThreadLocal保存细节信息,因此这些信息对于同一个线程内容调用的方法都是可用的。当用户的请求处理完成后,框架会自动清理线程而不必用户关心。但是由于某些应用由于其对线程的使用方式,并不适合使用ThreadLocal,则需要根据情况,在启动前设置SecurityContextHolder的策略。
在SecurityContextHolder中保存了当前活跃用户的信息。Spring Security使用一个Authentication对象来表示这些信息。在程序的任何地方,都可以用以下代码来获取当前认证用户的信息。
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
    String username = ((UserDetails)principal).getUsername();
} else {
    String username = principal.toString();
}
UserDetailsService
在接口UserDetailService中只有一个方法,接收一个字符串返回一个UserDetails对象,当认证成功后,UserDetails会被用来构造一个Authentication对象保存在SecurityContextHolder中。
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
UserDetailsService的实现,主要是用来加载用户信息,并向其他组件提供这些信息,并不能进行认证用户的操作,认证的操作由AuthenticationManager完成。
如果用户想自定义一个认证流程,则需要实现AuthenticationProvider接口。
GrantedAuthority
Authentication的getAuthorities( )方法返回GrantedAuthority的对象数组。GrantAuthority对象一般由UserDetailsService加载。
总结
ScurityContextHolder获取SecurityContext
SecurityContext保存了Authentication以及其他一些请求相关的安全信息
Authentication表示一个认证用户信息
GrantedAuthority表示授予用户的权限信息
UserDetails包含了构建Authentication对象需要的必要信息,这些信息来自于应用的DAO或其他数据源
UserDetailsService根据传入用户名字符串构建一个UserDetails对象
1.2 认证环节
一个基本的认证环节包括:
用户输入用户名和密码
系统验证用户名密码正确
系统获取该用户的角色、权限等信息。
以上三个步骤完成了一个认证过程,在Spring Security中,相应地完成了以下动作:
后端获取到用户名和密码并用之生成一个UsernamePasswordAuthenticationToken对象,UsernamePasswordAuthenticationToken是Authentication的一个实现类。
token被传入AuthenticationManager的实例中进行校验
认证成功后,AuthenticationManager会返回一个Authentication实例,其中包括了用户所有细节信息,包括角色、权限等
通过调用SecurityContextHolder.getContext().setAuthentication(…)建立安全上下文,传入Authentication对象
完成以上过程后,当前用户认证完成。以下代码示范了一个认证环节最基本的流程(并非SpringSecurity框架源码)
import org.springframework.security.authentication.*;
import org.springframework.security.core.*;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
public class AuthenticationExample {
// 0. 创建一个AuthenticationManager实例,之后用于用户校验 (具体实现在下方) 
private static AuthenticationManager am = new SampleAuthenticationManager();
public static void main(String[] args) throws Exception {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    // 1. 用户在界面输入用户名密码
    while(true) {
    System.out.println("Please enter your username:");
    String name = in.readLine();
    System.out.println("Please enter your password:");
    String password = in.readLine();
    try {
        // 2. 用户名和密码生成一个UsernamePasswordAuthenticationToken对象
        Authentication request = new UsernamePasswordAuthenticationToken(name, password);
        // 3. 使用AuthenticationManager实例校验token
        Authentication result = am.authenticate(request);

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载