目录

  • config配置
  • controller层
  • Mapper(Mybatis配置)
  • pojo
  • Service
  • 工具类 MailUtil
  • 前台页面
  • 配置(application)
  • 相关依赖

config配置

  1. UserRealm
package com.example.config;
import com.example.pojo.User;
import com.example.service.UserService;
import org.apache.shiro.SecurityUtils;
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.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;// 自定义的UserRealm
public class UserRealm extends AuthorizingRealm{@AutowiredUserService userService;// 授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("执行了授权doGetAuthorizationInfo");SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.addStringPermission("user:add");// 拿到当前登陆的这个对象Subject subject = SecurityUtils.getSubject();User currentUser = (User)subject.getPrincipal();// 设置当前用户的权限info.addStringPermission(currentUser.getPerms());return info;}// 认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("执行了认证doGetAuthorizationInfo");//        String name = "root";
//        String password = "123";UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;User user = userService.queryUserByName(usernamePasswordToken.getUsername());if(user == null){return null;  // 抛出异常 UnknownAccountException}// 密码认证,shiro做return new SimpleAuthenticationInfo(user,user.getPwd(),"");}
}
  1. ShiroConfig
package com.example.config;import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;
import java.util.Map;@Configuration
public class ShiroConfig {// ShiroFilterFactoryBean  3@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 设置安全管理器shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);/*添加shiro的内置过滤器anno:  无需认证就可以访问authc: 必须认证了才可以访问user:  必须拥有记住我功能才可以访问perms: 拥有对某个资源的权限才能访问role:  拥有某个角色权限才能访问*/Map<String,String> filterMap = new LinkedHashMap<>();//        filterMap.put("/user/add","authc");
//        filterMap.put("/user/update","authc");// 拥有了user:add权限才可以访问/user/add接口filterMap.put("/user/add","perms[user:add]");// 认证了就可以访问user下的所有接口filterMap.put("/user/*","authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);// 设置登录请求shiroFilterFactoryBean.setLoginUrl("/toLogin");// 设置未授权的请求shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");return shiroFilterFactoryBean;}// DefaultWebSecurityManger  2@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 关联UserRealmsecurityManager.setRealm(userRealm);return securityManager;}// 创建 realm对象  需要自定义类  1@Beanpublic UserRealm userRealm(){return new UserRealm();}// shiroDialect: 用来整合shiro和thymeleaf@Beanpublic ShiroDialect shiroDialect() {return new ShiroDialect();}
}

controller层

