shiro原理

本文链接:https://blog.csdn.net/romantic_PK/article/details/81510003
        Apache Shiro是一个强大而灵活的开源安全框架,它能够干净利落地处理身份认证、授权、企业会话管理和加密。相比spring security框架更简单灵活,spring security对spring依赖较强。shiro可以实现web系统、c/s、分布式等系统权限管理。

        Shiro完整架构图,如下图:

       

        核心组件:

Subject:主体,即当前操作用户
SecurityManager:安全管理器,它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务 
Realm:领域,充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息      
Authenticator:认证器,AuthenticationStrategy如果存在多个realm,则按着具体的策略进行登录控制,例如:如果有一个realm成功即可登录、必须所有realm都成功才能登录等 
Authorizer:授权器,决定subject能拥有什么样角色或者权限。
SessionManager:session管理器,创建和管理用户session。通过设置这个管理器,shiro可以在任何环境下使用session。
CacheManager:缓存管理器,可以减少不必要的后台访问。提高应用效率,增加用户体验。
Cryptography:Shiro的api大幅度简化java api中繁琐的密码加密。
 

        Shiro认证流程:

     

subject(主体)请求认证,调用subject.login(token)
SecurityManager (安全管理器)执行认证
SecurityManager通过ModularRealmAuthenticator进行认证。
ModularRealmAuthenticator将token传给realm,realm根据token中用户信息从数据库查询用户信息(包括身份和凭证)
realm如果查询不到用户给ModularRealmAuthenticator返回null,ModularRealmAuthenticator抛出异常(用户不存在)
realm如果查询到用户给ModularRealmAuthenticator返回AuthenticationInfo(认证信息)
ModularRealmAuthenticator拿着AuthenticationInfo(认证信息)去进行凭证(密码)比对。如果一致则认证通过,如果不致抛出异常(凭证错误)。
 

       Shiro授权流程:

      

对subject进行授权,调用方法isPermitted("*")或者hasRole("*")
SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据调用realm的授权方法:doGetAuthorizationInfo
realm从数据库查询权限数据,返回ModularRealmAuthorizer
ModularRealmAuthorizer调用PermissionResolver进行权限串比对
如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则没有权限,抛出异常。
  Shiro过滤器:    

过滤器简称

对应的java类

anon

org.apache.shiro.web.filter.authc.AnonymousFilter

authc

org.apache.shiro.web.filter.authc.FormAuthenticationFilter

authcBasic

org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

perms

org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter

port

org.apache.shiro.web.filter.authz.PortFilter

rest

org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

roles

org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

ssl

org.apache.shiro.web.filter.authz.SslFilter

user

org.apache.shiro.web.filter.authc.UserFilter

logout

org.apache.shiro.web.filter.authc.LogoutFilter

 anon:/admins/**=anon,没有参数,表示可以匿名使用。

 authc:/admins/user/**=authc,没有参数,表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,通过记住我认证通过的不可以访问;

 perms:/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法;

 user:/admins/user/**=user,没有参数,表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查;

 logout:/logout=logout,没有参数,表示退出登录,清楚session。

会话管理器(sessionManager):Shiro默认是从cookie中读取sessionId以此来维持会话,也可以自定义sessionManager,继承DefaultWebSessionManager类,重写getSessionId方法。如果在分布式集群环境中可以把session放在redis管理,可以实现session共享。

缓存管理器(cacheManager):Shiro默认整合了EhCache,来实现缓存,可以自定义cacheManager。如果在分布式集群环境中可以把session放在redis管理,可以实现cache共享。

记住我(rememeberMeManager):用户登陆选择“自动登陆”本次登陆成功会向cookie写身份信息,下次登陆从cookie中取出身份信息实现自动登陆。如果使用了UserFilter(例如:/user*=user),又如果设置记住我,下次访问这些url时可以不用登陆。

三种授权方式:
1.编程式授权
  1.1.基于角色的访问控制
  1.2.基于权限的访问控制
例子如下:
hasRole(String role)判断是否有角色,返回布尔类型
hasRoles(List<String> list)判断是否有角色,返回布尔类型数组
hasAllRoles(Collection<String> list)判断是都有角色,返回布尔类型
checkRole(String role)判断是否有角色,无返回值,如果没有角色则报异常
checkPermission()判断是否有权限,无返回值,如果没有权限则报异常
isPermitted(String permis)判断是否有权限,返回布尔类型

2.注解式授权
例子如下:
@@RequiresAuthentication 要求当前 Subject 已经在当前的 session 中被验证通过才能被访问或调用。
@RequiresGuest 要求当前的 Subject 是一个"guest",也就是说,他们必须是在之前的 session 中没有被验证或被记住才能被访问或调用。
@RequiresPermissions("account:create") 要求当前的 Subject 被允许一个或多个权限,以便执行注解的方法。
@RequiresRoles("administrator") 要求当前的 Subject 拥有所有指定的角色。如果他们没有,则该方法将不会被执行,而且 AuthorizationException 异常将会被抛出
@RequiresUser RequiresUser 注解需要当前的 Subject 是一个应用程序用户才能被注解的类/实例/方法访问或调用。一个“应用程序用户”被定义为一个拥有已知身份,或在当前 session 中由于通过验证被确认,或者在之前 session 中的'RememberMe'服务被记住。

3.jsp标签授权
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
Guest 标签:用户没有身份验证时显示相应信息,即游客访问信息;
User 标签:用户已经身份验证/记住我登录后显示相应的信息;
Authenticated 标签:用户已经身份验证通过,即 Subject.login 登录成功,不是记住我登录的。
notAuthenticated 标签:用户没有身份验证通过,即没有调用 Subject.login 进行登录,包括记住我自动登录
的也属于未进行身份验证。
principal 标签 显示用户身份信息,默认调用 Subject.getPrincipal()获取,即 Primary Principal。
hasRole 标签 如果当前 Subject 有角色将显示 body 体内容。
hasAnyRoles 标签 如果当前 Subject 有任意一个角色(或的关系)将显示 body 体内容。
hasPermission 标签 如果当前 Subject 有权限将显示 body 体内容。
lacksPermission 标签 如果当前 Subject 没有权限将显示 body 体内容。

Spring Security与Apache Shiro区别:

1. Shiro配置更加容易理解,容易上手。security配置相对比较难懂;

2. 在Spring的环境下,security整合性更好。Shiro对很多其他的框架兼容性更好,号称是无缝集成;

3. Shiro不仅仅可以使用在web中,它可以工作在任何应用环境中;

4. 在集群会话时Shiro最重要的一个好处或许就是它的会话是独立于容器的;

5. Shiro提供的密码加密使用起来非常方便。
————————————————
版权声明:本文为CSDN博主「romanitc」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/romantic_PK/article/details/81510003

积极向上,奋发图强,向着哪个目标前进。
原文地址:https://www.cnblogs.com/wzq-xf/p/11775871.html