Apache Shiro(二)——认证与授权

Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密。
Shiro 架构如下图所示:
在这里插入图片描述

认证

身份认证

身份验证:一般需要提供如身份 ID 等一些标识信息来表明登录者的身份,如提供 email,用户名/密码来证明。在 shiro 中,用户需要 提供 principals (身份)和 credentials(证明) 给 shiro,从而应用能验证用户身份。

principals身份,即主体的标识属性,可以是任何属性,如用户名、邮箱等,唯一即可。一个主体可以有多个 principals,但只有一个Primary principals,一般是用户名/邮箱/手机号。
credentials证明/凭证,即只有主体知道的安全值,如密码/数字证
书等。

最常见的 principals 和 credentials 组合就是用户名/密码了。

身份验证基本流程

1、收集用户身份/凭证,即如用户名/密码
2、调用 Subject.login 进行登录,如果失败将得到相应的 AuthenticationException 异常,根据异常提示用户错误信息;否则登录成功。
3、创建自定义的 Realm 类,继承org.apache.shiro.realm.AuthorizingRealm 类,实现doGetAuthenticationInfo() 方法。

身份验证示例

1、配置pom文件,倒入jar包

	<dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

2、编写测试类

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;

public class Authentication {

    private SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();

    @Before
    public void addUser() {

        simpleAccountRealm.addAccount("cczhang", "123456");
    }

    @Test
    public void testAuthentication() {

//      1、创建SecurityManager环境,要把 realm 设置进defaultSecurityManage
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();

        defaultSecurityManager.setRealm(simpleAccountRealm);
//      2、主体提交认证请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();
//      3、把用户名和密码封装为 UsernamePasswordToken 对象
        UsernamePasswordToken token = new UsernamePasswordToken("cczhang", "123456");

        try {
//      4、执行登录.
            subject.login(token);
        }
//      5、若没有指定的账户, 则 shiro 将会抛出 UnknownAccountException 异常.
        catch (UnknownAccountException uae) {
            return;
        }
//      6、若账户存在, 但密码不匹配, 则 shiro 会抛出 IncorrectCredentialsException 异常。
        catch (IncorrectCredentialsException ice) {
            return;
        }
        // 用户被锁定的异常 LockedAccountException
        catch (LockedAccountException lae) {
        }
        // 所有认证时异常的父类.
        catch (AuthenticationException ae) {
        }
//        测试当前的用户是否已经被认证. 即是否已经登录.
        System.out.println("Authenticated" + "--" + subject.isAuthenticated());

        subject.logout();

        System.out.println("Authenticated" + "--" + subject.isAuthenticated());

    }
}

3、测试身份认证

身份认证流程

身份认证流程

1、首先调用 Subject.login(token) 进行登录,其会自动委托给SecurityManager。

2、SecurityManager 负责真正的身份验证逻辑,它会委托给Authenticator 进行身份验证。

3、Authenticator 才是真正的身份验证者,Shiro API 中核心的身份认证入口点,此处可以自定义插入自己的实现。

4、Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用AuthenticationStrategy 进行多 Realm 身份验证。

5、Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

授权

授权,也叫访问控制,即在应用中控制谁访问哪些资源(如访问页面/编辑数据/页面操作等)。在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)。

主体(Subject):访问应用的用户,在 Shiro 中使用 Subject 代表该用户。用户只有授权后才允许访问相应的资源。

资源(Resource):在应用中用户可以访问的 URL,比如访问 JSP 页面、查看/编辑某些数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问。

权限(Permission):安全策略中的原子授权单位,通过权限我们可以表示在应用中用户有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源,如:访问用户列表页面查看/新增/修改/删除用户数据(即很多时候都是CRUD(增查改删)式权限控制)等。权限代表了用户有没有操作某个资源的权利,即反映在某个资源上的操作允不允许。

Shiro 支持粗粒度权限(如用户模块的所有权限)和细粒度权限(操作某个用户的权限,即实例级别的)。

角色(Role):权限的集合,一般情况下会赋予用户角色而不是权限,即这样用户可以拥有一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、CTO、开发工程师等都是角色,不同的角色拥有一组不同的权限。

授权方式

Shiro 支持三种方式的授权:
编程式:通过写if/else 授权代码块完成
注解式:通过在执行的Java方法上放置相应的注解完成,没有权限将抛出相应的异常
JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成
在这里插入图片描述

Permissions

规则:资源标识符:操作:对象实例 ID 即对哪个资源的哪个实例可以进行什么操作. 其默认支持通配符权限字符串,

: 表示资源/操作/实例的分割;
, 表示操作的分割,
星号表示任意资源/操作/实例。

多层次管理:
例如:user:query、user:edit
冒号是一个特殊字符,它用来分隔权限字符串的下一部件:第一部分是权限被操作的领域,第二部分是被执行的操作。

多个值:每个部件能够保护多个值。因此,除了授予用户 user:query和 user:edit 权限外,也可以简单地授予他们一个:user:query, edit。

还可以用 * 号代替所有的值,如:user:* , 也可以写:*:query,表示某个用户在所有的领域都有 query 的权限。

Shiro 的 Permissions

在这里插入图片描述

授权流程

在这里插入图片描述

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表示授权失败。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值