文章目录

  • 一、权限管理
  • 1、认证
  • 2、授权
  • 3、对权限控制,现有的解决方案
  • 二、SpringSecurity简介
  • 1、官方定义
  • 2、历史
  • 三、整体架构
  • 1、认证
  • AuthenticationManager
  • Authentication
  • SecurityContextHolder
  • 2、授权
  • AccessDecisionManager
  • AccessDecisionVoter
  • ConfigAttribute


一、权限管理

基本上涉及到⽤户参与的系统都要进⾏权限管理,权限管理属于系统安全的范畴,权限管理实现对⽤户访问系统的控制,按照安全规则或者安全策略控制⽤户可以访问⽽且只能访问⾃⼰被授权的资源
权限管理包括⽤户身份认证授权两部分,简称认证授权。对于需要访问控制的资源⽤户⾸先经过身份认证,认证通过后⽤户具有该资源的访问权限⽅可访问。

也就是通过身份认证检查是否有进入系统的权利,通过授权检查是否有访问特定资源的权利。

springbnot普通用户和管理员怎么权限设置_权限管理

1、认证

身份认证,就是判断⼀个⽤户是否为合法⽤户的处理过程。最常⽤的简单身份认证⽅式是系统通过核对⽤户输⼊的⽤户名和⼝令,看其是否与系统中存储的该⽤户的⽤户名和⼝令⼀致,来判断⽤户身份是否正确。对于采⽤指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡

2、授权

授权,即访问控制,控制谁能访问哪些资源。主体进⾏身份认证后需要分配权限⽅可访问系统的资源,对于某些资源没有权限是⽆法访问的

3、对权限控制,现有的解决方案

和其他领域不同,在 Java 企业级开发中,安全管理框架⾮常少,⽬前⽐较常⻅的就是:

  • ShiroShiro 本身是⼀个⽼牌的安全管理框架,有着众多的优点,例如轻量、简单、易于集成、可以在JavaSE环境中使⽤等。不过,在微服务时代,Shiro 就显得⼒不从⼼了,在微服务⾯前和扩展⽅⾯,⽆法充分展示⾃⼰的优势
  • 开发者⾃定义
    也有很多公司选择⾃定义权限,即⾃⼰开发权限管理。但是⼀个系统的安全,不仅仅是登录和权限控制这么简单,我们还要考虑种各样可能存在的⽹络政击以及防彻策略,从这个⻆度来说,开发者⽩⼰实现安全管理也并⾮是⼀件容易的事情,只有⼤公司才有⾜够的⼈⼒物⼒去⽀持这件事情。
  • Spring SecuritySpring Security,作为Spring 家族的⼀员,在和 Spring 家族的其他成员如
    Spring Boot Spring Clond等进⾏整合时,具有其他框架⽆可⽐拟的优势,同
    时对 OAuth2 有着良好的⽀持,再加上Spring Cloud Spring Security
    不断加持(如推出Spring Cloud Security),让 Spring Securiy 不知不
    觉中成为微服务项⽬的⾸选安全管理⽅案。

二、SpringSecurity简介

1、官方定义

查看官方介绍:https://spring.io/projects/spring-security

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements.


Spring Security是⼀个功能强⼤、可⾼度定制的身份验证和访问控制框架。它是保护基
于Spring的应⽤程序的事实标准。
Spring Security是⼀个⾯向Java应⽤程序提供身份验证和安全性的框架。与所有Spring
项⽬⼀样,Spring Security的真正威⼒在于它可以轻松地扩展以满⾜定制需求。
总结:Spring Security是⼀个功能强⼤、可⾼度定制的身份验证访问控制的框架。或者说⽤来实现系统中权限管理的框架。

2、历史

