ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多Realm验证策略

2021-09-20 23:33:01  阅读:153  来源: 互联网

标签:return String 验证 loginType user Realm public 策略


前言:多Realm验证,有时候会存在多Realm,不同的角色会有不同的验证逻辑,这个时候会需要多Realm。

首先这里编写两个Realm,并且返回name

Realm1:CustomerRealm

public class CustomerRealm extends AuthorizingRealm {

    @Autowired
    @Lazy
    private UserService userService;

    @Override
    public String getName(){
        return "网页登录";
    }

    //授权

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        User user = null;
        user = userService.getUserByPrincipal(principal);
        if(null!=user){
//            return new SimpleAuthenticationInfo(principal,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());

            //这里可以直接存储为user
            return new SimpleAuthenticationInfo(user,user.getPassword(), new MySimpleByteSource(user.getSalt()),this.getName());
        }else{
            return null;
        }
    }
}

Realm2:Customer2Realm

public class Customer2Realm extends AuthorizingRealm {

    @Autowired
    @Lazy
    private UserService userService;

    @Override
    public String getName(){
        return "app登录";
    }

    //授权

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        User user = null;
        user = userService.getUserByPrincipal(principal);
        if(null!=user){
//            return new SimpleAuthenticationInfo(principal,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());

            //这里可以直接存储为user
            return new SimpleAuthenticationInfo(user,user.getPassword(), new MySimpleByteSource(user.getSalt()),this.getName());
        }else{
            return null;
        }
    }
}

多Realm分为两种场景:
一、多个Realm串联认证,只要一个Realm通过,就会通过验证。

public class shiroConfig {

    ... ...
    
    //创建shiro安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(CookieRememberMeManager rememberMeManager, DefaultWebSessionManager mySessionManager){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();

        //配置rememberMe
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager);

        //配置session
        defaultWebSecurityManager.setSessionManager(mySessionManager);

        //如果有多个realm,如果没有配置Token和Authenticator,则两个realm穿行都验证,只要有一个认证成功,则通过
        ArrayList<Realm> realms = new ArrayList<>();
        realms.add(getCustomerRealm());
        realms.add(getCustomer2Realm());

        defaultWebSecurityManager.setRealms(realms);


        return defaultWebSecurityManager;
    }

	... ...

}

二、多个Realm分支认证
1.编写自定义Token继承UsernamePasswordToken,添加loginType属性

public class MyToken extends UsernamePasswordToken {
    private String loginType;
    public MyToken(String username,String password,String loginType){
        super(username, password);
        this.loginType = loginType;
    }

    public String getLoginType() {
        return loginType;
    }

    public void setLoginType(String loginType) {
        this.loginType = loginType;
    }
}

2.编写自定义认证器,继承ModularRealmAuthenticator,更改Realm策略

public class MyModularRealmAuthenticator extends ModularRealmAuthenticator {
    @Override
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        this.assertRealmsConfigured();
        MyToken myToken = (MyToken) authenticationToken;
        String loginType = myToken.getLoginType();

        Collection<Realm> realms = this.getRealms();
        Collection<Realm> myRealms = this.getRealms();
        for(Realm realm:realms){
            if(realm.getName().startsWith(loginType)){
                myRealms.add(realm);
            }
        }
        //这里Realms为最终认证集合
        return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)myRealms.iterator().next(), authenticationToken) : this.doMultiRealmAuthentication(myRealms, authenticationToken);
    }
}

3.shiroConfig

public class shiroConfig {

	... ...
   
    //创建shiro安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(CookieRememberMeManager rememberMeManager, DefaultWebSessionManager mySessionManager){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();

        //配置rememberMe
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager);

        //配置session
        defaultWebSecurityManager.setSessionManager(mySessionManager);

        //如果多个Realm分支验证,则需要自定义认证器
        defaultWebSecurityManager.setAuthenticator(getMyModularRealmAuthenticator());

        ArrayList<Realm> realms = new ArrayList<>();
        realms.add(getCustomerRealm());
        realms.add(getCustomer2Realm());

        defaultWebSecurityManager.setRealms(realms);


        return defaultWebSecurityManager;
    }

   ... ...
   
}

4.注意提交认证时使用自定义Token

            MyToken token = new MyToken(user.getUsername(),user.getPassword(),"网页登录");
            subject.login(token);

标签:return,String,验证,loginType,user,Realm,public,策略
来源: https://blog.csdn.net/weixin_45390688/article/details/120396199

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有