Shiro简单使用

Shiro简单使用

简介

  1. shiro是一个安全框架

  2. 可以完成:认证、授权、加密、会话管理、与Web 集成、缓存等功能。

  3. 下载地址

    • 官网:http://shiro.apache.org/

    • github:https://github.com/apache/shiro

功能

  • Authentication:身份认证/登录,验证用户是不是拥有相应的身份
  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限
  • Session Management:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境,也可以是Web 环境的
  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储
  • Web Support:Web 支持,可以非常容易的集成到Web 环境
  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率
  • Concurrency:Shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去
  • Testing:提供测试支持
  • “Run As”:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问
  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

使用(springboot+shiro实现用户认证)

  1. shiro核心API

    1. Subject:用户主体,包含登陆、注销、判断、授权等方法(把操作交给SecurityManager)
    2. SecurityManager:安全管理器(关联Realm)
    3. Realm:Shiro连接数据的桥梁
    4. Subject 关联 SecurityManager,SecurityManager 关联 Realm
  2. Springboot 整合 Shiro 步骤

    1. 导入 shiro 整合依赖(pom.xml)

      <dependency>
          <groupId>org.crazycake</groupId>
          <artifactId>shiro-redis-spring-boot-starter</artifactId>
          <version>3.3.1</version>
      </dependency>
      
    2. Controller控制器类

      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class XxxxConfroller {
      
          @RequestMapping("/xxx")
          public String xxx(){
              return "xxx";
          }
      
          @RequestMapping("/xxx/{user}")
          public String user(String user,String pwd){
              return user;
          }
      
          @RequestMapping("login")
          public String loginUser(){
              return "login";
          }
      
      }
      
    3. 自定义 Realm 类

      创建自定义的 Realm 类:UserRealm.java(要继承 AuthorizingRealm 类)

      import org.apache.shiro.authc.AuthenticationException;
      import org.apache.shiro.authc.AuthenticationInfo;
      import org.apache.shiro.authc.AuthenticationToken;
      import org.apache.shiro.authz.AuthorizationInfo;
      import org.apache.shiro.realm.AuthorizingRealm;
      import org.apache.shiro.subject.PrincipalCollection;
      
      public class UserRealm extends AuthorizingRealm {
      
          /**
           * 执行授权逻辑,获取授权信息(方法名直译)
           * @param principalCollection
           * @return
           */
          @Override
          protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
              System.out.println("执行授权逻辑");
              return null;
          }
      
          /**
           * 执行认证逻辑,获取认证信息(方法名直译)
           * @param authenticationToken
           * @return
           * @throws AuthenticationException
           */
          @Override
          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
              System.out.println("执行认证逻辑");
              return null;
          }
      }
      
    4. 编写shiro配置类(最基本、重要)

      创建shiro配置类:ShiroConfig.java

      1. 创建 ShiroFilterFactoryBean(shiro过滤器)
      2. 创建 DefaultWebSecurityManager(默认web安全管理器)
      3. 创建 Realm 对象
      4. Subject 关联 SecurityManager,SecurityManager 关联 Realm
      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;
      
      /**
       * @author wei斯基
       * Shiro配置类
       *  通过@Bean将方法/类交由spring容器管理,之后利用@Qualifier根据设置的名字(若不设置名字则默认是方法/类名首字母小写)进行调用关联。
       */
      @Configuration
      public class ShiroConfig {
      
          /**
           * 第三步:创建 ShiroFilterFactoryBean(shiro过滤器)
           */
          @Bean
          public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
              ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
      
              //1.设置安全管理器(关联web安全管理器)
              shiroFilterFactoryBean.setSecurityManager(securityManager);
              //2.添加shiro内置过滤器
              //拦截,Map第一个值为要拦截的地址,第二个值是要使用的过滤器
              Map<String, String> fileMap = new LinkedHashMap<String, String>();
              // /xxx地址无需认证即可访问
              fileMap.put("/xxx","anon");
              // /xxx/user地址需要认证才可访问,拦截成功后会跳转到login.jsp页面
              fileMap.put("/xxx/user","authc");
      
              //修改为自定义的login登陆页面(设置登录网址)
              shiroFilterFactoryBean.setLoginUrl("/login");
      
              // 设置过滤器链定义映射(放置一个用于存储拦截地址和过滤器的map,)
              shiroFilterFactoryBean.setFilterChainDefinitionMap(fileMap);
      
              return shiroFilterFactoryBean;
          }
      
          /**
           * 第二步:创建 DefaultWebSecurityManager(默认web安全管理器)
           */
          @Bean(name = "securityManager")
          public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
              DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
      //        关联自定义的 Realm
              defaultWebSecurityManager.setRealm(userRealm);
              return defaultWebSecurityManager;
          }
      
          /**
           * 第一步:创建 Realm 对象,利用@Bean将其交给spring容器管理,以便给安全管理器调用
           */
          @Bean(name = "userRealm")
          public UserRealm getRealm() {
              return new UserRealm();
          }
      
      }
      
    5. 使用 Shiro过滤器(ShiroFilterFactoryBean) 实现认证资源拦截

      shiro内置常用过滤器:

      1. anon:无需认证(登陆)即可访问资源
      2. authc:必须认证才可访问
      3. user:如果使用remeberMe(记住我)的功能即可直接进行访问
      4. perms:该资源必须获得资源权限才可访问
      5. role:该资源必须获得用户权限才可访问
      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;
      
      /**
       * @author wei斯基
       * Shiro配置类
       *  通过@Bean将方法/类交由spring容器管理,之后利用@Qualifier根据设置的名字(若不设置名字则默认是方法/类名首字母小写)进行调用关联。
       */
      @Configuration
      public class ShiroConfig {
      
          /**
           * 第三步:创建 ShiroFilterFactoryBean(shiro过滤器)
           */
          @Bean
          public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
              ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
      
              //1.设置安全管理器(关联web安全管理器)
              shiroFilterFactoryBean.setSecurityManager(securityManager);
              //2.添加shiro内置过滤器
              //拦截,Map第一个值为要拦截的地址,第二个值是要使用的过滤器
              Map<String, String> fileMap = new LinkedHashMap<String, String>();
              // /xxx地址无需认证即可访问
              fileMap.put("/toLogin","anon");
              fileMap.put("/loginUser","anon");
              // /xxx/user地址需要认证才可访问,拦截成功后会跳转到login.jsp页面
              fileMap.put("/user/*","authc");
              fileMap.put("/main","authc");
      
              //修改为自定义的login登陆页面(设置登录网址)
              shiroFilterFactoryBean.setLoginUrl("/toLogin");
      
              // 设置过滤器链定义映射(放置一个用于存储拦截地址和过滤器的map,)
              shiroFilterFactoryBean.setFilterChainDefinitionMap(fileMap);
      
              return shiroFilterFactoryBean;
          }
      
          /**
           * 第二步:创建 DefaultWebSecurityManager(默认web安全管理器)
           */
          @Bean(name = "securityManager")
          public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
              DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
      //        关联自定义的 Realm
              defaultWebSecurityManager.setRealm(userRealm);
              return defaultWebSecurityManager;
          }
      
          /**
           * 第一步:创建 Realm 对象,利用@Bean将其交给spring容器管理,以便给安全管理器调用
           */
          @Bean(name = "userRealm")
          public UserRealm getRealm() {
              return new UserRealm();
          }
      
      }
      
    6. 创建测试用的页面

      login.html

      <!DOCTYPE html>
      <html lang="en" xmlns:th="http://www.thymeleaf.org">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      <h1>登录界面</h1>
      <p color="red" th:text="${loginMsg}"></p>
      <form action="/loginUser" method="post">
          用户名:<input name="username" type="text"/>
          <br>
          密码:<input name="password" type="password"/>
          <br>
          <input type="submit" value="登录"/>
          <input type="reset" value="重置">
      </form>
      </body>
      </html>
      

      main.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>main</title>
      </head>
      <body>
      <a href="/user/add">add</a>
      <a href="/user/update">update</a>
      </body>
      </html>
      

      add.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>add</title>
      </head>
      <body>
      add
      </body>
      </html>
      

      update.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>update</title>
      </head>
      <body>
      update
      </body>
      </html>
      
    7. 在Controller类中编写用户认证操作

      package com.study.controller;
      
      import com.study.service.Impl.UserServiceImpl;
      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.subject.Subject;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.Model;
      import org.springframework.web.bind.annotation.RequestMapping;
      
      @Controller
      public class UserController {
      
          @Autowired
          UserServiceImpl userServiceImpl;
      
          @RequestMapping(value = "/user/add")
          public String add() {
              return "/user/add";
          }
      
          @RequestMapping(value = "/user/update")
          public String update() {
              return "/user/update";
          }
      
          @RequestMapping("toLogin")
          public String toLogin() {
              return "login";
          }
      
          @RequestMapping(value = "/loginUser")
          public String login(String username, String password, Model model) {
              /**
               * 使用shiro编写认证操作
               */
              // 1.获取Subject
              Subject subject = SecurityUtils.getSubject();
              // 2.封装用户数据
              UsernamePasswordToken token = new UsernamePasswordToken(username, password);
              // 3.执行登陆操作
              try {
                  // subject.login(token)会跳转到 UserRealm的AuthenticationInfo中执行认证操作
                  subject.login(token);
                  return "main";
              } catch (UnknownAccountException e) {    // 此错误(未知的帐号异常)表示没有此用户
                  model.addAttribute("loginMsg", "用户名不存在");
                  return "login";
              } catch (IncorrectCredentialsException e) { // 此错误(不正确的凭据异常)表示密码错误
                  model.addAttribute("loginMsg", "密码错误");
                  return "login";
              }
          }
      }
      
    8. 在UserRealm中编写认证操作

      /**
       * 执行认证逻辑,获取认证信息(方法名直译)
       *
       * @param authenticationToken
       * @return
       * @throws AuthenticationException
       */
      @Override
      protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
          System.out.println("执行认证逻辑");
      
          //模拟用户名和密码
          String username = "qweasdzxc";
          String password = "qweasdzxc";
      
          /**
           * 编写shiro判断逻辑,判断用户名和密码
           */
      
          // 1.判断用户名(前端传过来的便是一个 UsernamePasswordToken,将 authenticationToken 转换为 UsernamePasswordToken 便可利用方法将其中的用户名和密码取出)
          UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
      
          //将从 token 中取出的用户名和密码与数据库或者模拟的数据进行对比
          if (token.getUsername().equals(username)) {
      
              // 2.判断密码,第一个参数是返回给.login方法的参数,可以为空;第二个参数是数据库或者模拟的密码;第三个参数是shiro的名字,可以为空
              return new SimpleAuthenticationInfo("", password, "");
      
          } else {
      
              System.out.println("用户名不存在");
      
              // 此步骤 shiro 底层会抛出一个 UnknownAccountException
              return null;
          }
      }
      
    9. shiro连接数据库进行判断

      package com.study.shiro;
      
      import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
      import com.study.pojo.User;
      import com.study.service.Impl.UserServiceImpl;
      import com.study.service.UserService;
      import org.apache.shiro.authc.*;
      import org.apache.shiro.authz.AuthorizationInfo;
      import org.apache.shiro.realm.AuthorizingRealm;
      import org.apache.shiro.subject.PrincipalCollection;
      import org.springframework.beans.factory.annotation.Autowired;
      
      /**
       * @author wei斯基
       */
      public class UserRealm extends AuthorizingRealm {
      
          @Autowired
          UserServiceImpl userService;
      
      
          /**
           * 执行授权逻辑,获取授权信息(方法名直译)
           */
          @Override
          protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
              System.out.println("执行授权逻辑");
              return null;
          }
      
          /**
           * 执行认证逻辑,获取认证信息(方法名直译)
           */
          @Override
          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
              System.out.println("执行认证逻辑");
      
              QueryWrapper<User> userWrapper = new QueryWrapper<>();
      
              /* 编写shiro判断逻辑,判断用户名和密码 */
      
              // 1.判断用户名(前端传过来的便是一个 UsernamePasswordToken,将 authenticationToken 转换为 UsernamePasswordToken 便可利用方法将其中的用户名和密码取出)
              UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
      
              String username = token.getUsername();
              System.out.println("token携带的username:" + username);
              userWrapper.eq("userName", username);
              User user = userService.getOne(userWrapper);
      
              if (user == null) {
                  System.out.println("用戶名不存在");
                  return null;
              } else {
                  // 判断密码,第一个参数是返回给.login方法的参数,可以为空;第二个参数是数据库或者模拟的密码;第三个参数是shiro的名字,可以为空
                  return new SimpleAuthenticationInfo("", user.getPassword(), "");
              }
          }
      }
      
    10. 权限限制

      在ShiroConfig,java中编写资源权限过滤

              // 授权过滤器,只有获取相应的授权才能访问
              fileMap.put("/user/add", "perms[user:add]");
      		.....
              // 设置未授权页面
              shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
      
      package com.study.shiro;
      
      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;
      
      /**
       * @author wei斯基
       * Shiro配置类
       * 通过@Bean将方法/类交由spring容器管理,之后利用@Qualifier根据设置的名字(若不设置名字则默认是方法/类名首字母小写)进行调用关联。
       */
      @Configuration
      public class ShiroConfig {
          /**
           * 第三步:创建 ShiroFilterFactoryBean(shiro过滤器)
           */
          @Bean
          public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
              ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
      
              //1.设置安全管理器(关联web安全管理器)
              shiroFilterFactoryBean.setSecurityManager(securityManager);
              //2.添加shiro内置过滤器
              //拦截,Map第一个值为要拦截的地址,第二个值是要使用的过滤器
              Map<String, String> fileMap = new LinkedHashMap<String, String>();
              // 授权过滤器,只有获取相应的授权才能访问
              fileMap.put("/user/add", "perms[user:add]");
              // /xxx地址无需认证即可访问
              fileMap.put("/toLogin", "anon");
              fileMap.put("/loginUser", "anon");
              // /xxx/user地址需要认证才可访问,拦截成功后会跳转到login.jsp页面
              fileMap.put("/user/*", "authc");
              fileMap.put("/main", "authc");
              fileMap.put("/*", "authc");
      
              //修改为自定义的login登陆页面(设置登录网址)
              shiroFilterFactoryBean.setLoginUrl("/toLogin");
              // 设置未授权页面
              shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
      
              // 设置过滤器链定义映射(放置一个用于存储拦截地址和过滤器的map,)
              shiroFilterFactoryBean.setFilterChainDefinitionMap(fileMap);
      
              return shiroFilterFactoryBean;
          }
          /**
           * 第二步:创建 DefaultWebSecurityManager(默认web安全管理器)
           */
          @Bean(name = "securityManager")
          public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
              DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
      //        关联自定义的 Realm
              defaultWebSecurityManager.setRealm(userRealm);
              return defaultWebSecurityManager;
          }
          /**
           * 第一步:创建 Realm 对象,利用@Bean将其交给spring容器管理,以便给安全管理器调用
           */
          @Bean(name = "userRealm")
          public UserRealm getRealm() {
              return new UserRealm();
          }
      }
      

      在 UserController.java 中添加

      @RequestMapping("noAuth")
      public String noAuth() {
          return "noAuth";
      }
      

      编写未授权跳转页面:noAuth.html

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>noAuth</title>
          </head>
          <body>
              <h1>未获取该页面的访问权限</h1>
          </body>
      </html>
      
    11. 执行授权逻辑

      /**
       * 执行授权逻辑,获取授权信息(方法名直译)
       */
      @Override
      protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
          System.out.println("执行授权逻辑");
      
          //给资源进行授权
          SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
      
          //添加资源的授权字符串
          simpleAuthorizationInfo.addStringPermission("user:add");
          
          return simpleAuthorizationInfo;
      }
      
    12. 关联数据库进行动态授权

          /**
           * 执行授权逻辑,获取授权信息(方法名直译)
           */
          @Override
          protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
              System.out.println("执行授权逻辑");
      
              //给资源进行授权
              SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
      
              // 静态,添加资源的授权字符串
              // simpleAuthorizationInfo.addStringPermission("user:add");
              QueryWrapper<User> userWrapper = new QueryWrapper<>();
      
              /* 动态,从数据库取出用户的权限 */
      
              // 获取当前用户
              Subject subject = SecurityUtils.getSubject();
              // getPrincipal是从下方的认证 SimpleAuthenticationInfo 的第一个参数传过来的
              User user = (User) subject.getPrincipal();
              // 将当前用户的用户名设置为查询条件
              QueryWrapper<User> username = userWrapper.eq("username", user.getUsername());
              User dbUser = userService.getOne(username);
      
              //设置授权字符串
              simpleAuthorizationInfo.addStringPermission(dbUser.getPerms());
      
      
              return simpleAuthorizationInfo;
          }
      
      package com.study.shiro;
      
      import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
      import com.study.pojo.User;
      import com.study.service.Impl.UserServiceImpl;
      import com.study.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;
      
      /**
       * @author wei斯基
       */
      public class UserRealm extends AuthorizingRealm {
      
          @Autowired
          UserServiceImpl userService;
      
          /**
           * 执行授权逻辑,获取授权信息(方法名直译)
           */
          @Override
          protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
              System.out.println("执行授权逻辑");
      
              //给资源进行授权
              SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
      
              // 静态,添加资源的授权字符串
              // simpleAuthorizationInfo.addStringPermission("user:add");
              QueryWrapper<User> userWrapper = new QueryWrapper<>();
      
              /* 动态,从数据库取出用户的权限 */
      
              // 获取当前用户
              Subject subject = SecurityUtils.getSubject();
              // getPrincipal是从下方的认证 SimpleAuthenticationInfo 的第一个参数传过来的
              User user = (User) subject.getPrincipal();
              // 将当前用户的用户名设置为查询条件
              QueryWrapper<User> username = userWrapper.eq("username", user.getUsername());
              User dbUser = userService.getOne(username);
      
              //设置授权字符串
              simpleAuthorizationInfo.addStringPermission(dbUser.getPerms());
      
      
              return simpleAuthorizationInfo;
          }
      
          /**
           * 执行认证逻辑,获取认证信息(方法名直译)
           */
          @Override
          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
              System.out.println("执行认证逻辑");
      
              QueryWrapper<User> userWrapper = new QueryWrapper<>();
      
              /* 编写shiro判断逻辑,判断用户名和密码 */
      
              // 1.判断用户名(前端传过来的便是一个 UsernamePasswordToken,将 authenticationToken 转换为 UsernamePasswordToken 便可利用方法将其中的用户名和密码取出)
              UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
      
              String username = token.getUsername();
              System.out.println("token携带的username:" + username);
              userWrapper.eq("userName", username);
              User user = userService.getOne(userWrapper);
      
              if (user == null) {
                  System.out.println("用戶名不存在");
                  return null;
              } else {
                  // 判断密码,第一个参数是返回给.login方法的参数(Principal),可以为空;第二个参数是数据库或者模拟的密码;第三个参数是shiro的名字,可以为空
                  return new SimpleAuthenticationInfo(user, user.getPassword(), "");
              }
          }
      }
      
    13. shiro与thymeleaf的整合

      pom.xml 导入thymeleaf扩展坐标

      <dependency>
          <groupId>com.github.theborakompanioni</groupId>
          <artifactId>thymeleaf-extras-shiro</artifactId>
          <version>2.0.0</version>
      </dependency>
      

      在 ShiroConfig类 中配置 ShiroDialect方法

      /**
       * 配置ShiroDialect,用于thymeleaf和shiro的配合使用
       */
      @Bean
      public ShiroDialect getShiroDialect(){
          return new ShiroDialect();
      }
      

      在页面上使用thymeleaf,main.html

      <!DOCTYPE html>
      <html lang="en" xmlns:th="http://www.thymeleaf.org"
                      xmlns:shiro="http://www.w3.org/1999/xhtml">
          <head>
              <meta charset="UTF-8">
              <title>main</title>
          </head>
          <body>
              <div shiro:hasPermission="user:add">
                  用户添加:<a href="/user/add">add</a>
              </div>
              <div shiro:hasPermission="user:update">
                  用户修改:<a href="/user/update">update</a>
              </div>
          </body>
      </html>
      
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值