shiro 的realm的授权

realm有授权和认证两部分,其中认证在先,授权在后

package cn.taotao.dao;


import org.apache.catalina.realm.AuthenticatedUserRealm;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;


//public class UserRealm extends AuthenticatingRealm {

public class UserRealm extends AuthorizingRealm {

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        Object principal=authenticationToken.getPrincipal();
        // 这一步是需要去数据库取出密码的
       // Object credentials=new String("123456");
        // 若配置了加密,在realm中配置了密码匹配器,这里需要的是数据库的加密后的密码
        Object credentials=new String("e10adc3949ba59abbe56e057f20f883e");
        String realmName=this.getClass().getSimpleName();
        // 这里的密码,是去数据库中取,根据token传来的用户名,去数据库中取。
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal,credentials,realmName);
        return info;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole("role1");

        info.addStringPermission("*:*");
        return info;
    }


}

因为这里的授权,每次都会查数据库,可能导致数据库频繁,但是认证只查询一次。

可以把授权里的,查询那一步,加入到认证里,只是查询到了结果集,

List<Roles> roles = this.RoleService.getRolesByName("xxx")

然后构造一个ActiveUser,在ActivieUser构造方法中把Roles和perimisstion传进去,然后再在

SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(ActiveUser,credentials,realmName);

这一步把activeuser传进去

测试类代码

@Test
    void testRealm(){
        String username="zhangsan";
        String  password = "123456";   // 模拟用户键盘输入
        // 创建工厂,注意引入的包名,SecurityManager 是shiro的包
        Factory<SecurityManager>  factory =  new IniSecurityManagerFactory("classpath:shiro.ini");
    //    Factory<SecurityManager>  factory = new SecurityManagerFactory
        // 取得安全管理器实例


        DefaultSecurityManager securityManager = (DefaultSecurityManager) factory.getInstance();
        UserRealm userRealm= new UserRealm();
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher("MD5");

        userRealm.setCredentialsMatcher(credentialsMatcher);
        securityManager.setRealm(userRealm);

        SecurityUtils.setSecurityManager(securityManager);

        Subject subject = SecurityUtils.getSubject();
        AuthenticationToken authenticationToken = new UsernamePasswordToken(username,password);

        subject.login(authenticationToken);
        System.out.println("认证是否realm,:"+subject.isAuthenticated());
        //subject

        boolean hasRole = subject.hasRole("role1");

        //System.out.println("看是否用ini文件的角色role吗?:"+hasRole);

        //需要在realm中取得info后,自增加role
        System.out.println("看是否用reale文件的角色role吗?:"+hasRole);

        // 支持通配符的权限。 info.addStringPermission("*:*");
        boolean permitted = subject.isPermitted("user:queryxxx");
        System.out.println("是否有permitted:"+permitted);


    }
原文地址:https://www.cnblogs.com/sdgtxuyong/p/15243366.html