千家信息网

怎么用Java整合Shiro实现用户登录认证功能

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要讲解了"怎么用Java整合Shiro实现用户登录认证功能",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用Java整合Shiro实现用户
千家信息网最后更新 2026年11月02日怎么用Java整合Shiro实现用户登录认证功能

这篇文章主要讲解了"怎么用Java整合Shiro实现用户登录认证功能",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用Java整合Shiro实现用户登录认证功能"吧!

内容:

对于Shiro,相信各位小伙伴应该听说过,甚至应该也使用过!简单而言,它是一个很好用的用户身份认证、权限授权框架,可以实现用户登录认证,权限、资源授权、会话管理等功能,在本秒杀系统中,我们将主要采用该框架实现对用户身份的认证和用户的登录功能。

值得一提的是,本篇博文介绍的"Shiro实现用户登录认证"功能模块涉及到的数据库表为用户信息表user,下面进入代码实战环节。

    org.apache.shiro    shiro-ehcache    ${shiro.version}     org.apache.shiro    shiro-core    ${shiro.version}     org.apache.shiro    shiro-web    ${shiro.version}     org.apache.shiro    shiro-spring    ${shiro.version}

(2)紧接着是在UserController控制器中开发用户前往登录、用户登录以及用户退出登录的请求对应的功能方法,其完整的源代码如下所示:

@Autowiredprivate Environment env; //跳到登录页@RequestMapping(value = {"/to/login","/unauth"})public String toLogin(){    return "login";} //登录认证@RequestMapping(value = "/login",method = RequestMethod.POST)public String login(@RequestParam String userName, @RequestParam String password, ModelMap modelMap){    String errorMsg="";    try {        if (!SecurityUtils.getSubject().isAuthenticated()){            String newPsd=new Md5Hash(password,env.getProperty("shiro.encrypt.password.salt")).toString();            UsernamePasswordToken token=new UsernamePasswordToken(userName,newPsd);            SecurityUtils.getSubject().login(token);        }    }catch (UnknownAccountException e){        errorMsg=e.getMessage();        modelMap.addAttribute("userName",userName);    }catch (DisabledAccountException e){        errorMsg=e.getMessage();        modelMap.addAttribute("userName",userName);    }catch (IncorrectCredentialsException e){        errorMsg=e.getMessage();        modelMap.addAttribute("userName",userName);    }catch (Exception e){        errorMsg="用户登录异常,请联系管理员!";        e.printStackTrace();    }    if (StringUtils.isBlank(errorMsg)){        return "redirect:/index";    }else{        modelMap.addAttribute("errorMsg",errorMsg);        return "login";    }} //退出登录@RequestMapping(value = "/logout")public String logout(){    SecurityUtils.getSubject().logout();    return "login";}

其中,在匹配用户的密码时,我们在这里采用的Md5Hash的方法,即MD5加密的方式进行匹配(因为数据库的user表中用户的密码字段存储的正是采用MD5加密后的加密串)

前端页面login.jsp的内容比较简单,只需要用户输入最基本的用户名和密码即可,如下图所示为该页面的部分核心源代码:

当前端提交"用户登录"请求时,将以"提交表单"的形式将用户名、密码提交到后端UserController控制器对应的登录方法中,该方法首先会进行最基本的参数判断与校验,校验通过之后,会调用Shiro内置的组件SecurityUtils.getSubject().login()方法执行登录操作,其中的登录操作将主要在 "自定义的Realm的doGetAuthenticationInfo方法"中执行。

(3)接下来是基于Shiro的AuthorizingRealm,开发自定义的Realm,并实现其中的用户登录认证方法,即doGetAuthenticationInfo()方法。其完整的源代码如下所示:

/** * 用户自定义的realm-用于shiro的认证、授权 * @Author:debug (SteadyJack) * @Date: 2019/7/2 17:55 **/public class CustomRealm extends AuthorizingRealm{    private static final Logger log= LoggerFactory.getLogger(CustomRealm.class);     private static final Long sessionKeyTimeOut=3600_000L;    @Autowired    private UserMapper userMapper;     //授权    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        return null;    }     //认证-登录    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;        String userName=token.getUsername();        String password=String.valueOf(token.getPassword());        log.info("当前登录的用户名={} 密码={} ",userName,password);         User user=userMapper.selectByUserName(userName);        if (user==null){            throw new UnknownAccountException("用户名不存在!");        }        if (!Objects.equals(1,user.getIsActive().intValue())){            throw new DisabledAccountException("当前用户已被禁用!");        }        if (!user.getPassword().equals(password)){            throw new IncorrectCredentialsException("用户名密码不匹配!");        }         SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user.getUserName(),password,getName());        setSession("uid",user.getId());        return info;    }     /**     * 将key与对应的value塞入shiro的session中-最终交给HttpSession进行管理(如果是分布式session配置,那么就是交给redis管理)     * @param key     * @param value     */    private void setSession(String key,Object value){        Session session=SecurityUtils.getSubject().getSession();        if (session!=null){            session.setAttribute(key,value);            session.setTimeout(sessionKeyTimeOut);        }    }}

其中,userMapper.selectByUserName(userName);主要用于根据userName查询用户实体信息,其对应的动态Sql的写法如下所示:

值得一提的是,当用户登录成功时(即用户名和密码的取值跟数据库的user表相匹配),我们会借助Shiro的Session会话机制将当前用户的信息存储至服务器会话中,并缓存一定时间!(在这里是3600s,即1个小时)!

(4)最后是我们需要实现"用户在访问待秒杀商品详情或者抢购商品或者任何需要进行拦截的业务请求时,如何自动检测用户是否处于登录的状态?如果已经登录,则直接进入业务请求对应的方法逻辑,否则,需要前往用户登录页要求用户进行登录"。

基于这样的需求,我们需要借助Shiro的组件ShiroFilterFactoryBean 实现"用户是否登录"的判断,以及借助FilterChainDefinitionMap拦截一些需要授权的链接URL,其完整的源代码如下所示:

/** * shiro的通用化配置 * @Author:debug (SteadyJack) * @Date: 2019/7/2 17:54 **/@Configurationpublic class ShiroConfig {     @Bean    public CustomRealm customRealm(){        return new CustomRealm();    }     @Bean    public SecurityManager securityManager(){        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();        securityManager.setRealm(customRealm());        securityManager.setRememberMeManager(null);        return securityManager;    }     @Bean    public ShiroFilterFactoryBean shiroFilterFactoryBean(){        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();        bean.setSecurityManager(securityManager());        bean.setLoginUrl("/to/login");        bean.setUnauthorizedUrl("/unauth");           //对于一些授权的链接URL进行拦截        Map filterChainDefinitionMap=new HashMap<>();        filterChainDefinitionMap.put("/to/login","anon");        filterChainDefinitionMap.put("/**","anon");         filterChainDefinitionMap.put("/kill/execute","authc");        filterChainDefinitionMap.put("/item/detail/*","authc");         bean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return bean;    } }

从上述该源代码中可以看出,Shiro的ShiroFilterFactoryBean组件将会对 URL=/kill/execute 和 URL=/item/detail/* 的链接进行拦截,即当用户访问这些URL时,系统会要求当前的用户进行登录(前提是用户还没登录的情况下!如果已经登录,则直接略过,进入实际的业务模块!)

除此之外,Shiro的ShiroFilterFactoryBean组件还设定了 "前往登录页"和"用户没授权/没登录的前提下的调整页"的链接,分别是 /to/login 和 /unauth!

(5)至此,整合Shiro框架实现用户的登录认证的前后端代码实战已经完毕了,将项目/系统运行在外置的tomcat服务器中,打开浏览器即可访问进入"待秒杀商品的列表页",点击"详情",此时,由于用户还没登陆,故而将跳转至用户登录页,如下图所示:

输入用户名:debug,密码:123456,点击"登录"按钮,即可登录成功,并成功进入"详情页",如下图所示:

登录成功之后,再回到刚刚上一个列表页,即"待秒杀商品的列表页",再次点击"详情"按钮,此时会直接进入"待秒杀商品的详情页",而不会跳转至"用户登录页",而且用户的登录态将会持续1个小时!(这是借助Shiro的Session的来实现的)。

感谢各位的阅读,以上就是"怎么用Java整合Shiro实现用户登录认证功能"的内容了,经过本文的学习后,相信大家对怎么用Java整合Shiro实现用户登录认证功能这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

用户 登录 认证 方法 功能 密码 用户名 整合 商品 源代码 详情 成功 内容 组件 链接 管理 业务 信息 数据 数据库 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司官网 腾讯科技 互联网女皇 沃里互联网科技 掌上梦互联网科技 互联网科技创新企业排名 互联网科技中介 常德市电业局互联网科技部 重庆威客帮互联网科技 互联网科技与管理 广州市恰铎互联网科技有限公司 青海科技产业互联网发展 中国科技创新与世界互联网大会 深圳市罗太互联网科技有限公司 2021互联网科技公司排名 领航科技大厦互联网公司 广州有谷有贝互联网科技有限公司 互联网科技和医药行业 安徽零酒互联网科技有限公司 深圳互联网科技园地址 互联网企业和网络科技有限公司 万易互联网科技有限公司 广州善班互联网科技 海南购全球互联网科技 恒生科技互联网指数分析 世界互联网科技公司市值排名 用友工业互联网科技发展 工业互联网山东科技大学 上海京穆互联网科技有限公司 元气玛特互联网科技公司是外包吗 上海互联网科技公司ppt
0