广告
返回顶部
首页 > 资讯 > 精选 >如何在SpringBoot中使用Shiro怎么实现一个邮件验证码登录功能
  • 486
分享到

如何在SpringBoot中使用Shiro怎么实现一个邮件验证码登录功能

2023-06-06 13:06:44 486人浏览 薄情痞子
摘要

如何在SpringBoot中使用shiro怎么实现一个邮件验证码登录功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。导入依赖(pom.xml)  &

如何在SpringBoot中使用shiro怎么实现一个邮件验证码登录功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

导入依赖(pom.xml)

 <!--整合Shiro安全框架-->  <dependency>   <groupId>org.apache.shiro</groupId>   <artifactId>shiro-spring</artifactId>   <version>1.4.0</version>  </dependency>  <!--集成Jwt实现token认证-->  <dependency>   <groupId>com.auth0</groupId>   <artifactId>java-jwt</artifactId>   <version>3.2.0</version>  </dependency>

在 SpringBoot 项目配置 config 包下创建 ShiroConfig 配置类

@Configurationpublic class ShiroConfig {  @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWEBSecurityManager defaultWebSecurityManager) {  ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();  // 设置安全管理器  factoryBean.setSecurityManager(defaultWebSecurityManager);  // 添加shiro的内置过滤器  Map<String, String> filterMap = new LinkedHashMap<>();  // 放行不需要权限认证的接口  // 网站首页  filterMap.put("/", "anon");  filterMap.put("/index", "anon");  filterMap.put("/index.html", "anon");  // 不验证跳转接口  filterMap.put("/into @Bean("lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {  return new LifecycleBeanPostProcessor(); }  @Bean @DependsOn("lifecycleBeanPostProcessor") public UserPassWordRealm userPasswordRealm() {  return new UserPasswordRealm(); }  @Bean @DependsOn("lifecycleBeanPostProcessor") public UserEmailRealm userEmailRealm() {  return new UserEmailRealm(); }  @Bean public DefaultWebSecurityManager securityManager(UserPasswordRealm userPasswordRealm, UserEmailRealm userEmailRealm, AbstractAuthenticator abstractAuthenticator) {  DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();  List<Realm> realms = new ArrayList<>();  realms.add(userPasswordRealm);  realms.add(userEmailRealm);  defaultWebSecurityManager.setRealms(realms);  // 记住我  defaultWebSecurityManager.setRememberMeManager(cookieRememberMeManager());  defaultWebSecurityManager.setAuthenticator(abstractAuthenticator);  return defaultWebSecurityManager; }  @Bean public AbstractAuthenticator abstractAuthenticator(UserPasswordRealm userPasswordRealm, UserEmailRealm userEmailRealm) {  // 自定义模块化认证器,用于解决多realm抛出异常问题  //开始没用自定义异常问题,发现不管是账号密码错误还是什么错误  //shiro只会抛出一个AuthenticationException异常  ModularRealmAuthenticator authenticator = new MyCustomModularRealmAuthenticator();  // 认证策略:AtLeastOneSuccessfulStrategy(默认),AllSuccessfulStrategy,FirstSuccessfulStrategy  authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());  // 加入realms  List<Realm> realms = new ArrayList<>();  realms.add(userPasswordRealm);  realms.add(userEmailRealm);  authenticator.setRealms(realms);  return authenticator; }  @Bean @DependsOn({"lifecycleBeanPostProcessor"}) public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {  DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();  advisorAutoProxyCreator.setProxyTargetClass(true);  return advisorAutoProxyCreator; }  @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {  AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();  authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);  return authorizationAttributeSourceAdvisor; }  @Bean public CookieRememberMeManager cookieRememberMeManager() {  CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();  cookieRememberMeManager.setCookie(rememberMeCookie());  return cookieRememberMeManager; }  @Bean public SimpleCookie rememberMeCookie() {    SimpleCookie simpleCookie = new SimpleCookie("rememberMe");    simpleCookie.setMaxAge(259200);  return simpleCookie; }}

创建自定义验证器 MyCustomModularRealmAuthenticator 类

public class MyCustomModularRealmAuthenticator extends ModularRealmAuthenticator { @Override protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {  AuthenticationStrategy authenticationStrategy = this.getAuthenticationStrategy();  AuthenticationInfo authenticationInfo = authenticationStrategy.beforeAllAttempts(realms, token);  Iterator var5 = realms.iterator();  while (var5.hasNext()) {   Realm realm = (Realm) var5.next();   authenticationInfo = authenticationStrategy.beforeAttempt(realm, token, authenticationInfo);   if (realm.supports(token)) {    AuthenticationInfo info = null;    Throwable t = null;    info = realm.getAuthenticationInfo(token);    authenticationInfo = authenticationStrategy.afterAttempt(realm, token, info, authenticationInfo, t);   }  }  authenticationInfo = authenticationStrategy.afterAllAttempts(token, authenticationInfo);  return authenticationInfo; }}

创建密码登录时验证授权 UserPasswordRealm 类

@Componentpublic class UserPasswordRealm extends AuthorizingRealm { // 注入用户业务 @Autowired private UserMapper userMapper;  @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  System.out.println("————密码授权————doGetAuthorizationInfo————");  return null; }  @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  System.out.println("————密码认证————doGetAuthenticationInfo————");  UsernamePasswordToken userToken = (UsernamePasswordToken) token;  // 连接数据库 查询用户数据  QueryWrapper<User> wrapper = new QueryWrapper<>();  wrapper.eq("user_name", userToken.getUsername());  User user = userMapper.selectOne(wrapper);  // 验证用户  if (user == null) {   throw new UnknownAccountException();  }  return new SimpleAuthenticationInfo("", user.getUserPassword(), ""); }  @Override public boolean supports(AuthenticationToken var1) {  return var1 instanceof UsernamePasswordToken; }}

创建邮件验证码登录时验证授权UserEmailRealm

@Componentpublic class UserEmailRealm extends AuthorizingRealm { // 注入用户业务 @Autowired UserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {  System.out.println("————邮箱登录授权————doGetAuthorizationInfo————");  return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  System.out.println("————邮箱登录认证————doGetAuthenticationInfo————");  UserEmailToken userEmailToken = (UserEmailToken) token;  String userEmail = (String) userEmailToken.getPrincipal();  // 连接数据库 查询用户数据  QueryWrapper<User> wrapper = new QueryWrapper<>();  wrapper.eq("user_email", userEmail);  User user = userService.getOne(wrapper);  //因为没有密码,并且验证码在之前就验证了  if (user == null) {   throw new UnknownAccountException();  }  return new SimpleAuthenticationInfo("", userEmail, ""); }  @Override public boolean supports(AuthenticationToken var1) {  return var1 instanceof UserEmailToken; }}

创建邮件验证码登录验证通过生成令牌的 UserEmailToken 类(密码登录时使用shiro默认的 UsernamePasswordToken 令牌)

@Data // 使用lombok 生成get方法、set方法public class UserEmailToken implements HostAuthenticationToken, RememberMeAuthenticationToken { private String userEmail; private boolean rememberMe; private String host; public UserEmailToken() {  this.rememberMe = false; } public UserEmailToken(String userEmail) {  this(userEmail, false, null); } public UserEmailToken(String userEmail, boolean rememberMe) {  this(userEmail, rememberMe, null); } public UserEmailToken(String userEmail, boolean rememberMe, String host) {  this.userEmail = userEmail;  this.rememberMe = rememberMe;  this.host = host; } @Override public String getHost() {  return host; } @Override public boolean isRememberMe() {  return rememberMe; }  @Override public Object getPrincipal() {  return userEmail; }  @Override public Object getCredentials() {  return userEmail; }}

创建密码盐值加密 MDPasswordUtil 工具

public class MDPasswordUtil { public String getMDPasswordUtil(String userName, String userPassword) {  String hashAlGorithmName = "MD5"; // 加密方式:md5加密  Object credentials = userPassword; // 密码  Object salt = ByteSource.Util.bytes(userName); // 盐  int hashIterations = 512; // 加密次数  Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);  return result.toString(); }}

控制层用户密码登录

// 用户密码登录 @PostMapping("/passwordLogin") public String userLogin(@RequestParam("userName") String userName,       @RequestParam("userPassword") String userPassword,       httpsession session, Model model) {  // 获取当前的用户  Subject subject = SecurityUtils.getSubject();  // 对密码进行MD5盐值加密  String md5Password = new MDPasswordUtil().getMDPasswordUtil(userName, userPassword);  // 封装用户的登录数据  UsernamePasswordToken token = new UsernamePasswordToken(userName, md5Password);  //rememberme记住我  token.setRememberMe(true);  try {   // 登录,验证,保存令牌   subject.login(token);   //查询登录信息   QueryWrapper<User> wrapper = new QueryWrapper<>();   wrapper.eq("user_name", userName);   User user = userService.getOne(wrapper);   //保存登录用户信息   session.setAttribute(user.getUserId().toString(), user);   return "admin";  } catch (UnknownAccountException e) {   model.addAttribute("userError", "用户名错误!请重新输入。");   return "login";  } catch (IncorrectCredentialsException ice) {   model.addAttribute("pwError", "密码错误!请重新输入。");   return "login";  } }

控制层用户邮件验证码密码登录

// 用户邮箱登录 @PostMapping("/emailLogin") public String emailLogin(@RequestParam("userEmail") String userEmail,        @RequestParam("emailCode") String emailCode,        HttpSession session, Model model) {  // 根据userEmail从session中取出发送的验证码  String sendEmailCode = (String) session.getAttribute(userEmail);  // 比对验证码  if (StringUtils.isNoneBlank(sendEmailCode) && sendEmailCode.equals(emailCode)) {   try {    UserEmailToken token = new UserEmailToken(userEmail);    //rememberme记住我    token.setRememberMe(true);    // 登录,验证,保存令牌    Subject subject = SecurityUtils.getSubject();    subject.login(token);    //查询登录信息    QueryWrapper<User> wrapper = new QueryWrapper<>();    wrapper.eq("user_email", userEmail);    User user = userService.getOne(wrapper);    //保存登录用户信息    session.setAttribute(user.getUserId().toString(), user);    // 销毁验证码    session.removeAttribute(emailCode);    return "admin";   } catch (Exception e) {    model.addAttribute("error", "验证码错误!请重新输入。");    return "login";   }  } else {   return "login";  } }

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网精选频道,感谢您对编程网的支持。

--结束END--

本文标题: 如何在SpringBoot中使用Shiro怎么实现一个邮件验证码登录功能

本文链接: https://www.lsjlt.com/news/247299.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何在SpringBoot中使用Shiro怎么实现一个邮件验证码登录功能
    如何在SpringBoot中使用Shiro怎么实现一个邮件验证码登录功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。导入依赖(pom.xml)  &...
    99+
    2023-06-06
  • 怎么在SpringBoot中利用Shiro实现一个密码登录功能
    怎么在SpringBoot中利用Shiro实现一个密码登录功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。导入依赖(pom.xml) <!--...
    99+
    2023-06-06
  • springboot中怎么利用shiro实现多验证登录功能
    springboot中怎么利用shiro实现多验证登录功能,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 首先新建一个shiroConfig shiro的配置类...
    99+
    2023-06-20
  • springboot整合shiro多验证登录功能的实现(账号密码登录和使用手机验证码登录)
    1. 首先新建一个shiroConfig shiro的配置类,代码如下: @Configuration public class SpringShiroConfig { ...
    99+
    2022-11-12
  • 使用golang怎么实现一个登录验证码功能
    这篇文章将为大家详细讲解有关使用golang怎么实现一个登录验证码功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。golang适合做什么golang可以做服务器端开发,但golang很适合...
    99+
    2023-06-06
  • 怎么在java中使用JDBC实现一个验证登录功能
    怎么在java中使用JDBC实现一个验证登录功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整...
    99+
    2023-06-14
  • Java web如何实现一个验证码权限登录功能
    今天就跟大家聊聊有关Java web如何实现一个验证码权限登录功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。所用到的开发工具为myeclipse10,MySQL数据库。首先,在m...
    99+
    2023-05-31
    javaweb 验证码 ava
  • 使用Struts2拦截器如何实现一个登录验证功能
    使用Struts2拦截器如何实现一个登录验证功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Struts2拦截器Struts2拦截器的概念和Spring Mvc拦截器一样...
    99+
    2023-05-31
    struts 登录验证 拦截器
  • 使用ajax怎么实现一个验证码功能
    本篇文章给大家分享的是有关使用ajax怎么实现一个验证码功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。首先创建一个验证码:<%@ page con...
    99+
    2023-06-08
  • 怎么在Android中利用控件实现一个验证码倒计时功能
    这期内容当中小编将会给大家带来有关怎么在Android中利用控件实现一个验证码倒计时功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。使用方式<com.landptf.view.CountDownM...
    99+
    2023-05-31
    android roi
  • 使用JavaScript怎么实现一个验证码干扰功能
    使用JavaScript怎么实现一个验证码干扰功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。代码<!DOCTYPE html><html&g...
    99+
    2023-06-06
  • 怎么使用PHP实现一个短信验证码功能
    本篇内容介绍了“怎么使用PHP实现一个短信验证码功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!第一步:生成短信验证码要生成短信验证码,我...
    99+
    2023-07-05
  • 使用java怎么实现一个动态验证码功能
    使用java怎么实现一个动态验证码功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Andro...
    99+
    2023-06-06
  • 使用canvas怎么实现一个图形验证码功能
    本篇文章给大家分享的是有关使用canvas怎么实现一个图形验证码功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。<!DOCTYPE html><h...
    99+
    2023-06-09
  • 怎么在React中利用Form组件实现一个登录功能
    本篇文章给大家分享的是有关怎么在React中利用Form组件实现一个登录功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。引入所需的 Antd 组件,代码如下所示:import...
    99+
    2023-06-14
  • 如何在Java中利用patchca实现一个验证码生成功能
    本篇文章为大家展示了如何在Java中利用patchca实现一个验证码生成功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。代码如下: @RequestMapping(value = {"...
    99+
    2023-05-31
    java patchca ava
  • 怎么在Android应用中实现一个信验证码倒计时功能
    这篇文章将为大家详细讲解有关怎么在Android应用中实现一个信验证码倒计时功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。实现步骤:一个关键类:CountDownTimer(Androi...
    99+
    2023-05-31
    android roi
  • 如何在Android中实现一个滑块拼图验证码功能
    本篇文章给大家分享的是有关如何在Android中实现一个滑块拼图验证码功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、实现步骤:定义自定义属性; 2、确认目标位置,这里使...
    99+
    2023-06-06
  • 使用python 怎么实现一个滑块验证码识别功能
    今天就跟大家聊聊有关使用python 怎么实现一个滑块验证码识别功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。普通滑动验证import timefrom se...
    99+
    2023-06-14
  • 使用Spring Boot怎么样实现一个验证码生成功能
    这篇文章给大家介绍使用Spring Boot怎么样实现一个验证码生成功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、验证码生成类import java.awt.*;import java.awt.image.Bu...
    99+
    2023-05-31
    springboot spring boo
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作