10.springboot2.X整合shiro之多Realm

添加多个自定义的Realm实现类,定义你的认证和权限认证逻辑.这里演示代码为复制了一份CustomRealm2 .
这样的好处是当你的用户表不是一张表可以分别认证用户,比如学生表 教师表 分别都有账户密码 权限
步骤:
1.准备一个以上的自定义Realm类:
/授权和认证逻/

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println ("执行授权逻辑");

        SimpleAuthorizationInfo simpleInfo = new SimpleAuthorizationInfo ( );
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal ( );
        //之后在数据库查询他是什么角色 什么权限一一添加他们
        System.out.println ("查询角色和权限:" + name);
        List<String> listRoles = userService.listRoles (name);
        // simpleInfo.addRoles (listRoles);直接添加多个角色或者forench添加
        for (String role : listRoles) {
            simpleInfo.addRole (role);
        }
        //添加角色下的权限 比如crud
        List<String> listPermissions = userService.listPermissions (name);
        System.out.println (listPermissions.size ( ));
        simpleInfo.addStringPermissions (listPermissions);
        //设置好权限返回
        return simpleInfo;
    }

       @Override
    protected SimpleAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        ;
        //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
        if (null == authenticationToken.getPrincipal ( )) {
            return null;
        }
        //这里用于区分两个认证是否都可以加载
        System.out.println ("执行认证逻辑2222222222222222" + getName ( ));

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //获取用户登陆的名
        String name = token.getUsername ( );
        //查出的密码和盐封装成User
        User user = userService.getPwdByName (name);

        if (null == user) {
            //用户名不存在
            return null;//抛出一个空的对象 抛出异常UnknowAccountException
        }
        //密码
        String pwd = user.getPassword ( );
        //盐
        String salt = user.getSalt ( );
        //真盐=name+salt
        salt = name + salt;

        //这里验证authenticationToken和simpleAuthenticationInfo的信息
        return new SimpleAuthenticationInfo (name, pwd, ByteSource.Util.bytes (salt), getName ( ));
    }
}

第二个:修改一下名字和打印语句来区分他们省略
2.ShiroConfig配置修改,添加Realm bean配置和多肉(Realm)认证策略

/*常用的过滤器
* anon:无认证
* authc:必须认证 登陆即可
* user: 使用记住我可以直接访问
* perms: 必须有资源权限 比如crud
* roles: 必须有角色权限
* */
@Configuration
public class ShiroConfig {
    /**
     * 创建自定义配置的Realm
     */
    @Bean
    CustomRealm myRealm() {
        CustomRealm customRealm = new CustomRealm ( );

        //注入加密算法
        customRealm.setCredentialsMatcher (hashedCredentialsMatcher ());
        return customRealm;
    }
    @Bean
    CustomRealm2 myRealm2() {
        CustomRealm2 customRealm = new CustomRealm2 ( );

        //注入加密算法
        customRealm.setCredentialsMatcher (hashedCredentialsMatcher ());
        return customRealm;
    }
    //认证策略配置需要把realm集合配置进来这
    @Bean
    public ModularRealmAuthenticator authenticators(){
        ModularRealmAuthenticator model=new ModularRealmAuthenticator ();
        AllSuccessfulStrategy authenticationStrategy= new AllSuccessfulStrategy();
        //最少一个成功验证  都失败则返回null
        AtLeastOneSuccessfulStrategy atLeastOne=new AtLeastOneSuccessfulStrategy ();
        //最先验证成功的那个返回,剩下的不验证  都失败则返回null
        FirstSuccessfulStrategy first =new FirstSuccessfulStrategy ();
        //添加策略属性为其中一个对象
        List list= new ArrayList<Realm> ();
        list.add (myRealm ());
        list.add (myRealm2 ());
        //多策略需要先把realm配置属性加进去
        model.setRealms (list);
        model.setAuthenticationStrategy (authenticationStrategy);
        return model;

    }
    /**
     * 创建DefaultWebSecurityManager管理器,使它管理自定义的Realm
     */
    @Bean
    DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager ( );
       List list= new ArrayList<Realm> ();
        //多realm配置通过以下获取
        List list= new ArrayList<Realm> ();
         list.add (myRealm ());
         list.add (myRealm2 ());
         //realm配置通过以下获取
         manager.setRealms (list);
          //自定义的Realm交给manager

           // manager.setRealm (myRealm ( ));
           //策略设置
        manager.setAuthenticator (authenticators ());
       
        // 自定义缓存实现 使用redis
         // manager.setCacheManager(cacheManager ());
        // 自定义session管理 使用redis
          //manager.setSessionManager(SessionManager ());
        // 使用记住我,注入配置
       manager.setRememberMeManager(new RememberMeConfig ().rememberMeManager ());
        return manager;
    }

    /**
     *创建shiroFilterFactoryBean
     * 关联一个securityManager ( )管理器
     */
    @Bean
    ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean ( );
        bean.setSecurityManager (securityManager ( ));
        //登陆页
        bean.setLoginUrl ("/login");
        //登陆成功后界面
        bean.setSuccessUrl ("/index");
        //未授权跳转到
        bean.setUnauthorizedUrl ("/tip");
        Map<String, String> map = new LinkedHashMap<> ( );
        //anon是把限制权限改为无限制
        //map.put ("/index", "anon");
        //authc 登陆后可以访问
       // map.put ("/**", "authc");
        map.put ("/add", "authc");
        //权限必须有addProduct才可以访问
        map.put ("/update","perms[addProduct]");
        //角色是admin 才可以访问超级管理员界面
        map.put ("/admin","roles[admin]");
        bean.setFilterChainDefinitionMap (map);
        return bean;
    }
    /**用于ShiroDialect和thymeleaf标签配合使用*/
    @Bean(name = "shiroDialect")

    public ShiroDialect shiroDialect(){

        return new ShiroDialect ();

    }



    /**
     * 密码加密算法设置
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        //散列的次数
        hashedCredentialsMatcher.setHashIterations(2);
        return hashedCredentialsMatcher;
    };


}

两个要点:1. DefaultWebSecurityManager securityManager配置list属性
2.ModularRealmAuthenticator authenticators配置策略和list同上

最后发现一个问题: AtLeastOneSuccessfulStrategy策略是最少一个验证成功还是第一个验证成功策略.都会有一个问题,就是只要验证账号密码成功了,那么其他realm虽然账号密码验证失败但是也会将权限一起添加.

因为,不同的realm肯定是对不同表的验证,他们的账号必须不同.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值