Springboot+Shiro+Mybatis+mysql实现权限安全认证

打印 上一主题 下一主题

主题 878|帖子 878|积分 2634

Shiro是Apache 的一个强大且易用的Java安全框架,执行身份验证、授权、暗码学和会话管理。Shiro 主要分为两个部分就是认证和授权两部分
一、介绍


  • Subject代表了当前用户的安全操纵
  • SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
  • Authenticator即认证器,对用户身份举行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自界说认证器。
  • Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判定用户是否有此功能的操纵权限。
  • Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
  • sessionManager即会话管理,shiro框架界说了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上。
Shiro相关类介绍

  • (1)Authentication 认证 —— 用户登录
  • (2)Authorization 授权 —- 用户具有哪些权限
  • (3)Cryptography 安全数据加密
  • (4)Session Management 会话管理
  • (5)Web Integration web系统集成
  • (6)Interations 集成其它应用,spring、缓存框架
二、依赖引入

完整的pom文件如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.                  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.         <modelVersion>4.0.0</modelVersion>
  6.         <parent>
  7.                 <groupId>org.springframework.boot</groupId>
  8.                 <artifactId>spring-boot-starter-parent</artifactId>
  9.                 <version>2.4.1</version>
  10.                 <relativePath></relativePath>
  11.         </parent>
  12.         <groupId>com.gt.shiro</groupId>
  13.         <artifactId>com.sunyue.shiro</artifactId>
  14.         <version>1.0-SNAPSHOT</version>
  15.         <packaging>jar</packaging>
  16.         <properties>
  17.                 <java.version>1.8</java.version>
  18.                 <druid.verzion>1.1.10</druid.verzion>
  19.                 <pagehelper.version>1.2.10</pagehelper.version>
  20.                 <mybatis.version>2.1.4</mybatis.version>
  21.                 <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
  22.         </properties>
  23.         <dependencies>
  24.                 <dependency>
  25.                         <groupId>org.springframework.boot</groupId>
  26.                         <artifactId>spring-boot-starter-web</artifactId>
  27.                        
  28.                         <exclusions>
  29.                                 <exclusion>
  30.                                         <groupId>org.springframework.boot</groupId>
  31.                                         <artifactId>spring-boot-starter-tomcat</artifactId>
  32.                                 </exclusion>
  33.                         </exclusions>
  34.                 </dependency>
  35.                
  36.                 <dependency>
  37.                         <groupId>org.springframework.boot</groupId>
  38.                         <artifactId>spring-boot-starter-jetty</artifactId>
  39.                 </dependency>
  40.                 <dependency>
  41.                         <groupId>org.mybatis.spring.boot</groupId>
  42.                         <artifactId>mybatis-spring-boot-starter</artifactId>
  43.                         <version>${mybatis.version}</version>
  44.                 </dependency>
  45.                 <dependency>
  46.                         <groupId>org.springframework.boot</groupId>
  47.                         <artifactId>spring-boot-starter-thymeleaf</artifactId>
  48.                 </dependency>
  49.                 <dependency>
  50.                         <groupId>com.github.theborakompanioni</groupId>
  51.                         <artifactId>thymeleaf-extras-shiro</artifactId>
  52.                         <version>2.0.0</version>
  53.                 </dependency>
  54.                
  55.                 <dependency>
  56.                         <groupId>org.apache.shiro</groupId>
  57.                         <artifactId>shiro-spring</artifactId>
  58.                         <version>1.4.0</version>
  59.                 </dependency>
  60.                 <dependency>
  61.                         <groupId>com.alibaba</groupId>
  62.                         <artifactId>druid-spring-boot-starter</artifactId>
  63.                         <version>${druid.verzion}</version>
  64.                 </dependency>
  65.                
  66.                 <dependency>
  67.                         <groupId>com.github.pagehelper</groupId>
  68.                         <artifactId>pagehelper-spring-boot-starter</artifactId>
  69.                         <version>${pagehelper.version}</version>
  70.                 </dependency>
  71.                 <dependency>
  72.                         <groupId>mysql</groupId>
  73.                         <artifactId>mysql-connector-java</artifactId>
  74.                         <scope>runtime</scope>
  75.                 </dependency>
  76.                 <dependency>
  77.                         <groupId>org.projectlombok</groupId>
  78.                         <artifactId>lombok</artifactId>
  79.                         <optional>true</optional>
  80.                 </dependency>
  81.                 <dependency>
  82.                         <groupId>org.springframework.boot</groupId>
  83.                         <artifactId>spring-boot-starter-test</artifactId>
  84.                         <scope>test</scope>
  85.                 </dependency>
  86.         </dependencies>
  87.         <build>
  88.                 <plugins>
  89.                        
  90.                         <plugin>
  91.                                 <groupId>org.springframework.boot</groupId>
  92.                                 <artifactId>spring-boot-maven-plugin</artifactId>
  93.                                 <configuration>
  94.                                         <mainClass>com.gt.shiro.SpringShiroApplication</mainClass>
  95.                                 </configuration>
  96.                         </plugin>
  97.                 </plugins>
  98.         </build>
  99. </project>
