Shiro识别多种用户进行登录

简介: Shiro识别多种用户进行登录

前言


Shiro是我们经常用的一个用户权限的工具。在我们工作中,我们有可能刚刚编辑好了一个系统,但是新的需求又出来了。假定有这么一种情况,我们系统的原来的用户表需要用,但是呢,我们不想改变原来的用户表结构,这就会催使我们建立一个新的用户表,这个时候我们怎么办呢?本节内容就是说的这件事。


这么实现的前提条件是,我们需要升级系统,但是,我们不想改变原来的系统的结构,这就催使我们增加新的额数据库表。很有可能增加的是我们的用户表,这个时候,我们如何有效的管理我们的用户的登陆呢,所以今天讲述的是Shiro的多用户的登陆操作。


我们实现的主要思路是,我们要改变重写UsernamePasswordToken,加上所属的功能,来判断是原来的用户登陆还是,我们新增加的用户登陆。之后我们要改变用户的认证逻辑,具体的实现方法如下。



正文


重写UsernamePasswordToken


重写这个类,实质上是我们的Java代码继承这个类,来实现我们的想要的功能。


/**
 * 自己定义token
 *
 * @date : 2018/01/02
 */
@Getter
public class LocalUsernamePasswordToken extends UsernamePasswordToken {
    /**
     * 远端的IP
     */
    private String remoteIp;
    private String function;
    private UserCategoryEnum belongUser;
    public LocalUsernamePasswordToken(String username, String password, String remoteIp, UserCategoryEnum belongUser) {
        super(username, password);
        this.remoteIp = remoteIp;
        this.belongUser = belongUser;
    }
    public LocalUsernamePasswordToken(String username, String password, String remoteIp, String function, UserCategoryEnum belongUser) {
        super(username, password);
        this.remoteIp = remoteIp;
        this.function = function;
        this.belongUser = belongUser;
    }
}


重构登陆的实现代码


@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    /**
     * 判断是否为自己重新写的
     */
    if (token instanceof LocalUsernamePasswordToken) {
        LocalUsernamePasswordToken usernamePasswordToken = (LocalUsernamePasswordToken) token;
        if (UserCategoryEnum.SYSTEM.getUserCategoryMessage().equals(usernamePasswordToken.getBelongUser().getUserCategoryMessage())) {
            /**
             * 系统用户
             */
            String username = usernamePasswordToken.getUsername();
            UserService userService = SpringUtil.getBean(UserService.class);
            User user = userService.getUser(username);
            if (user == null) {
                throw new UnknownAccountException("用户名不存在");
            }
            if (!user.getPassword()
                    .equals(userService.passwordEncoder(new String(usernamePasswordToken.getPassword()), user.getSalt()))) {
                throw new IncorrectCredentialsException("密码错误");
            }
            if (user.getStatus() != User.Status.VALID) {
                throw new IncorrectCredentialsException("无效状态,请联系管理员");
            }
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, new String(usernamePasswordToken.getPassword()),
                    getName());
            UserUtil.setUserSession(user);
            return authenticationInfo;
        } else {
            /**
             * 企业用户平台用户
             */
            String username = usernamePasswordToken.getUsername();
            if (null == username || "".equals(username)) {
                log.error("您填写的用户名为空!");
                throw new UnknownAccountException("您填写的用户名为空!");
            }
            if (!username.matches(PHONE_REGEX)) {
                log.error("您填写的手机号格式不对!");
                throw new UnknownAccountException("您填写的手机号格式不对!");
            }
            List<FinanceUserEntity> financeUserEntityByPhoneNumber = financeUserService.getFinanceUserEntityByPhoneNumber(username);
            FinanceUserEntity financeUserEntity = null;
            if (null != financeUserEntityByPhoneNumber && financeUserEntityByPhoneNumber.size() > 0) {
                financeUserEntity = financeUserEntityByPhoneNumber.get(0);
                String clientSalt = financeUserEntity.getClientSalt();
                String password = new String(usernamePasswordToken.getPassword());
                String passwordMd5 = LocalGeneratePasswordUtil.generatePasswordByPassSalt(password, clientSalt);
                if (!financeUserEntity.getClientPassword().equals(passwordMd5)) {
                    throw new IncorrectCredentialsException("密码错误");
                }
                Date nowTime = new Date();
                financeUserEntity.setLastLoginDate(nowTime);
                financeUserEntity.setLastLoginIp(usernamePasswordToken.getRemoteIp());
                Integer loginCount = financeUserEntity.getLoginCount();
                if (null == loginCount) {
                    /**
                     * 第一次登录
                     */
                    loginCount = 1;
                } else {
                    loginCount++;
                }
                financeUserEntity.setLoginCount(loginCount);
                financeUserEntity.setGmtModified(nowTime);
                financeUserService.updateFinanceUserByPhoneNumber(financeUserEntity);
            } else {
                throw new UnknownAccountException("用户名不存在");
            }
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(financeUserEntity, new String(usernamePasswordToken.getPassword()), getName());
            UserUtil.setFinanceUserSession(financeUserEntity);
            return authenticationInfo;
        }
    } else {
        throw new UnknownAccountException("联系管理员  不是LocalUsernamePasswordToken的对象");
    }
}


