Apache Shiro是一个强大而灵活的开源安全框架,它能够干净利落地处理身份认证、授权、企业会话管理和加密。相比spring security框架更简单灵活,spring security对spring依赖较强。shiro可以实现web系统、c/s、分布式等系统权限管理。
Shiro完整架构图,如下图:
核心组件:
Shiro认证流程:
Shiro授权流程:
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
hasAllRoles(Collection
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提供的密码加密使用起来非常方便。
以下是我精心整理的文章: