前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ShiroRealm中配置散列And授权

ShiroRealm中配置散列And授权

原创
作者头像
杨不易呀
修改2023-11-29 15:03:02
2303
修改2023-11-29 15:03:02
举报
文章被收录于专栏:杨不易呀杨不易呀

前言

Shiro自定义RealmAnd散列算法

ini 文件当中配置散列

相关配置内容如下所示:

代码语言:txt
复制
[main]
# 定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
# 散列算法
credentialsMatcher.hashAlgorithmName=md5
# 散列次数
credentialsMatcher.hashIterations=3
# 指定realm
myRealm=com.yby6.realm.MyRealm
# 配置散列
myRealm.credentialsMatcher=$credentialsMatcher
# 配置自定义散列
securityManager.realms=$myRealm

要保证存储在数据库中的密码是经过散列之后的,不然认证器进行认证的时候是通过你定义的规则去进行认证的,而你数据库存储的不一致会导致不成功,假如你设置认证的相关信息为盐为 yby6 而数据库中已经存储的密码是通过 JonathanTang 盐值进行加密存储的,你登录的时候认证器去验证的时候就会导致双方不一致,所以数据库中存储的信息需要和你认证器设置的规则加密之后的信息一致才行。

首先我们自己使用 MD5 规则加密一串密文出来。

代码语言:txt
复制
@Test
public void encryption() {
    SimpleHash simpleHash = new SimpleHash("md5", "1234", "it6666", 3);
    System.out.println(simpleHash);
}
代码语言:txt
复制
80abd6b3faad22acb16bc1a11da51b2e

然后更改我们自定义的 Realm,更改之后的内容如下所示:

代码语言:txt
复制
public class MyRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取用户名
        String username = (String) token.getPrincipal();

        // 假如以下定义的用户名和密码是从数据库中查询出来的,实际中需要注入Dao去数据库中进行查询然后进行验证查询出来的信息是否合法
        String myName = "yby6";
        String password = "80abd6b3faad22acb16bc1a11da51b2e";

        // 如果输入的名称不和数据库查询出来的一致
        if (!myName.equals(username)) {
            return null;
        }

        // 如果等于,交给认证器去认证即可我们就无须关心了
        return new SimpleAuthenticationInfo(username, password, ByteSource.Util.bytes("yby6"), this.getName());
    }
}

什么是授权

● 授权,即访问控制,控制谁能访问哪些资源。

● 主体进行身份认证后需要分配权限,方可访问系统的资源,对于某些资源没有权限是无法访问的这就是授权。

使用 ini 的形式配置权限信息

● 在 ini 文件中设置用户、角色、权限的配置规则。

● 用户名=密码,角色1,角色2 ...

● 首先根据用户名找角色,再根据角色找权限,角色是权限集合。

● 权限字符串的规则

○ “资源标识符:操作:资源实例标识符”

○ 对哪个资源的哪个实例具有什么操作。

○ : 是资源 / 操作 / 实例的分割符。

○ 权限字符串也可以使用 * 通配符。

如下将给出一个配置示例如下所示,修改 shiro.ini:

代码语言:txt
复制
[users]
#用户yby6的密码是1234,此用户具有role1和role2两个角色
#用户yangbuyiya的密码是1234,此用户具有role2一个角色
yby6=1234,role1,role2
yangbuyiya=1234,role2
[roles]
#角色role1对资源user拥有create、update权限
role1=user:create,user:update
#角色role2对资源user拥有create、delete权限
role2=user:create,user:delete
#角色role3对资源user拥有create权限
role3=user:create

自定义 Realm 的形式权限

修改 MyRealm.java

代码语言:txt
复制
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    // 获取身份信息
    Object principal = principals.getPrimaryPrincipal();

    // 根据用户名查询该用户的角色和权限
    List<String> roles = new ArrayList<>();
    roles.add("role1");
    roles.add("role2");

    List<String> permissions = new ArrayList<>();
    permissions.add("user:create");
    permissions.add("user:delete");

    // 把角色和权限与 subject 关联在一起,然后进行返回
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    info.addRoles(roles);
    info.addStringPermissions(permissions);
    return info;
}

然后修改之前的测试类,具体修改的内容或者新增的内容如下代码所示, 在认证成功之后才去做授权, 判断当前的用户是否有某一个角色和某一个权限

代码语言:txt
复制
public class Demo {

    public static void main(String[] args) {
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");

        SecurityManager securityManager = factory.getInstance();

        SecurityUtils.setSecurityManager(securityManager);

        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken("yby6", "12345");

        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            System.out.println("用户名不存在");
            e.printStackTrace();
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误");
            e.printStackTrace();
        }

        System.out.println("是否认证" + subject.isAuthenticated());

        subject.logout();

        System.out.println("是否认证" + subject.isAuthenticated());

        // 判断当前用户有没有角色1
        System.out.println(subject.hasRole("role1"));

        // 判断当前用户是否同时具备多个角色
        System.out.println(subject.hasAllRoles(Arrays.asList("role1", "role3")));

        // 判断是否有某一个权限
        System.out.println(subject.isPermitted("user:create"));

        // 判断是否同时有多个权限
        System.out.println(subject.isPermittedAll("user:create", "user:update"));
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 什么是授权
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档