复制代码
三、配置文件
  1. application.yml配置文件:
  2. # 开发时关闭缓存,不然没法看到实时页面
  3. spring.thymeleaf.cache=false
  4. # 用非严格的 HTML
  5. spring.thymeleaf.mode=HTML
  6. spring.thymeleaf.encoding=utf-8
  7. spring.thymeleaf.servlet.content-type=text/html
  8. spring.datasource.druid.url=jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
  9. spring.datasource.druid.username=root
  10. spring.datasource.druid.password=admin
  11. spring.datasource.druid.initial-size=1
  12. spring.datasource.druid.min-idle=1
  13. spring.datasource.druid.max-active=20
  14. spring.datasource.druid.test-on-borrow=true
  15. #springbootjdbc导入包不和以前一样
  16. spring.datasource.druid.driver-class-name= com.mysql.cj.jdbc.Driver
  17. mybatis.type-aliases-package=com.gt.shiro.entity
  18. mybatis.mapper-locations=classpath:mapper/*.xml
  19. #打印数据库的操作
  20. logging.level.com.example.springsecurity.dao=debug
  21. #redis缓存
  22. ### 配置Redis
  23. mybatis.configuration.cache-enabled=true
  24. # Redis数据库索引(默认为0)
  25. spring.redis.database=0
  26. # Redis服务器地址
  27. spring.redis.host=...
  28. # Redis服务器连接端口
  29. spring.redis.port=6379
  30. # Redis服务器连接密码(默认为空)
  31. spring.redis.password=sunyue
  32. # 连接池最大连接数(使用负值表示没有限制)
  33. spring.redis.jedis.pool.max-idle=200
  34. # 连接池最大阻塞等待时间(使用负值表示没有限制)
  35. spring.redis.jedis.pool.max-wait=-1
  36. # 连接池中的最小空闲连接
  37. spring.redis.jedis.pool.min-idle=0
  38. # 连接超时时间(毫秒)
  39. spring.redis.timeout=1000
复制代码
Shiro两个紧张的配置类:

  • 1.UserRealm
    1.   package com.gt.shiro.config;
    2.   import com.gt.shiro.entity.TestUser;
    3.   import com.gt.shiro.server.TestUserServer;
    4.   import org.apache.shiro.SecurityUtils;
    5.   import org.apache.shiro.authc.*;
    6.   import org.apache.shiro.authz.AuthorizationInfo;
    7.   import org.apache.shiro.authz.SimpleAuthorizationInfo;
    8.   import org.apache.shiro.realm.AuthorizingRealm;
    9.   import org.apache.shiro.subject.PrincipalCollection;
    10.   import org.apache.shiro.subject.Subject;
    11.   import org.springframework.beans.factory.annotation.Autowired;
    12.   import java.util.ArrayList;
    13.   import java.util.HashSet;
    14.   import java.util.List;
    15.   import java.util.Set;
    16.   public class UserRealm extends AuthorizingRealm {
    17.           @Autowired
    18.           private TestUserServer testUserServer;
    19.           /**
    20.            * 执行授权逻辑
    21.            *
    22.            * @param principalCollection
    23.            * @return
    24.            */
    25.           @Override
    26.           protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    27.                   System.out.println("执行授权逻辑");
    28.                   /*获取当前登录的用户信息*/
    29.                   Subject subject = SecurityUtils.getSubject();
    30.                   TestUser testUser = (TestUser) subject.getPrincipal();
    31.                   //设置角色,多个角色
    32.                   /*Set<String> rolesSet = new HashSet<>();
    33.                   rolesSet.add(testUser.getRole());*/
    34.                   //SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(rolesSet);
    35.                   //给资源进行授权
    36.                   SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    37.                   /*可以在以下list加入多个权限*/
    38.                   /*List<String> roles = new ArrayList<>();
    39.                   roles.add(testUser.getPerms());
    40.                   info.addRoles(roles);*/
    41.                   //设置权限
    42.                   info.addRole(testUser.getRole());
    43.                   //需要判断权限是否为空值(null是没有地址,""是有地址但是里面的内容是空的)
    44.                   if (testUser.getPerms() != null && !testUser.getPerms().equals("")) {
    45.                           info.addStringPermission(testUser.getPerms());
    46.                   }
    47.                   return info;
    48.           }
    49.           /**
    50.            * 执行认证逻辑
    51.            *
    52.            * @param authenticationToken
    53.            * @return
    54.            * @throws AuthenticationException
    55.            */
    56.           @Override
    57.           protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    58.                   System.out.println("执行认证逻辑");
    59.                   /*获取令牌*/
    60.                   UsernamePasswordToken passwordToken = (UsernamePasswordToken) authenticationToken;
    61.                   //取出用户名并且判断用户名是否和数据库一致
    62.                   TestUser testUser = testUserServer.selectOneByName(passwordToken.getUsername());
    63.                   if (testUser != null) {
    64.                           //进行认证,将正确数据给shiro处理
    65.                           //密码不用自己比对,AuthenticationInfo认证信息对象,一个接口,new他的实现类对象SimpleAuthenticationInfo
    66.                           /*    第一个参数随便放,可以放user对象,程序可在任意位置获取 放入的对象
    67.                            * 第二个参数必须放密码,
    68.                            * 第三个参数放 当前realm的名字,因为可能有多个realm*/
    69.                           //若密码不正确则返回IncorrectCredentialsException异常
    70.                           return new SimpleAuthenticationInfo(testUser, testUser.getPassword(), this.getName());
    71.                   }
    72.                   //若用户名不存在则返回UnknownAccountException异常
    73.                   return null;
    74.           }
    75.   }
    复制代码
  • 2.ShiroConfig
    1.   package com.gt.shiro.config;
    2.   import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
    3.   import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    4.   import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    5.   import org.apache.shiro.mgt.SecurityManager;
    6.   import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    7.   import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
    8.   import org.springframework.beans.factory.annotation.Qualifier;
    9.   import org.springframework.context.annotation.Bean;
    10.   import org.springframework.context.annotation.Configuration;
    11.   import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
    12.   import java.util.LinkedHashMap;
    13.   import java.util.Map;
    14.   import java.util.Properties;
    15.   @Configuration
    16.   public class ShiroConfig {
    17.           @Bean
    18.           public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
    19.                   ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    20.                   //设置安全管理器
    21.                   shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
    22.                   //添加一些Shiro的内置过滤器
    23.                   /**
    24.                    * Shiro 的内置过滤器可以实现权限的相关拦截
    25.                    * 常用过滤器
    26.                    * 1.anon:无需认证
    27.                    * 2.authc:必须认证才能访问
    28.                    * 3.user:如果使用rememberme功能可以访问
    29.                    * 4.perms:对应权限才能访问
    30.                    * 5.role:对应角色才能访问
    31.                    */
    32.                   //登录状态下才可以访问main页面,manage权限可访问manage页面,admin角色可访问admin页面
    33.                   Map<String, String> filterMap = new LinkedHashMap<String, String>();
    34.                   filterMap.put("/main", "authc");
    35.                   filterMap.put("/manage", "perms[manage]");
    36.                   filterMap.put("/admin", "roles[admin]");
    37.                   shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
    38.                   //未登录状态下访问将跳转至login页面
    39.                   // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
    40.                   shiroFilterFactoryBean.setLoginUrl("/login");
    41.                   // 登录成功后要跳转的链接
    42.                   shiroFilterFactoryBean.setSuccessUrl("/");
    43.                   //无授限状态下访问将请求unauthor
    44.                   shiroFilterFactoryBean.setUnauthorizedUrl("/unAuth");
    45.                   return shiroFilterFactoryBean;
    46.           }
    47.           @Bean(name = "securityManager")
    48.           public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
    49.                   DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
    50.                   //DefaultWebSecurityManager需要关联一个Realm
    51.                   defaultWebSecurityManager.setRealm(userRealm);
    52.                   return defaultWebSecurityManager;
    53.           }
    54.           /**
    55.            * 创建realm
    56.            */
    57.           @Bean(name = "userRealm")
    58.           public UserRealm getRealm() {
    59.                   return new UserRealm();
    60.           }
    61.           @Bean
    62.           public ShiroDialect shiroDialect() {
    63.                   return new ShiroDialect();
    64.           }
    65.           /**
    66.            * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions)
    67.            * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能
    68.            *
    69.            * @return
    70.            */
    71.           @Bean
    72.           public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
    73.                   DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    74.                   advisorAutoProxyCreator.setProxyTargetClass(true);
    75.                   return advisorAutoProxyCreator;
    76.           }
    77.           /**
    78.            * 开启 shiro 的@RequiresPermissions注解
    79.            *
    80.            * @param securityManager
    81.            * @return
    82.            */
    83.           @Bean
    84.           public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
    85.                   AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    86.                   authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    87.                   return authorizationAttributeSourceAdvisor;
    88.           }
    89.           /**
    90.            * shiro出现权限异常可通过此异常实现制定页面的跳转(或接口跳转)
    91.            *
    92.            * @return
    93.            */
    94.           @Bean
    95.           public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
    96.                   SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
    97.                   Properties properties = new Properties();
    98.                   /*未授权处理页*/
    99.                   properties.setProperty("org.apache.shiro.authz.UnauthorizedException", "/error.html");
    100.                   /*身份没有验证*/
    101.                   properties.setProperty("org.apache.shiro.authz.UnauthenticatedException", "/error.html");
    102.                   resolver.setExceptionMappings(properties);
    103.                   return resolver;
    104.           }
    105.   }
    复制代码