我们看到,我们用了一个判断来实现不同的对象,这样我们就实现了Shiro多种用户登陆。

相关文章
|
1月前
|
移动开发 Linux Apache
apache 用户登录认证
在Redhat 9系统中,已安装Apache服务。遵循教程,首先创建用户&quot;DL&quot;并设置密码,然后创建用户目录/home/DL/public_html,存放index.html。启用Apache的userdir模块,取消UserDir disabled的注释,并重启服务。通过htpasswd创建用户认证文件,编辑userdir.conf添加权限设置,包括AllowOverride、authuserfile、authname、authtype和require user。最后,通过浏览器访问ip/~DL/进行测试,实现用户登录验证。
22 4
|
1月前
|
SQL 安全 前端开发
Security登录认证流程分析
Security登录认证流程分析
44 5
|
8月前
|
存储 Java 测试技术
03 Shrio身份认证示例
03 Shrio身份认证示例
27 0
|
存储 缓存 安全
2021年你还不会Shiro?----2.Shiro实现登录功能(身份认证实践)
上一篇介绍了Shiro的架构,我们可以发现Shiro核心的东西并不多,我们花个几分钟就可以把Shiro的机构记清楚,其中Security Manager就是Shiro的核心,他包含了身份认证器Authenticator、授权器Authorizer、Session管理Session Manager、缓存管理Cache Manager。这一篇我们就介绍下Shiro的身份认证的过程,也就是我们说的用户登录。
116 0
2021年你还不会Shiro?----2.Shiro实现登录功能(身份认证实践)
|
JSON 安全 前端开发
如何认证当前的操作用户?
如何认证当前的操作用户?
|
Java 数据安全/隐私保护 容器
【JavaWeb】案例:用户登录、用户自动登录
本期主要介绍案例:用户登录、用户自动登录
251 0
【JavaWeb】案例:用户登录、用户自动登录
|
安全 Java 数据库连接
【Shiro】1、Shiro实现登录授权认证功能(上)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
281 0
|
Java 数据安全/隐私保护
【Shiro】1、Shiro实现登录授权认证功能(中)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
115 0
|
Java 数据安全/隐私保护
【Shiro】1、Shiro实现登录授权认证功能(下)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
109 0
|
数据库 数据安全/隐私保护
【Shiro】3、Shiro实现自定义密码验证规则
我们在使用 Shiro 实现登录的时候,我们只需要将账号、密码,Shiro 会自动判断账户、密码是否正确,那么 Shiro 怎么会知道我们的密码加密规则呢?所以我们需要自定义密码的加密规则
181 0