Spring Security 最早叫 Acegi Security, 这个名称并不是说它和 Spring 就没有关系,它依然是为Spring 框架提供安全⽀持的。Acegi Security 基于 Spring,可以帮助我们为项⽬建⽴丰富的⻆⾊与权限管理系统。Acegi security 虽然好⽤,但是最为⼈诟病的则是它臃肿烦琐的配置这⼀问题最终也遗传给了 Spring Security

Acegi Security 最终被并⼊ Spring Security 项⽬中,并于 2008 年4⽉发布了改名后的第⼀个版本 Spring Security 2.0.0。和 Shiro 相⽐,Spring Security重量级并且配置烦琐,直⾄今天,依然有⼈以此为理由⽽拒绝了解 Spring Security。其实,⾃从 Spring Boot推出后,就彻底颠覆了传统了 JavaEE 开发,⾃动化配置让许多事情变得⾮常容易,包括Spring Security 的配置。在⼀个Spring Boot项⽬中,我们甚⾄只需要引⼊⼀个依赖,不需要任何额外配置,项⽬的所有接⼝就会被⾃动保护起来了。在 Spring Cloud中,很多涉及安全管理的问题,也是⼀个Spring Security依赖两⾏配置就能搞定,在和
Spring 家族的产品⼀起使⽤时,Spring Security 的优势就⾮常明显了。

因此,在微服务时代,我们不需要纠结要不要学习 Spring Security,我们要考虑的是如何快速掌握Spring Security, 并且能够使⽤ Spring Security 实现我们微服务的安全管理。

三、整体架构

应用程序安全性可以归结为差不多两个独立的问题:身份验证(你是谁?)授权(你可以做什么?)。有时候,人们会说“访问控制”而不是“授权”,“授权”会让人感到困惑,可以这样想:“授权”在其他地方已经被使用,为了避免歧义而用“访问控制”来描述。 Spring Security 有一个旨在将认证与授权分开的体系结构,并兼备多种策略和扩展点。

Spring Security架构设计中,认证授权 是分开的,⽆论使⽤什么样的认证⽅式。都不会影响授权,这是两个独⽴的存在,这种独⽴带来的好处之⼀,就是可以⾮常⽅便地整合⼀些外部的解决⽅案。

springbnot普通用户和管理员怎么权限设置_权限管理_02

1、认证

AuthenticationManager

Spring Security中认证是由AuthenticationManager接⼝来负责的,接⼝定义为

springbnot普通用户和管理员怎么权限设置_权限管理_03


它只有一个核心方法Authentication authenticate(Authentication authentication) 一个 AuthenticationManager 认证管理者可能会在 authenticate()方法中做下面三件事中的任意一个:

  • 如果认证成功,返回 Authentication (通常它的authenticated属性为true authenticated=true) .
  • 如果认证失败,抛出 AuthenticationException 异常.
  • 如果无法判断,返回 null

对于AuthenticationException 是一个运行时异常。通常由应用程序以通用方式处理,具体取决于应用程序的风格或目的。 换句话说,用户代码通常不会捕获和处理。需要用户自己去处理这个异常。

AuthenticationManager 最常用的实现是 ProviderManager,在ProviderManager中管理了众多 AuthenticationProvider 实例。在⼀次完整的认证流程中,Spring Security 允许存在多个 AuthenticationProvider ,⽤来实现多种认证⽅式,这些

AuthenticationProvider 都是由ProviderManager进⾏统⼀管理的。

springbnot普通用户和管理员怎么权限设置_Spring_04


具体的代码实现:

springbnot普通用户和管理员怎么权限设置_权限管理_05

Authentication

Spring Security中,通过Authentication来封装用户的验证请求信息,Authentication可以是需要验证和已验证的用户请求信息封装。认证以及认证成功的信息主要是由 Authentication 的实现类进⾏保存的,其接⼝定义


springbnot普通用户和管理员怎么权限设置_ide_06

这个类非常的重要。对于UsernamePasswordAuthenticationToken或者是RememberMeAuthenticationToken都是基于这个的。

