博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
shiro权限框架
阅读量:2378 次
发布时间:2019-05-10

本文共 3248 字,大约阅读时间需要 10 分钟。

框架简介

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。

转载地址:http://rfaxb.baihongyu.com/

你可能感兴趣的文章
冒号和他的学生们(连载2)——首轮提问
查看>>
正则表达式与文件格式化处理
查看>>
Java EE互联网轻量级框架整合开发
查看>>
Java语言程序设计(基础篇)
查看>>
大型网站技术架构:核心原理与案例分析
查看>>
JAVA并发编程实战
查看>>
RabbitMQ实战++高效部署分布式消息队列
查看>>
微服务设计
查看>>
Spring Cloud微服务实战
查看>>
C++ static 语义
查看>>
C++ static 语义
查看>>
Linux Cgroups概述
查看>>
centos7 硬盘性能测试
查看>>
cgroup使用--cpu资源限制
查看>>
cgroup使用--memory资源限制
查看>>
Redis 单机环境搭建
查看>>
elasticsearch 单机环境搭建
查看>>
spark 独立模式部署
查看>>
Redis 基础命令 --- String篇
查看>>
Redis 基础命令 --- Hash篇
查看>>