开发喵星球

若依如何实现用户免密登录配置方法(七十九)

免密使用的场景,例如短信验证码,第三方应用登录等。

下面列出一个简单的实现方法,当然还有更多实现方式可以自己尝试。

1、新建一个登录类型枚举类

package com.ruoyi.framework.shiro.token;

/**
 * 登录类型枚举类
 * 
 */
public enum LoginType
{
    /**
     * 密码登录
     */
    PASSWORD("password"),
    /**
     * 免密码登录
     */
    NOPASSWD("nopasswd");

    private String desc;

    LoginType(String desc)
    {
        this.desc = desc;
    }

    public String getDesc()
    {
        return desc;
    }
}

2、自定义登录Token

package com.ruoyi.framework.shiro.token;

import org.apache.shiro.authc.UsernamePasswordToken;

/**
 * 自定义登录Token
 * 
 */
public class UserToken extends UsernamePasswordToken
{
    private static final long serialVersionUID = 1L;

    private LoginType type;

    public UserToken()
    {
    }

    public UserToken(String username, String password, LoginType type, boolean rememberMe)
    {
        super(username, password, rememberMe);
        this.type = type;
    }

    public UserToken(String username, LoginType type)
    {
        super(username, "", false, null);
        this.type = type;
    }

    public UserToken(String username, String password, LoginType type)
    {
        super(username, password, false, null);
        this.type = type;
    }

    public LoginType getType()
    {
        return type;
    }

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

3、对应Realm中添加登录类型判断,例如UserRealm(这里演示公用一个realm,如单独有免密realm不需要)

/**
 * 登录认证
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
{
    UserToken upToken = (UserToken) token;
    LoginType type = upToken.getType();
    String username = upToken.getUsername();
    String password = "";
    if (upToken.getPassword() != null)
    {
        password = new String(upToken.getPassword());
    }

    User user = null;
    try
    {
        if (LoginType.PASSWORD.equals(type))
        {
            user = loginService.login(username, password);
        }
        else if (LoginType.NOPASSWD.equals(type))
        {
            user = loginService.login(username);
        }
    }
    catch (CaptchaException e)
    {
        throw new AuthenticationException(e.getMessage(), e);
    }
    catch (UserNotExistsException e)
    {
        throw new UnknownAccountException(e.getMessage(), e);
    }
    catch (UserPasswordNotMatchException e)
    {
        throw new IncorrectCredentialsException(e.getMessage(), e);
    }
    catch (UserPasswordRetryLimitExceedException e)
    {
        throw new ExcessiveAttemptsException(e.getMessage(), e);
    }
    catch (UserBlockedException e)
    {
        throw new LockedAccountException(e.getMessage(), e);
    }
    catch (RoleBlockedException e)
    {
        throw new LockedAccountException(e.getMessage(), e);
    }
    catch (Exception e)
    {
        log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
        throw new AuthenticationException(e.getMessage(), e);
    }
    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
    return info;
}

4、LoginService添加login方法,去掉密码验证。

/**
 * 登录
 */
public User login(String username)
{
    // 验证码校验
    if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
    {
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
        throw new CaptchaException();
    }
    // 用户名或密码为空 错误
    if (StringUtils.isEmpty(username))
    {
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
        throw new UserNotExistsException();
    }

    // 用户名不在指定范围内 错误
    if (username.length() < UserConstants.USERNAME_MIN_LENGTH
            || username.length() > UserConstants.USERNAME_MAX_LENGTH)
    {
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
        throw new UserPasswordNotMatchException();
    }

    // 查询用户信息
    User user = userService.selectUserByLoginName(username);

    if (user == null)
    {
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
        throw new UserNotExistsException();
    }

    if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
    {
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
        throw new UserDeleteException();
    }

    if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
    {
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
        throw new UserBlockedException();
    }

    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
    recordLoginInfo(user);
    return user;
}

5、在对应的登录方法中传入LoginType.NOPASSWD调用

UserToken token = new UserToken(username, LoginType.NOPASSWD);
Subject subject = SecurityUtils.getSubject();
subject.login(token);
   
分类:Java/OOP 作者:无限繁荣, 吴蓉 发表于:2023-12-22 12:02:51 阅读量:175
<<   >>


powered by kaifamiao