public interface Authentication extends Principal, Serializable {
 Collection<? extends GrantedAuthority> getAuthorities();
 Object getCredentials();
 Object getDetails();
 Object getPrincipal();
 boolean isAuthenticated();
 void setAuthenticated(boolean isAuthenticated) throws
IllegalArgumentException; }
  • getAuthorities 获取⽤户权限信息
  • getCredentials 获取⽤户凭证信息,⼀般指密码
  • getDetails 获取⽤户详细信息
  • getPrincipal 获取⽤户身份信息,⽤户名、⽤户对象等
    - isAuthenticated ⽤户是否认证成功

SecurityContextHolder

SecurityContextHolder是用来存储认证信息的,以方便保存用户的状态,供线程内所有方法使用SecurityContext,也就是用户信息。

SecurityContextHolder ⽤来获取登录之后⽤户信息。Spring Security 会将登录⽤户数据保存在 Session 中。但是,为了使⽤⽅便,Spring Security在此基础上还做了⼀些改进,其中最主要的⼀个变化就是线程绑定。当⽤户登录成功后,Spring Security 会将登录成功的⽤户信息保存到 SecurityContextHolder SecurityContextHolder 中的数据保存默认是通过ThreadLocal 来实现的,使⽤ThreadLocal 创建的变量只能被当前线程访问,不能被其他线程访问和修改,也就是⽤户数据和请求线程绑定在⼀起。当登录请求处理完毕后,Spring Security 会将SecurityContextHolder 中的数据拿出来保存到 Session 中,同时将SecurityContexHolder 中的数据清空。以后每当有请求到来时,Spring Security就会先从 Session 中取出⽤户登录数据,保存SecurityContextHolder 中,⽅便在该请求的后续处理过程中使⽤,同时在请求结束时将 SecurityContextHolder 中的数据拿出来保存到 Session 中,然后将 Security SecurityContextHolder 中的数据清空。这⼀策略⾮常⽅便⽤户在Controller、Service层以及任何代码中获取当前登录⽤户数据。

2、授权

当完成认证后,接下来就是授权了。在 Spring Security 的授权体系中,有两个关键接⼝

AccessDecisionManager

AccessDecisionManager (访问决策管理器),⽤来决定此次访问是否被允许

springbnot普通用户和管理员怎么权限设置_Java_07


注意这里的ConfigAttribute类,后文会提到。

AccessDecisionVoter

AccessDecisionVoter (访问决定投票器),投票器会检查⽤户是否具备应有的⻆⾊,进⽽投出赞成、反对或者弃权票。

springbnot普通用户和管理员怎么权限设置_ide_08


AccesDecisionVoterAccessDecisionManager 都有众多的实现类,在

AccessDecisionManager 中会换个遍历 AccessDecisionVoter,进⽽决定是否允许⽤户访问,因⽽ AaccesDecisionVoter AccessDecisionManager 两者的关系类似于 AuthenticationProviderProviderManager 的关系。

ConfigAttribute

ConfigAttribute,⽤来保存授权时的⻆⾊信息

springbnot普通用户和管理员怎么权限设置_ide_09


上文中有提到ConfigAttribute, 在 Spring Security 中,⽤户请求⼀个资源(通常是⼀个接⼝或者⼀个 Java ⽅法)需要的⻆⾊会被封装成⼀个ConfigAttribute对象,在 ConfigAttribute 中只有⼀个getAttribute⽅法,该⽅法返回⼀个 String 字符串,就是⻆⾊的名称。⼀般来说,⻆⾊名称都带有⼀个 ROLE_ 前缀,投票器 AccessDecisionVoter 所做的事情,其实就是⽐较⽤户所具各的⻆⾊和请求某个资源所需的ConfigAtuibute之间的关系。

springbnot普通用户和管理员怎么权限设置_SpringSecurity_10


三者的关系可以用这张图来表示。对于ConfigAttribute是一个对比器,用来对比用户权限的。