shiro权限框架

框架简介

Apache Shiro 是 Java 的一个安全框架。相比 Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 就足够了,而且 Shiro 的 API 也是非常简单。
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

Shiro 不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给 Shiro 即可。

对于一个好的框架,从外部来看应该具有非常简单易于使用的 API,从内部来看的话,其应该有一个可扩展的架构,即非常容易插入用户自定义实现。
从外部看
1、 应用代码通过 Subject 来进行认证和授权,而 Subject 又委托给 SecurityManager;
2、 我们需要给 Shiro 的 SecurityManager 注入 Realm,从而让 SecurityManager 能得到合法的用户及其权限进行判断。
在这里插入图片描述

身份认证

在 shiro 中,用户需要提供 principals (身份)和 credentials(证明)给 shiro,让应用来验证用户身份
principals:身份,可以是用户名、邮箱等,唯一即可。
credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。
最常见的 principals 和 credentials 组合就是用户名/密码了。

Realm

Shiro 从Realm 获取安全数据(如用户、角色、权限),SecurityManager要验证用户身份,需要从 Realm 获取用户信息进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/权限以验证用户是否能进行操作;可以把 Realm 看成 DataSource,即安全数据源

1、UserRealm 父类 AuthorizingRealm 将获取 Subject 相关信息分成两步:获取身份验证信息(doGetAuthenticationInfo)及授权信息(doGetAuthorizationInfo);
2、doGetAuthenticationInfo() 获取身份验证相关信息:
首先根据传入的用户名获取 User 信息;然后如果 user 为空,抛出没找到帐号异常 UnknownAccountException;
如果 user找到但锁定了抛出锁定异常 LockedAccountException;
最后生成 AuthenticationInfo 信息,交给间接父类 AuthenticatingRealm 使用 CredentialsMatcher 进行判断密码是否匹配,
如果不匹配将抛出密码错误异常 IncorrectCredentialsException;
另外如果密码重试此处太多将抛出超出重试次数异常 ExcessiveAttemptsException;
组装 SimpleAuthenticationInfo() 信息并返回
3、doGetAuthorizationInfo 获取授权信息:
PrincipalCollection 是一个身份集合,因为我们现在就一个 Realm,所以直接调用 getPrimaryPrincipal 得到之前传入的用户名即可;然后根据用户名调用 UserService 接口获取角色及权限信息。

AuthenticationInfo 有两个作用:

1、如果 Realm 是 AuthenticatingRealm 子类,则提供给 AuthenticatingRealm 内部使用的CredentialsMatcher 进行凭据验证;
2、提供给 SecurityManager 来创建 Subject(提供身份信息);

PrincipalCollection作用:

Shiro 中同时配置多个 Realm,所以身份信息可能就有多个;因此其提供了 PrincipalCollection 用于聚合这些身份信息

授权

在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)。
主体,即访问应用的用户,在 Shiro 中使用 Subject 代表该用户。

Shiro 支持三种方式的授权

1、编程式

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}

2、注解式

@RequiresRoles("admin")
public void hello() {
//有权限
}

3、在jsp中使用标签

访问控制包括基于角色授权和基于资源授权
在这里插入图片描述
授权流程如下:

1、首先调用 Subject.isPermitted*/hasRole* 接口,其会委托给 SecurityManager,而SecurityManager 接着会委托给 Authorizer;
2、Authorizer 是真正的授权者,如果我们调用如 isPermitted(“user:view”),其首先会通过PermissionResolver 把字符串转换成相应的 Permission 实例;
3、在进行授权之前,其会调用相应的 Realm 获取 Subject 相应的角色/权限用于匹配传入的角色/权限;
4、Authorizer 会判断 Realm 的角色/权限是否和传入的匹配,如果有多个 Realm,会委托给ModularRealmAuthorizer 进行循环判断,如果匹配如 isPermitted*/hasRole*会返回 true,否则返回 false 表示授权失败。

Authorizer、PermissionResolver 及RolePermissionResolver

Authorizer 的职责是进行授权(访问控制),是 Shiro API 中授权核心的入口点,其提供了相应的角色/权限判断接口。
SecurityManager 继承了 Authorizer 接口,且提供了 ModularRealmAuthorizer 用于多 Realm 时的授权匹配。
PermissionResolver 用于解析权限字符串到 Permission 实例,而RolePermissionResolver 用于根据角色解析相应的权限集合。

权限注解

@RequiresAuthentication 表示当前 Subject 已经通过 login 进行了身份验证;即 Subject. isAuthenticated()返回 true。
@RequiresUser 表示当前 Subject 已经身份验证或者通过记住我登录的。
@RequiresGuest 表示当前 Subject 没有身份验证或通过记住我登录过,即是游客身份。
@RequiresRoles(value={“admin”, “user”}, logical= Logical.AND) 表示当前 Subject 需要角色 admin 和 user。
@RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR) 表示当前 Subject 需要权限 user:a 或 user:b。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值