SpringBoot+Shiro实现免密登录

1、自定义登录认证规则

import org.apache.shiro.authc.UsernamePasswordToken;

public class EasyUsernameToken extends UsernamePasswordToken {
    private static final long serialVersionUID = -2564928913725078138L;
    private ShiroApproveLoginType type;
    public EasyUsernameToken() {
        super();
    }

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

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

    public ShiroApproveLoginType getType() {
        return type;
    }

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

枚举类 

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

    public String getCode() {
        return code;
    }
}

 

2、自定义登录认证方案

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

/**
 * 自定义登录认证方案
 * 1.免密登录,不加密
 * 2.密码登录,SHA256加密
 *
 */
public class EasyCredentialsMatch extends HashedCredentialsMatcher {
    /**
     * 重写方法
     * 区分 密码和非密码登录
     * 此次无需记录登录次数 详情看SysPasswordService
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        EasyUsernameToken easyUsernameToken = (EasyUsernameToken) token;

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

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

}

3、shiro配置类设置加密规则

/**
     * 凭证匹配器
     * 将密码校验交给Shiro的SimpleAuthenticationInfo进行处理,在这里做匹配配置
     *
     * @Author
     * @CreateTime 2021/5/06 8:42
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
//        HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
        EasyCredentialsMatch shaCredentialsMatcher = new EasyCredentialsMatch();
        // 散列算法:这里使用SHA256算法;
        shaCredentialsMatcher.setHashAlgorithmName(SHA256Util.HASH_ALGORITHM_NAME);
        // 散列的次数,比如散列两次,相当于 md5(md5(""));
        shaCredentialsMatcher.setHashIterations(SHA256Util.HASH_ITERATIONS);
        return shaCredentialsMatcher;
    }

4、登录认证

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;

/**
 * @Description Shiro权限匹配和账号密码匹配
 */
public class ShiroRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;
    /**
     * 身份认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        EasyUsernameToken easyUsernameToken = (EasyUsernameToken) authenticationToken;
        //获取用户的输入的账号.
        String username = (String) authenticationToken.getPrincipal();
        //通过username从数据库中查找 User对象,如果找到进行验证
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        SysUserEntity user = userService.getUserByName(username);
        //判断账号是否存在
        if (user == null) {
            throw new AuthenticationException();
        }
        //判断账号是否被冻结
        if (user.getState() == null || user.getState().equals("PROHIBIT")) {
            throw new LockedAccountException();
        }
        SimpleAuthenticationInfo authenticationInfo;
        if(easyUsernameToken.getType().equals(ShiroApproveLoginType.PASSWORD)){
            //进行用户名密码验证
            authenticationInfo = new SimpleAuthenticationInfo(
                    user,                                  //用户名
                    user.getPassword(),                    //密码
                    ByteSource.Util.bytes(user.getSalt()), //设置盐值
                    getName()
            );
        }else{
            //免密验证
            authenticationInfo = new SimpleAuthenticationInfo(
                    user,                                  //用户名
                    "",                    //密码
                    getName()
            );
        }
        return authenticationInfo;
    }
}

5、登录方法

public Result login(@RequestBody Map<String,Object> userMap) {
        Map<String, Object> map = new HashMap<>();
        //进行身份验证
        String name = userMap.get("name").toString();
        try {
            //验证身份和登陆
            Subject subject = SecurityUtils.getSubject();
            EasyUsernameToken token = new EasyUsernameToken(name);
            //进行登录操作
            subject.login(token);
            return ResultUtil.success();
        } catch (IncorrectCredentialsException e) {
            return ResultUtil.error(500,"用户不存在或者密码错误");
        } catch (LockedAccountException e) {
            return ResultUtil.error(500,"登录失败,该用户已被冻结");
        } catch (AuthenticationException e) {
            return ResultUtil.error(500,"该用户不存在");
        } 
    }

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot是一个用于快速开发Java应用程序的开源框架,Shiro是一个强大且易于使用的Java安全框架,Redis是一个开源的内存数据库。结合使用这些技术可以实现单点登录功能。 在Spring Boot中使用Shiro来处理认证和授权,可以通过配置Shiro的Realm来实现用户的登录认证和权限控制。将用户的信息存储在Redis中,利用Redis的持久化特性来实现用户登录状态的共享和存储。 首先,在Spring Boot项目的配置文件中配置Redis的连接信息,以便连接到Redis数据库。 然后,创建一个自定义的Shiro的Realm,在其中重写认证和授权的方法。在认证方法中,将用户的登录信息存储到Redis中,以便其他服务可以进行验证。在授权方法中,根据用户的角色和权限进行相应的授权操作。 接着,在Spring Boot项目的配置类中配置Shiro的相关设置,包括Realm、Session管理器、Cookie管理器等。 最后,可以在Controller层中使用Shiro的注解来标记需要进行认证和授权的接口,以确保只有登录后且具备相应权限的用户才能访问这些接口。 总的来说,通过使用Spring BootShiro和Redis的组合,可以实现单点登录的功能。用户在登录后,将登录信息存储到Redis中,其他服务可以通过验证Redis中的数据来判断用户的登录状态。同时,Shiro提供了强大的认证和授权功能,可以确保只有具备相应权限的用户才能访问受保护的接口。这些功能的具体实现可以通过深入研究Spring BootShiro和Redis的源码来了解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值