zoukankan      html  css  js  c++  java
  • (4)shiro多个realm

    shiro支持多个realm,当设置多个realm的时候,shiro的认证和授权的步骤是怎样的呢。

    多个realm认证原理:

     

    发现需要在执行认证的时候,需要策略来处理多个realm存在的情况。默认实现类有三个策略:

    1. AtLeastOneSuccessfulStrategy :如果一个(或更多)Realm 验证成功,则整体的尝试被认为是成功的。如果没有一个验证成功,则整体尝试失败。

    2. FirstSuccessfulStrategy 只有第一个成功地验证的Realm 返回的信息将被使用。后面的realm会被忽略,如果一个都没有成功则失败。

    3. AllSucessfulStrategy 为了整体的尝试成功,所有配置的Realm 必须验证成功。如果没有一个验证成功,则整体尝试失败。

    ModularRealmAuthenticator 默认的是AtLeastOneSuccessfulStrategy 

    多个realm授权原理:

    当shiro判断是否有对应的角色或者资源的时候,最底层是调用Authenticator的doAuthenticate方法。

    下面是Authenticator的一个实现类(ModularRealmAuthenticator)当有多个realms的时候执行的步骤:

    得到总结:只要有一个realm里面有这个角色或者资源就代表有这个权限

    代码测试

     1,新增一个realm2,无论如何都是通过的,返回的principal固定为test(自己可以根据业务需要,为当前登录的用户设置别的身份)

    public class MyRealm2 extends AuthorizingRealm {
    
        //认证信息,
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    
            String password = new String(upToken.getPassword());
            //模拟用户名密码是否正确
            return new SimpleAuthenticationInfo("test",password,getName());
    
        }
    
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //获取用户名
            String username = (String)getAvailablePrincipal(principals);
            //模拟从数据库查询出来对应的角色和权限
            Set<String> roles = new HashSet<String>();
            roles.add("role_3");
            roles.add("role_4");
    
            Set<String> permissions = new HashSet<String>();
            permissions.add("user:update");
    
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.setRoles(roles);
            info.setStringPermissions(permissions);
            return info;
        }

    2配置文件

    myrealm=com.nfcm.shiro.Realm.MyRealm
    myrealm2=com.nfcm.shiro.Realm.MyRealm2
    #设置策略,必须所有的realm都通过
    authcStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy
    #配置认证器
    authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
    #将验证器和策略关联起来
    authenticator.authenticationStrategy=$authcStrategy
    #注入认证器
    securityManager.authenticator=$authenticator
    #设置realm,这个要最后设置,如果后设置认证器或者授权器,则里面的realms都是空的
    securityManager.realms=$myrealm,$myrealm2

    3.测试代码

            ShiroUtils.login("classpath:shiro-myrealm2.ini","zhang","123456");
    
            Subject subject = SecurityUtils.getSubject();
    
            List<String> principals =subject.getPrincipals().asList();
            for (String principal:principals) {
                System.out.println(principal);
            }
    
            System.out.println(subject.getPrincipals().getPrimaryPrincipal());
            //是否通过认证
            System.out.println(subject.isAuthenticated());
            //是否有role1角色
            System.out.println(subject.hasRole("role_1"));
            //realm2里面的角色
            System.out.println(subject.hasRole("role_3"));
    
            System.out.println(subject.isPermitted("user:create"));
            //realm2里面的资源
            System.out.println(subject.isPermitted("user:update"));

    最后输出结果:

    zhang
    test
    zhang
    true
    true
    true
    true
    true

    getPrimaryPrincipal方法获取的是第一个realm里面的身份。

    subject.getPrincipals().fromRealm("myrealm2")可以获取指定的realm里面的身份信息,返回的是一个集合,获取第一个即可。

    github代码地址

    https://github.com/cmniefei/shiroparent

  • 相关阅读:
    【leetcode】Binary Search Tree Iterator
    【leetcode】Palindrome Partitioning II
    【leetcode】Best Time to Buy and Sell Stock III
    【leetcode】Best Time to Buy and Sell Stock II
    【leetcode】Longest Consecutive Sequence
    【leetcode】Factorial Trailing Zeroes
    【leetcode】Simplify Path
    【leetcode】Generate Parentheses
    【leetcode】Combination Sum II
    【leetcode】Combination Sum
  • 原文地址:https://www.cnblogs.com/nfcm/p/9889969.html
Copyright © 2011-2022 走看看