shiro自定义AuthenticationToken适应多认证条件

一般的登陆只需要校验账号和密码两个要素

Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                user.getAccNum(), user.getPasswd());
        try {
            subject.login(usernamePasswordToken);
        } catch (UnknownAccountException uae) {
            return result.failed("账号或密码错误");
        } catch (IncorrectCredentialsException ice) {
            return result.failed("账号或密码错误");
        } catch (LockedAccountException lae) {
            return result.failed("账号被冻结");
        } catch (RuntimeException re) {
            return result.failed(re.getMessage());
        }

如上,默认的UsernamePasswordToken就能满足需求
现有需求,不仅需要账号和密码,还需要附带一个组织id来校验用户信息,解决方案,自行重写token

一、定义token

package cn.com.suntree.treeback.config;

import org.apache.shiro.authc.AuthenticationToken;

public class MyAuthenticationToken implements AuthenticationToken {


    private String companyId;//新增的校验因子
    /**
     * The username
     */
    private String username;

    /**
     * The password, in char[] format
     */
    private char[] password;

    public void setCompanyId(String companyId){
        this.companyId = companyId;
    }
    public String getCompanyId(){
        return companyId;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(char[] password) {
        this.password = password;
    }

    public Object getPrincipal() {
        return getUsername();
    }

    public Object getCredentials() {
        return getPassword();
    }

    public char[] getPassword() {
        return password;
    }

    public String getUsername() {
        return username;
    }

    public MyAuthenticationToken() {
    }
    public MyAuthenticationToken(final String username, final char[] password,
                                 final String companyId) {

        this.username = username;
        this.password = password;
        this.companyId = companyId;
    }

}

二、复写supports方法

在自定义realm中复写supports方法,使之能识别自定义token

 @Override
        public boolean supports(AuthenticationToken token){
            return token != null && token instanceof MyAuthenticationToken;
        }

三、改造身份认证方法doGetAuthenticationInfo

 @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            MyAuthenticationToken token = (MyAuthenticationToken)authenticationToken;//强转为自定义token

            SysUserBack u = new SysUserBack();
            u.setAccNum(token.getUsername());
            u.setCompanyId(token.getCompanyId());
            SysUserBack user = userBackService.getUserByAcc(u);
            System.err.println(user);
            if (user == null) {
                throw new UnknownAccountException();
            } else if ("0".equals(user.getIsLock())) {
                throw new LockedAccountException(); // 帐号冻结,非正常

            } else {
                SimpleAuthenticationInfo simpleAuthenticationInfo =
                        new SimpleAuthenticationInfo(user, user.getBackPasswd(), this.getName());
                return simpleAuthenticationInfo;
            }
        }

三、修改login

使用自定义的token

Subject subject = SecurityUtils.getSubject();
        subject.getSession().setTimeout(28800000);
        MyAuthenticationToken usernamePasswordToken = new MyAuthenticationToken(
                sysUserBack.getAccNum(), sysUserBack.getBackPasswd().toCharArray(),companyId);
        
        try {
            subject.login(usernamePasswordToken);
        } catch (UnknownAccountException uae) {
            return result.failed("账号或密码错误");
        } catch (IncorrectCredentialsException ice) {
            return result.failed("账号或密码错误");
        } catch (LockedAccountException lae) {
            return result.failed("账号被冻结");
        } catch (RuntimeException re) {
            return result.failed(re.getMessage());
        }

搞定~

补充一个完整的realm


    /**
     * 自定义 - 数据域
     */
    public class MyShiroRealm extends AuthorizingRealm {

        @Autowired
        @Lazy
        private SysUserBackService userBackService;

        /**
         * @param principalCollection
         * @return
         * @implNote 功能授权
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            SysUserBack user = (SysUserBack) principalCollection.getPrimaryPrincipal();
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

            user = userBackService.getUserDetailInfoByUserId(user.getUserID(), user.getCompanyId());
            List<Role> roleList = user.getRoleList();
            for (Role role : roleList) {
                authorizationInfo.addRole(role.getRoleName());
                if (CommonUtil.check(role.getPowerList())) {
                    for (Power permission : role.getPowerList()) {
                        authorizationInfo.addStringPermission(permission.getUrl());
                    }
                }
            }
            return authorizationInfo;
        }

        /**
         * @param authenticationToken
         * @return
         * @throws AuthenticationException
         * @implNote 身份认证
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            MyAuthenticationToken token = (MyAuthenticationToken)authenticationToken;

            SysUserBack u = new SysUserBack();
            u.setAccNum(token.getUsername());
            u.setCompanyId(token.getCompanyId());
            SysUserBack user = userBackService.getUserByAcc(u);
            System.err.println(user);
            if (user == null) {
                throw new UnknownAccountException();
            } else if ("0".equals(user.getIsLock())) {
                throw new LockedAccountException(); // 帐号冻结,非正常

            } else {
                SimpleAuthenticationInfo simpleAuthenticationInfo =
                        new SimpleAuthenticationInfo(user, user.getBackPasswd(), this.getName());
                return simpleAuthenticationInfo;
            }
        }

        @Override
        public boolean supports(AuthenticationToken token){
            return token != null && token instanceof MyAuthenticationToken;
        }

    }

猜你喜欢

转载自blog.csdn.net/leisure_life/article/details/104697225
今日推荐