import com.example.utils.MailUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class Test {@RequestMapping({"/","/index"})public String test(Model model){model.addAttribute("msg","shiro测试");return "index";}@RequestMapping("/user/add")public String toAdd(){return "user/add";}@RequestMapping("/user/update")public String toUpdate(){return "user/update";}@RequestMapping("/toLogin")public String toLogin(){return "login";}@RequestMapping("/login")public String login(String username,String password,String code,Model model){// 获取当前用户Subject subject = SecurityUtils.getSubject();// 封装用户的登陆数据UsernamePasswordToken token = new UsernamePasswordToken(username, password);Session session = subject.getSession();String sendCode = (String) session.getAttribute("sendCode");System.out.println("sendCode:"+sendCode);try{subject.login(token); // 执行登录方法,如果没有异常就说明OK了session.setAttribute("loginUser",token.getPrincipal());if(!sendCode.equals(code)){model.addAttribute("msg","验证码错误");return "login";}return "index";}catch (UnknownAccountException uae) {model.addAttribute("msg","用户名错误");return "login";} catch (IncorrectCredentialsException ice) {model.addAttribute("msg","密码错误");return "login";}}// 未授权页面@RequestMapping("/unauth")@ResponseBodypublic String toUnauthorized(){return "未授权无法访问该页面";}// 注销@RequestMapping("/user/logout")public String logout(){Subject subject = SecurityUtils.getSubject();Session session = subject.getSession();session.removeAttribute("loginUser");System.out.println("注销了");return "redirect:/toLogin";}// 邮箱验证码发送@RequestMapping("/sendCode")@ResponseBodypublic String sendCode(){// 获取当前用户Subject subject = SecurityUtils.getSubject();Session session = subject.getSession();String s = MailUtil.mail1();session.setAttribute("sendCode",s);return s;}
}

Mapper(Mybatis配置)

package com.example.mapper;import com.example.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
@Mapper
public interface UserMapper {User queryUserByName(String name);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><resultMap type="User" id="usermap"><result column="id" property="id"/><result column="name" property="name"/><result column="password" property="pwd"/></resultMap><select id="queryUserByName" resultType="User" resultMap="usermap">select * from mybatis.user where name = #{name}</select>
</mapper>

pojo

package com.example.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String name;private String pwd;private String perms;
}

Service

package com.example.service;import com.example.pojo.User;import java.util.List;
public interface UserService {User queryUserByName(String name);
}
package com.example.service;import com.example.mapper.UserMapper;
import com.example.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
@Service
public class UserServiceImpl implements UserService{@AutowiredUserMapper userMapper;@Overridepublic User queryUserByName(String name){return userMapper.queryUserByName(name);}
}

工具类 MailUtil

package com.example.utils;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Random;
@Component
public class MailUtil {@Autowired(required = false)private JavaMailSenderImpl mailSender;private static MailUtil mailUtil;@PostConstructpublic void init(){mailUtil = this;mailUtil.mailSender = this.mailSender;}public static String mail1() {SimpleMailMessage mailMessage = new SimpleMailMessage();Random random = new Random();StringBuffer str = new StringBuffer();for(int i = 0; i < 6; i++){str.append(random.nextInt(10));}String s = str.toString();System.out.println("邮箱验证码:"+s);mailMessage.setSubject("验证码");mailMessage.setText("您的验证码为:"+s+",如非本人操作,请忽略!请勿回复此邮箱");// 收件人
//        mailMessage.setTo("li17718541773@163.com");mailMessage.setTo("1303205856@qq.com");// 发件人mailMessage.setFrom("1303205856@qq.com");mailUtil.mailSender.send(mailMessage);System.out.println("发送成功");return s;}public void mail2() throws MessagingException {// 复杂的邮件发送MimeMessage mimeMessage = mailSender.createMimeMessage();// 提供对 HTML 文本内容、图像等内联元素和典型邮件附件的支持(multipart是否支持多文本上传)MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);// 主题helper.setSubject("黎明的黑暗");// 正文(true表示开启html)helper.setText("<h1 style='color:red'>穿过黑暗时间</h1>",true);// 附件helper.addAttachment("2.jpg",new File("C:\\Users\\Lenovo\\Pictures\\Camera Roll\\2.jpg"));// 每次只能发给一个人helper.setTo("lo17828541773@163.com");
//      helper.setTo("1306305856@qq.com");// 发件人helper.setFrom("1303205856@qq.com");mailSender.send(mimeMessage);}}

前台页面


1.index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body>
<h1>首页</h1>
<!--登陆成功就不显示登陆了-->
<div th:if="${session.loginUser}==null"><a th:href="@{/toLogin}">登录</a></div>
<p th:text="${msg}"></p>
<div shiro:hasPermission="user:add"><a th:href="@{/user/add}">添加</a></div>
<div shiro:hasPermission="user:update"><a th:href="@{/user/update}">修改</a></div>
<p><a th:href="@{/user/logout}">注销</a></p>
</body>
</html>

2.login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title><script type="text/javascript" src="../js/jquery-3.6.0.min.js" ></script>
</head>
<body>
<p style="color:red" th:text="${msg}"></p>
<form th:action="@{/login}"><p>用户名: <input type="text" name="username"></p><p>  密码: <input type="text" name="password"></p><p><input type="text" name="code"><button id="click" type="button">获取验证码</button></p><p><input type="submit" value="登录"></p>
</form><script>$(function (){$("#click").click(function (){$.ajax({type: "GET",url: "/sendCode",success: function(res){console.log(res);}})})})
</script></body>
</html>

配置(application)

1.application.properties

mybatis.type-aliases-package=com.example.pojo
mybatis.mapper-locations=classpath:mapper/*.xml#邮件发送配置
spring.mail.default-encoding=UTF-8
spring.mail.host=smtp.qq.com
spring.mail.username= 登录邮箱
spring.mail.password=POP3/SMTP服务
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

1.application.yaml


spring:datasource:username: rootpassword: root#?serverTimezone=UTC解决时区的报错url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource#Spring Boot 默认是不注入这些属性值的,需要自己绑定#druid 数据源专有配置initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入#如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4jfilters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

相关依赖

<!--thymeleaf模板--><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring5</artifactId></dependency><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-java8time</artifactId></dependency><!-- shiro整合spring的包 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.8.0</version></dependency><!--Druid数据源--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--shiro-thymeleaf整合--><dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version></dependency><!--邮件发送核心包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency>

shiro整合springboot,配置mybatis和增加邮箱验证码登录相关推荐

  1. activiti+5.21+mysql_ydl-workflow基于SAAS服务,完美整合springboot + activiti5 + MyBatis

    workflow V1.0 ydl-workflow基于SAAS服务,完美整合springboot + activiti5 + MyBatis 通用 Mapper + 分页插件 PageInfo! 说 ...

  2. Shiro 整合 SpringBoot

    Shiro 整合 SpringBoot shiro主要有三大功能模块 Subject:主体,一般指用户. SecurityManager:安全管理器,管理所有Subject,可以配合内部安全组件.(类 ...

  3. SpringBoot配置Mybatis多数据源

    SpringBoot配置Mybatis多数据源 配置多数据源可以将springboot自动装配的数据源给关闭. 1.添加pom文件,只需要添加数据源驱动和mybatis包 <dependency ...

  4. SpringBoot OAuth2.0 使用短信验证码登录授权

    SpringBoot OAuth2.0 使用短信验证码登录授权 实现步骤: 自定义授权器,继承 AbstractTokenGranter 类: 重写 getOAuth2Authentication 函 ...

  5. SpringBoot配置Mybatis打印SQL

    两种方式,一种基于SpringBoot自动装配通过yml文件直接配置,另一种是配置在mybatis的全局配置文件中. 但是两种方式不能同时配置,在SpringBoot V1.5.9以上版本惠报错: P ...

  6. SpringBoot配置mybatis多数据源(包含单数据源)最终解决方案,带源码

    贴上我的github: https://github.com/mx342/testSpringbootMutipartDatasource.git 具体项目文件请查看github上面的项目 # tes ...

  7. springboot配置mybatis redis缓存

    一.概述 首先来了解下mybatis 缓存,mybatis缓存分为一级缓存和二级缓存.一级缓存是默认开启的,无需其他配置操作,二级缓存则需要手动设置开启. 一级缓存原理: Mybatis的一级缓存是指 ...

  8. 手把手带你在集成SpringSecurity的SpringBoot应用中添加短信验证码登录认证功能

    本文目录 前言 1 自定义AuthenticationToken类 2 自定义AuthenticationProvider类 3 自定义MobilePhoneAuthenticationFilter ...

  9. QQ空间及邮箱验证码登录的校验方式及自动登录的解决方案

    目前有很多的SNS社区或类SNS的网站,例如开心.51.校内等,但是发现大多数社区在邀请好友的时候都没有提供对QQ邮箱或者QQ空间好友列表获取的功能,不过似乎海内支持,但是网上相关QQ的文章还不是很多 ...

最新文章

  1. 计算各种形钢的重量用什么软件_造价常用工具不会用,30个常用工程算量工具免费送,速来领取收藏...
  2. 远程服务器返回了意外响应400,远程服务器返回400
  3. boost::io::ostream_put用法的测试程序
  4. ORACLE TEXT DATASTORE PREFERENCE(七)
  5. SpringBoot自定义参数
  6. 2017上海金马五校 购买装备 贪心+二分Check
  7. 从前端智能化看“低代码/无代码”
  8. Eclipse中SVN过滤指定文件夹或文件下内容
  9. JPA通用Dao类设计
  10. (转)OL2中设置鼠标的样式
  11. [deviceone开发]-QQ分享、微信分享和新浪微博分享
  12. java逻辑运算符的使用
  13. 从精度看CPU线程:实验室与量产的差距
  14. 电脑横机服务器维修,三招搞定电脑横机维修
  15. 丁昊 北大计算机,北大清华17人!2018自主招生等类型入选名单公示,苏州333人!...
  16. 在微型计算机中ega,在微机系统中,常有VGA、EGA等说法,它们的含义是什么
  17. 如何区分电梯卡为id卡ic卡_门禁卡ID卡和IC卡从外表怎么区分?
  18. gitee项目能用SVN拉取吗_使用Git开发维护Github开源项目的一些经验
  19. ip中继对接_FreePBX配置IP对接中继
  20. 深度学习-扩张卷积(dilated convolution)

热门文章

  1. 性能与可靠性:Java应用为何像一级方程式赛车
  2. multiavatar.com获取一个随机的头像
  3. 下载 m3u8 视频脚本
  4. Silverlight 动画实现--太阳升起、落下
  5. Distilling Object Detectors with Fine-grained Feature Imitation论文解读
  6. php教室预约系统怎么做,预约系统怎么做?
  7. android 7zip库的编译
  8. 陕西省郁金香 鲜花展览盛会
  9. 零基础学习C++系列课程(三) 持续更新中
  10. 5分钟掌握智联招聘网站爬取并保存到MongoDB数据库