美文网首页
Shiro实现免密登陆

Shiro实现免密登陆

作者: 天不错啊 | 来源:发表于2020-01-09 00:31 被阅读0次

一、前言

需求:对接第三方登陆,实现绕过原有Shiro认证登陆。
网上例子都有,基本都可以用,反正我也抄别人的。

二、实现方案

1. 实现UsernamePasswordToken

/**
 * @author jihongyuan
 * @date 2020/1/8 14:42
 * 自定义token 继承UsernamePasswordToken,
 * 账号密码登陆(password) 和 免密登陆(nopassword)
 */

public class EasyUsernameToken extends UsernamePasswordToken {
    private static final long serialVersionUID = -2564928913725078138L;

    private LoginType type;

    public EasyUsernameToken() {
        super();
    }

    /**
     * 免密登录
     */
    public EasyUsernameToken(String username) {
        super(username, "", false, null);
        this.type = LoginType.NOPASSWD;
    }

    /**
     * 账号密码登录
     */
    public EasyUsernameToken(String username, String password, boolean rememberMe) {
        super(username, password, rememberMe, null);
        this.type = LoginType.PASSWORD;
    }

    public LoginType getType() {
        return type;
    }

    public void setType(LoginType type) {
        this.type = type;
    }

}

代码都很简单,没什么要说的

2. LoginType枚举

public enum  LoginType {
    /** 密码登录 */
    PASSWORD("password"),
    /** 密码登录 */
    NOPASSWD("nopassword");
    /** 状态值 */
    private String code;
    private LoginType(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }
}

3. 实现HashedCredentialsMatcher

public class EasyCredentialsMatch extends HashedCredentialsMatcher {

    /**
     * 重写方法
     * 区分 密码和非密码登录
     * 此次无需记录登录次数 详情看SysPasswordService
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        EasyUsernameToken easyUsernameToken = (EasyUsernameToken) token;

        //免密登录,不验证密码
        if (LoginType.NOPASSWD.equals(easyUsernameToken.getType())) {
            return true;
        }

        //密码登录
        Object tokenHashedCredentials = hashProvidedCredentials(token, info);
        Object accountCredentials = getCredentials(info);
        return equals(tokenHashedCredentials, accountCredentials);
    }
}

代码都很简单,没啥要注意的。

4. Spring Boot配置

    @Bean
    public EasyCredentialsMatch customCredentialsMatch() {
        EasyCredentialsMatch customCredentialsMatch = new EasyCredentialsMatch();
        customCredentialsMatch.setHashAlgorithmName("md5");
        customCredentialsMatch.setHashIterations(3);
        customCredentialsMatch.setStoredCredentialsHexEncoded(true);
        return customCredentialsMatch;
    }

5. 实现AuthorizingRealm

public class UserRealm extends AuthorizingRealm {
  @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
      ......................
    }

      /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        EasyUsernameToken upToken = (EasyUsernameToken) token;
        String username = upToken.getUsername();

        SysUser user = null;
        // 密码登录
        if (upToken.getType().getCode().equals(LoginType.PASSWORD.getCode())) {
            String password;
            if (upToken.getPassword() != null) {
                password = new String(upToken.getPassword());
                try {
                    user = loginService.login(username, password);
                } ......
                catch (Exception e) {
                    log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
                    throw new AuthenticationException(e.getMessage(), e);
                }
            }
        } else if (upToken.getType().getCode().equals(LoginType.NOPASSWD.getCode())) {
            // 第三方登录
            ......
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, upToken.getPassword(), getName());
        return info;
    }
}

6. 使用

    private AjaxResult login(String username, String password, Boolean rememberMe) {
        EasyUsernameToken token = new EasyUsernameToken(username, password, rememberMe);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            return success();
        } catch (AuthenticationException e) {
            String msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

三、总结

代码都网上抄的,找不到原文了。
注意一下强转EasyUsernameToken就好。

代码非常的简单!!!

相关文章

  • Shiro实现免密登陆

    一、前言 需求:对接第三方登陆,实现绕过原有Shiro认证登陆。网上例子都有,基本都可以用,反正我也抄别人的。 二...

  • Hadoop用户配置免密登陆

    Hadoop用户配置免密登陆,参考其他免密配置方法自己总结的更简洁的步骤。要实现A免密登陆B,需要把A生成的公钥放...

  • linux ssh 免密登陆排查技巧

    场景: 使用ssh免密登陆配置的时候。做了相关配置之后,尝试ssh免密登陆,还是提示输入密码,无法免密登陆。也没有...

  • SSH 免密登陆

    SSH 免密登陆 本地机器 回车回车 这里要注意权限的问题,如果权限不对可能会导致无法免密登陆。

  • mac免密登陆ssh服务器

    1. git clone 2. ssh免密登陆

  • linux 实现 ssh 免密登陆

    假设要实现在机器 A 上 ssh 到机器 B 不再输入密码,可以在机器 A 上进行如下操作 检查~/.ssh/ ...

  • Shell一键发布程序

    为实现一键发布,最好是可以免密码登陆服务器,通过创建RSA密钥对,将公钥写入目标服务器来实现免密登陆,参考这里。 ...

  • 免密登陆

    ssh-keygen -t rsa ssh-copy-id -i ~/.ssh/id_rsa.pub supers...

  • Zookeeper 集群部署

    0.集群环境 三台机器linux机器,并且相互免密登陆,安装好了java关于如何免密可以参考:https://ww...

  • Linux 设置免密登陆(Mac)

    设置ssh 免密登陆 前置条件: 安装ssh-copy-idbrew install ssh-copy-id 登陆...

网友评论

      本文标题:Shiro实现免密登陆

      本文链接:https://www.haomeiwen.com/subject/vkmeactx.html