四、数据连接和业务逻辑


  • 1.实体类
    1.   package com.gt.shiro.entity;
    2.   import lombok.Data;
    3.   import lombok.experimental.Accessors;
    4.   import java.io.Serializable;
    5.   import java.util.Date;
    6.   @Data
    7.   @Accessors(chain = true)
    8.   public class TestUser implements Serializable {
    9.           private Integer id;
    10.           private String username;
    11.           private String password;
    12.           /*权限*/
    13.           private String perms;
    14.           /*角色*/
    15.           private String role;
    16.           /*加盐密码*/
    17.           private String salt;
    18.   }
    复制代码
  • 2.Dao和Mapper
    1.   package com.gt.shiro.dao;
    2.   import com.gt.shiro.entity.TestUser;
    3.   import org.apache.ibatis.annotations.Mapper;
    4.   import java.util.List;
    5.   @Mapper
    6.   public interface TestUserMapper {
    7.           List<TestUser> findAll();
    8.           TestUser selectOne(Integer id);
    9.           TestUser selectOneByName(String username);
    10.           void insert(TestUser testUser);
    11.           void update(TestUser testUser);
    12.           void delete(Integer id);
    13.   }
    复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.gt.shiro.dao.TestUserMapper">
  4.         <select id="findAll"  resultType="TestUser">
  5.            select * from test_user
  6.         </select>
  7.         <select id="selectOne" resultType="TestUser">
  8.            select * from test_user where id=#{id}
  9.         </select>
  10.         <select id="selectOneByName" resultType="TestUser">
  11.            select * from test_user where username=#{username}
  12.         </select>
  13.         <insert id="insert">
  14.                 insert into test_user (id,username,password,perms,role,salt) value (#{id},#{username},#{password},#{perms},#{role},#{salt})
  15.         </insert>
  16.         <update id="update">
  17.                 update test_user set username = #{username},password=#{password},perms=#{perms},role=#{role},salt=#{salt} where id = #{id}
  18.         </update>
  19.         <delete id="delete">
  20.                 delete from test_user where id = #{id}
  21.         </delete>
  22. </mapper>
复制代码

  • 3.业务层及其实现
    1.   package com.gt.shiro.server;
    2.   import com.gt.shiro.entity.TestUser;
    3.   import org.springframework.stereotype.Service;
    4.   import java.util.List;
    5.   @Service
    6.   public interface TestUserServer {
    7.           /*查询所有*/
    8.           List<TestUser> selectAll();
    9.           /*查询一个用户*/
    10.           TestUser selectByOne(Integer id);
    11.           /*通过名字查询一个用户*/
    12.           TestUser selectOneByName(String name);
    13.           /*增加一个用户*/
    14.           void insert(TestUser testUser);
    15.           /*删除一个用户*/
    16.           void delete(Integer id);
    17.           /*更新一个用户*/
    18.           void update(TestUser testUser);
    19.   }
    复制代码
  1. package com.gt.shiro.server.serverImpl;
  2. import com.gt.shiro.dao.TestUserMapper;
  3. import com.gt.shiro.entity.TestUser;
  4. import org.apache.shiro.crypto.SecureRandomNumberGenerator;
  5. import org.apache.shiro.crypto.hash.SimpleHash;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Service;
  8. import com.sunyue.shiro.server.TestUserServer;
  9. import java.util.List;
  10. @Service
  11. public class TestUserServerImpl implements TestUserServer {
  12.         @Autowired
  13.         private TestUserMapper testUserMapper;
  14.         @Override
  15.         public List<TestUser> selectAll() {
  16.                 return testUserMapper.findAll();
  17.         }
  18.         @Override
  19.         public TestUser selectByOne(Integer id) {
  20.                 return testUserMapper.selectOne(id);
  21.         }
  22.         @Override
  23.         public TestUser selectOneByName(String name) {
  24.                 return testUserMapper.selectOneByName(name);
  25.         }
  26.         @Override
  27.         public void insert(TestUser testUser) {
  28.                 //加密写法
  29.                 String salt = new SecureRandomNumberGenerator().nextBytes().toString();
  30.                 String password= new SimpleHash("md5",testUser.getPassword(),salt,2).toString();
  31.                 testUser.setPassword(password);
  32.                 testUser.setSalt(salt);
  33.                 testUserMapper.insert(testUser);
  34.         }
  35.         @Override
  36.         public void delete(Integer id) {
  37.                 testUserMapper.delete(id);
  38.         }
  39.         @Override
  40.         public void update(TestUser testUser) {
  41.                 testUserMapper.update(testUser);
  42.         }
  43. }
复制代码

  • 4.控制层
    1.   package com.gt.shiro.controller;
    2.   import com.gt.shiro.entity.TestUser;
    3.   import com.gt.shiro.server.TestUserServer;
    4.   import org.apache.shiro.SecurityUtils;
    5.   import org.apache.shiro.authc.IncorrectCredentialsException;
    6.   import org.apache.shiro.authc.UnknownAccountException;
    7.   import org.apache.shiro.authc.UsernamePasswordToken;
    8.   import org.apache.shiro.crypto.hash.SimpleHash;
    9.   import org.apache.shiro.subject.Subject;
    10.   import org.springframework.beans.factory.annotation.Autowired;
    11.   import org.springframework.stereotype.Controller;
    12.   import org.springframework.ui.Model;
    13.   import org.springframework.web.bind.annotation.*;
    14.   @Controller
    15.   public class indexController {
    16.           @Autowired
    17.           private TestUserServer testUserServer;
    18.           @GetMapping("/{url}")
    19.           public String redirect(@PathVariable("url") String url) {
    20.                   return url;
    21.           }
    22.           @RequestMapping(value = {"/", "/index"}, method = RequestMethod.GET)
    23.           private String index() {
    24.                   return "index";
    25.           }
    26.           @PostMapping("/login")
    27.           public String login(String username, String password, Model model) {
    28.                   Subject subject = SecurityUtils.getSubject();
    29.                   TestUser testUser = testUserServer.selectOneByName(username);
    30.                   if (testUser != null) {
    31.                           //根据salt值和用户输入的密码计算加密后的密码
    32.                           String salt = testUser.getSalt();
    33.                           password = new SimpleHash("md5", password, salt, 2).toString();
    34.                           System.out.println(password);
    35.                   }
    36.                   UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    37.                   //UsernamePasswordToken token = new UsernamePasswordToken(username, testUser.getPassword());(不加密写法)
    38.                   try {
    39.                           //将用户名和密码通过token传给shiro进行认证
    40.                           subject.login(token);
    41.                           TestUser user = (TestUser) subject.getPrincipal();
    42.                           subject.getSession().setAttribute("testUser", user);
    43.                           return "index";
    44.                   } catch (UnknownAccountException e) {
    45.                           e.printStackTrace();
    46.                           model.addAttribute("msg", "用户名不存在");
    47.                           return "login";
    48.                   } catch (IncorrectCredentialsException e) {
    49.                           e.printStackTrace();
    50.                           model.addAttribute("msg", "密码有误");
    51.                           return "login";
    52.                   }
    53.           }
    54.           @ResponseBody
    55.           @GetMapping("/unauthor")
    56.           public String unauthor() {
    57.                   return "权限不足,无法访问";
    58.           }
    59.           @GetMapping("/logout")
    60.           public String logout() {
    61.                   Subject subject = SecurityUtils.getSubject();
    62.                   subject.logout();
    63.                   return "login";
    64.           }
    65.           @PostMapping("/register")
    66.           public String register(TestUser testUser, Model model) {
    67.                   String username = testUser.getUsername();
    68.                   String password = testUser.getPassword();
    69.                   if (username ** null || username.equals("")) {
    70.                           model.addAttribute("msg", "用户名不能为空");
    71.                           return "register";
    72.                   } else if (password ** null || password.equals("")) {
    73.                           model.addAttribute("msg", "密码不能为空");
    74.                           return "register";
    75.                   } else if (testUserServer.selectOneByName(username) != null) {
    76.                           model.addAttribute("msg", "用户名已被占用");
    77.                           return "register";
    78.                   } else {
    79.                           testUserServer.insert(testUser);
    80.                           return "login";
    81.                   }
    82.           }
    83.   }
    复制代码
  • 5.前端页面

    • (1)index.html
      1.   <!DOCTYPE html>
      2.   <html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymrleaf.org/thymeleaf-extras-shiro">
      3.   <head>
      4.           <meta charset="UTF-8">
      5.           <title>Insert title here</title>
      6.           <link rel="shortcut icon" href="#"/>
      7.   </head>
      8.   <body>
      9.   
      10.                  
      11.                   <a target="_blank" href="https://www.cnblogs.com/logout">退出</a>
      12.   
      13.   <a target="_blank" href="https://www.cnblogs.com/main">main</a>
      14.    | <a target="_blank" href="https://www.cnblogs.com/manage">manage</a>
      15.    | <a target="_blank" href="https://www.cnblogs.com/admin">admin</a>
      16.   
      17.   </body>
      18.   </html>
      复制代码
    • (2)login.html
      1.   <!DOCTYPE html>
      2.   <html xmlns:th="http://www.thymeleaf.org">
      3.   <head>
      4.           <meta charset="UTF-8">
      5.           <title>Insert title here</title>
      6.           <link rel="shortcut icon" href="#"/>
      7.   </head>
      8.   <body>
      9.   <form action="/login" method="post">
      10.          
      11.           <table>
      12.                   <tr>
      13.                           <td>用户名:</td>
      14.                           <td><input type="text" name="username"/></td>
      15.                   </tr>
      16.                   <tr>
      17.                           <td>密码:</td>
      18.                           <td><input type="password" name="password"/></td>
      19.                   </tr>
      20.                   <tr>
      21.                           <td><input type="submit" value="登录"/></td>
      22.                           <td><a target="_blank" href="https://www.cnblogs.com/register">
      23.                                   <button type="button" value="注册">注册</button>
      24.                           </a>
      25.                           </td>
      26.                   </tr>
      27.           </table>
      28.   </form>
      29.   </body>
      30.   </html>
      复制代码
    • (3)register.html
      1.   <!DOCTYPE html>
      2.   <html xmlns:th="http://www.thymeleaf.org">
      3.   <head>
      4.           <meta charset="UTF-8">
      5.           <title>Insert title here</title>
      6.           <link rel="shortcut icon" href="#"/>
      7.   </head>
      8.   <body>
      9.   <form action="/register" method="post">
      10.          
      11.           <table>
      12.                   <tr>
      13.                           <td>用户名:</td>
      14.                           <td><input type="text" name="username"/></td>
      15.                   </tr>
      16.                   <tr>
      17.                           <td>密码:</td>
      18.                           <td><input type="password" name="password"/></td>
      19.                   </tr>
      20.                   <tr>
      21.                           <td><input type="submit" value="注册"/></td>
      22.                   </tr>
      23.           </table>
      24.   </form>
      25.   </body>
      26.   </html>
      复制代码
    • (4)main.html
      1.   <!DOCTYPE html>
      2.   <html>
      3.   <head>
      4.           <meta charset="UTF-8">
      5.           <title>Insert title here</title>
      6.           <link rel="shortcut icon" href="#"/>
      7.   </head>
      8.   <body>
      9.   <h1>main</h1>
      10.   </body>
      11.   </html>
      复制代码
    • (5)manage.html
      1.   <!DOCTYPE html>
      2.   <html>
      3.   <head>
      4.           <meta charset="UTF-8">
      5.           <title>Insert title here</title>
      6.           <link rel="shortcut icon" href="#"/>
      7.   </head>
      8.   <body>
      9.   <h1>manage</h1>
      10.   </body>
      11.   </html>
      复制代码
    • (6)admin.html
      1.   <!DOCTYPE html>
      2.   <html>
      3.   <head>
      4.           <meta charset="UTF-8">
      5.           <title>Insert title here</title>
      6.           <link rel="shortcut icon" href="#"/>
      7.   </head>
      8.   <body>
      9.   <h1>admin</h1>
      10.   </body>
      11.   </html>
      复制代码

  • 6.数据库文件
    1.   /*
    2.   Navicat MySQL Data Transfer
    3.   Source Server         : sunyue
    4.   Source Server Version : 50724
    5.   Source Host           : localhost:3306
    6.   Source Database       : shiro
    7.   Target Server Type    : MYSQL
    8.   Target Server Version : 50724
    9.   File Encoding         : 65001
    10.   Date: 2021-01-11 22:00:47
    11.   */
    12.   SET FOREIGN_KEY_CHECKS=0;
    13.   -- ----------------------------
    14.   -- Table structure for test_user
    15.   -- ----------------------------
    16.   DROP TABLE IF EXISTS `test_user`;
    17.   CREATE TABLE `test_user` (
    18.     `id` int(11) NOT NULL AUTO_INCREMENT,
    19.     `username` varchar(120) DEFAULT NULL,
    20.     `password` varchar(120) DEFAULT NULL,
    21.     `perms` varchar(120) DEFAULT NULL,
    22.     `role` varchar(120) DEFAULT NULL,
    23.     `salt` varchar(100) DEFAULT NULL,
    24.     PRIMARY KEY (`id`)
    25.   ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
    26.   -- ----------------------------
    27.   -- Records of test_user
    28.   -- ----------------------------
    29.   INSERT INTO `test_user` VALUES ('4', 'admin', '4867df2e009d0096c4cd8d9be8cc104c', 'manage', 'admin', 'GQR2m1N1o3nSLjtOzMITRQ**');
    30.   INSERT INTO `test_user` VALUES ('5', 'user', '636502f40cf197dd2f4b19f56f475b24', '', '', 'Kxw3HZiFmgnlUu8fmjMY7Q**');
    31.   INSERT INTO `test_user` VALUES ('6', 'user1', '43f3133aa7e0ef9cf8373521dff8d8e8', 'manage', null, 'J8fn4HpauvNOrlUaRl/Spg**');
    32.   INSERT INTO `test_user` VALUES ('7', '1', '1', 'manage', null, null);
    复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表