目录
2.2、Security的过滤器链(FilterChain)
一、JWT( json web token)
一种生成token的处理机制,基于数字签名,定义了一种紧凑的、自包含的JSON对象在各方间进行安全是信息传输,由于其无状态的特性,常用于:鉴权、数据交换等方向。
1.1、JWT数据结构
Header、Payload、Signature
(1)Header :定义了token的类型,以及算法名称。
{
"alg":"RSA", # 定义算法名称
"type":"JWT" # 定义token类型
}
(2)Payload:负载。
用于声明(要求),声明是关于实体(通常是用户)和其他数据的声明。
声明有三种类型: registered, public 和 private。
一般来说,Payload 承载的基本为用户基本信息
Registered claims : 这里有一组预定义的声明,它们不是强制的,但是推荐。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
Public claims: 可以随意定义。
Private claims: 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。
{
"user_name": "19900002121", #用户名
"scope": ["all"], #范围
"loginName": "19900002121", #登陆名
"company": "shop", #项目类型
"exp": 1568750741, #过期时间
"authorities": [ #访问权限
"/order/**",
"/role/**",
"/admin/**",
"/user/**",
"ROLE_超级管理员",
"adminManage",
"roleManage"
],
"jti": "21b9b05f-fad2-463f-bb6e-3dbc76442bfa",
"client_id": "imooc"
}
(3)Signature:签名
想要获取签名必须包含以下信息:base64UrlEncode(header)、base64UrlEncode(payload)、密钥
RSA(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
注: RSA-Header中的算法类型
1.2、JWT使用流程
二、Spring Security
Spring提供的一套基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。Spring Security 采用了“责任链”的设计模式,使用了大概15个Filter(过滤器)组成的FilterChain(过滤器链)来进行用户认证(Authentication)、授权(Authorization)。
2.1、Security的作用
(1)用户认证(Authentication):主要用于验证当前用户是否为该系统的合法用户。即通过用户提供的用户名、密码、手机号、验证码来判断当前用户能否访问当前系统。
(2)用户授权(Authorization):主要用户验证当前用户(合法用户)是否拥有权限访问系统资源或执行某些操作。举例来说:某份文件对于用户A来说是拥有权限访问,对于用户B来说是没有访问权限的,因此我们就需要对用户的权限进行设定并校验。
2.2、Security的过滤器链(FilterChain)
-
-
WebAsyncManagerIntegrationFilter: 将Security上下文与Spring Web 中用于处理异步请求映射的WebAsyncManager进行集成。
-
SecurityContextPersistenceFilter:会在请求开始时从配置好的 SecurityContextRepository 中获取 SecurityContext然后把它设置给 SecurityContextHolder。在请求完成后将 SecurityContextHolder 持有的 SecurityContext 再保存到配置好的
-
SecurityContextRepository,同时清除 securityContextHolder 所持有的 SecurityContext;
-
HeaderWriterFilter:用于将头信息加入响应中。
-
CsrfFilter:用于处理跨站请求伪造。
-
LogoutFilter:用于处理退出登录。
-
UsernamePasswordAuthenticationFilter:用于处理基于表单的登录请求,从表单中获取用户名和密码。默认情况下处理来自 /login 的请求。从表单中获取用户名和密码时,默认使用的表单 name 值为 username 和 password,这两个值可以通过设置这个过滤器的usernameParameter 和 passwordParameter 两个参数的值进行修改。
-
DefaultLoginPageGeneratingFilter:如果没有配置登录页面,那系统初始化时就会配置这个过滤器,并且用于在需要进行登录时生成一个登录表单页面。
-
BasicAuthenticationFilter:检测和处理 http basic 认证。
-
RequestCacheAwareFilter:用来处理请求的缓存。
-
SecurityContextHolderAwareRequestFilter:主要是包装请求对象request。
-
AnonymousAuthenticationFilter:检测 SecurityContextHolder 中是否存在 Authentication 对象,如果不存在为其提供一个匿名 Authentication。
-
SessionManagementFilter:管理 session 的过滤器
-
ExceptionTranslationFilter: 能够捕获来自 FilterChain 所有的异常,并进行处理。但是它只会处理两类异常:AuthenticationException 和 AccessDeniedException,其它的异常它会继续抛出。(1)如果捕获到的是 AuthenticationException,那么将会使用其对应的 AuthenticationEntryPoint 的commence()处理。在处 理之前,ExceptionTranslationFilter先使用 RequestCache 将当前的HttpServerletRequest的信息保存起来,以至于用户成功登录后可以跳转到之前的界面; (2)如果捕获到的是 AccessDeniedException,那么将视当前访问的用户是否已经登录认证做不同的处理,如果未登录,则会使用关联的 AuthenticationEntryPoint 的 commence()方法进行处理,否则将使用关联的 AccessDeniedHandler 的handle()方法进行处理。
-
FilterSecurityInterceptor:是用于保护Http 资源的,它需要一个AccessDecisionManager和一个AuthenticationManager 的引用。它会从 SecurityContextHolder 获取 Authentication,然后通过 SecurityMetadataSource 可以得知当前请求是否在请求受保护的资源。对于请求那些受保护的资源,如果Authentication.isAuthenticated()返回false或者FilterSecurityInterceptor的alwaysReauthenticate 属性为 true,那么将会使用其引用的 AuthenticationManager 再认证一次,认证之后再使用认证后的 Authentication 替换 SecurityContextHolder 中拥有的那个。然后就是利用AccessDecisionManager 进行权限的检查;
-
RememberMeAuthenticationFilter:当用户没有登录而直接访问资源时, 从 cookie 里找出用户的信息, 如果 Spring Security 能够识别出用户提供的remember me cookie, 用户将不必填写用户名和密码, 而是直接登录进入系统,该过滤器默认不开启。
-
2.3、过滤器链执行流程
三、Apache Shiro
Apache Shiro 是一款强大且易用的Java安全框架。在轻量级的程序应用中应用较为广为广泛,对spring security的功能进行了简化,提供了身份验证、授权、密码和会话管理等功能。
3.1、Shiro的核心功能
-
-
-
身份验证: 提供了与Spring Security相同的用户认证功能,用于对用户身份进行验证
-
授权: 与Authorization一样提供了用户权限的管理功能
-
Session Management:会话管理。即用户登录一次为一次会话,在用户没有退出之前,用户所用信息都存储在会话中
-
Cryptography:加密。保护了数据的安全性,如:对用户密码进行加密存储进数据库,防止用户密码被盗用
-
Web Support:提供了Web 支持
-
Caching: 缓存。在用户登录后将用户基本信息、权限等相关信息存储进缓存中,提高查询效率
-
Concurrency:Shiro支持多线程应用的并发验证,即在一个线程中开启另外一个线程,可以把用户相关的权限传递过去
-
Testing:提供测试支持
-
Run As:允许一个用户假装成另一用户进行访问当前系统(前提为当前系统允许这样操作)
-
Remember Me:类似于记住密码
-
-
3.2、Shiro核心组件
-
-
Subject:主体。代表了与当前应用交互的任何东西,如网络爬虫,机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者
-
SecurityManager:SecurityManager 是 Shiro的核心,初始化时协调各个模块运行。然而,一 旦 SecurityManager协调完毕,SecurityManager 会被单独留下,且我 们只需要去操作Subject即可,无需操SecurityManager 。 但是我们 得知道,当我们正与一个 Subject 进行交互时,实质上是 SecurityManager在处理 Subject 安全操作。
-
Realms域:Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
总结:
Shiro配置更加容易理解,配置相对来说说较容易上手;security配置常需要重写大量过滤器配置来实现自定义逻辑。因此Security的自由性相对
在spring的环境下,security整合性更好。Shiro对很多其他的框架兼容性更好,号称是无缝集成。
shiro 不仅仅可以使用在web中,它可以工作在任何应用环境中。 在集群会话时Shiro最重要的一个好处或许就是它的会话是独立于容器的。 Shiro提供的密码加密使用起来非常方便。
控制精度: 注解方式控制权限只能是在方法上控制,无法控制类级别访问。