zoukankan      html  css  js  c++  java
  • shiro延伸

    shiro延伸

    spring-异常处理

    关于异常处理有四种方法:

    第一种:使用SimpleMappingExceptionResolver解析器

      在mvc的配置文件中配置异常处理解析器

     1 异常处理解析器
     2     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
     3         <!--默认的错误视图-->
     4         <property name="defaultErrorView" value="error"/>
     5         <!--异常属性-->
     6         <property name="exceptionAttribute" value="ex">
     7             <!--<props>-->
     8                 <!--<prop key="异常类型1">-->
     9                     <!--error1-->
    10                 <!--</prop>-->
    11                 <!--<prop key="异常类型2">-->
    12                     <!--error2-->
    13                 <!--</prop>-->
    14             <!--</props>-->
    15         </property>
    16     </bean>

    第二种:

      新建一个BaseController类,并在方法前使用@ExceptionHandler注解

     1 package com.aaa.controller;
     2 
     3 /**
     4  * @Author 刘其佳
     5  * 2019/8/14 -- 10:56
     6  * @Version 1.0
     7  */
     8 
     9 import org.apache.shiro.authc.AuthenticationException;
    10 import org.apache.shiro.authz.AuthorizationException;
    11 import org.springframework.ui.Model;
    12 import org.springframework.web.bind.annotation.ExceptionHandler;
    13 
    14 /**
    15  * 异常处理的第二种方法
    16  */
    17 public class BaseController {
    18     @ExceptionHandler(RuntimeException.class)
    19     public String handler1(RuntimeException ex, Model model){
    20         if(ex instanceof AuthenticationException){
    21             System.out.println("处理方案1");
    22             model.addAttribute("ex",ex);
    23             return "error";
    24         }else if(ex instanceof AuthorizationException){
    25             System.out.println("处理方案2");
    26             model.addAttribute("ex",ex);
    27             return "error";
    28         }
    29         return "error";
    30     }
    31 }

      控制器继承BaseController

     1 package com.aaa.controller;
     2 
     3 import com.aaa.service.UserService;
     4 import org.apache.shiro.SecurityUtils;
     5 import org.apache.shiro.authc.*;
     6 import org.apache.shiro.authz.annotation.RequiresPermissions;
     7 import org.apache.shiro.subject.Subject;
     8 import org.slf4j.Logger;
     9 import org.slf4j.LoggerFactory;
    10 import org.springframework.beans.factory.annotation.Autowired;
    11 import org.springframework.stereotype.Controller;
    12 import org.springframework.web.bind.annotation.*;
    13 
    14 import java.util.List;
    15 
    16 /**
    17  * @Author 刘其佳
    18  * 2019/8/12 -- 16:43
    19  * @Version 1.0
    20  */
    21 @Controller
    22 //@RequestMapping("/user")
    23 public class UserController extends BaseController{
    24     public class UserController{
    25     @Autowired
    26     private  UserService userService;
    27     //获取日志对象
    28     private static final transient Logger log = LoggerFactory.getLogger(UserController.class);
    29 
    30     @RequestMapping("/login")
    31     public String login(String username,String password){
    32         //创建subject
    33         Subject currentUser= SecurityUtils.getSubject();
    34         // currentUser.isAuthenticated()当前用户是否被认证
    35         // 如果当前用户被认证了,说明用户还是处于登录状态
    36         if (!currentUser.isAuthenticated()) {
    37             //用户名密码令牌:将表单中的用户名和密码封装进token中
    38             UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    39             //记住我
    40 //            token.setRememberMe(true);
    41             try {
    42                 // 调用subject中的login方法来进行匹配用户是否可以登录成功
    43                 // login方法的参数需要接收shiro的UsernamePasswordToken类型
    44                 currentUser.login(token);//找到xml文件中id=shiroFilter对应的realm
    45             } catch (UnknownAccountException uae) {//账号不存在
    46                 log.info("There is no user with username of " + token.getPrincipal());
    47                 throw new UnknownAccountException("账号不存在");
    48 //                return "login";
    49             } catch (IncorrectCredentialsException ice) {//密码错误
    50                 log.info("Password for account " + token.getPrincipal() + " was incorrect!");
    51                 throw new IncorrectCredentialsException("密码错误");
    52 //                return "login";
    53             } catch (LockedAccountException lae) {//账号锁死
    54                 log.info("The account for username " + token.getPrincipal() + " is locked.  " +
    55                         "Please contact your administrator to unlock it.");
    56             }
    57             catch (AuthenticationException ae) {
    58             }
    59         }
    60         return "front/ok";
    61     }
    62 
    63     @GetMapping("/delete/{id}")
    64     @ResponseBody
    65     @RequiresPermissions("emp/delete")
    66     public boolean delete(@PathVariable("id") Integer id){
    67         int result=userService.deleteByPrimaryKey(id);
    68         return result>0?true:false;
    69     }
    70 }

    第三种:使用 @ControllerAdvice+ @ ExceptionHandler 注解 (推荐使用)

      同步方式:

     1 package com.aaa.controller;
     2 
     3 import com.aaa.entity.Result;
     4 import org.apache.shiro.authc.AuthenticationException;
     5 import org.apache.shiro.authz.AuthorizationException;
     6 import org.springframework.ui.Model;
     7 import org.springframework.web.bind.annotation.ControllerAdvice;
     8 import org.springframework.web.bind.annotation.ExceptionHandler;
     9 import org.springframework.web.bind.annotation.ResponseBody;
    10 
    11 /**
    12  * @Author 刘其佳
    13  * 2019/8/14 -- 11:08
    14  * @Version 1.0
    15  */
    16 
    17 //处理异常的第三种方法之同步方式
    18     @ControllerAdvice
    19 public class ExceptionController {
    20     @ExceptionHandler(RuntimeException.class)
    21     public String handler1(RuntimeException ex, Model model){
    22         if(ex instanceof AuthenticationException){
    23             System.out.println("处理方案1");
    24             model.addAttribute("ex",ex);
    25             return "error";
    26         }else if(ex instanceof AuthorizationException){
    27             System.out.println("处理方案2");
    28             model.addAttribute("ex",ex);
    29             return "error";
    30         }
    31         return "error";
    32     }

      异步方式:返回的是json数据

      步骤:1、自定义实体类型(状态码,错误信息)

         2、处理异常时返回该类型的数据

    实体类:

     1 package com.aaa.entity;
     2 
     3 import lombok.AllArgsConstructor;
     4 import lombok.Data;
     5 import lombok.NoArgsConstructor;
     6 import lombok.ToString;
     7 
     8 /**
     9  * @Author 刘其佳
    10  * 2019/8/14 -- 11:12
    11  * @Version 1.0
    12  */
    13 @Data
    14 @AllArgsConstructor
    15 @NoArgsConstructor
    16 @ToString
    17 public class Result {
    18     private Integer statusCode;
    19     private String message;
    20 }

    此处说明一下,该实体类使用了lombok的注解:

      首先导入Lombok的jar包:

    1     <!--lombok:简化实体类的编写-->
    2     <dependency>
    3       <groupId>org.projectlombok</groupId>
    4       <artifactId>lombok</artifactId>
    5       <version>1.18.8</version>
    6     </dependency>

      然后在setting中的plugins下载Lombok的插件

    异常处理:

     1 //处理异常的第三种方法之异步方式
     2     @ExceptionHandler(RuntimeException.class)
     3     @ResponseBody
     4     public Result handler1(RuntimeException ex){
     5         Result result=new Result();
     6         if(ex instanceof AuthenticationException){
     7             result.setStatusCode(501);
     8             result.setMessage("认证异常:"+ex.getMessage());
     9             System.out.println("处理方案1");
    10         }else if(ex instanceof AuthorizationException){
    11             result.setStatusCode(502);
    12             result.setMessage("授权异常:"+ex.getMessage());
    13             System.out.println("处理方案2");
    14         }
    15         return result;
    16     }

    第四种方法

      实现HandlerExceptionResolver接口


    定时任务

     借助Scheduled来实现定时任务

    1、配置注解

    14     <!--启用定时任务-->
    5     <task:annotation-driven/>

     2、创建定时任务

     1 package com.aaa.controller;
     2 
     3 import org.springframework.scheduling.annotation.Scheduled;
     4 import org.springframework.stereotype.Controller;
     5 
     6 /**
     7  * @Author 刘其佳
     8  * 2019/8/14 -- 17:00
     9  * @Version 1.0
    10  */
    11 
    12 @Controller
    13 public class SchController {
        //每隔5秒执行一次
    14 @Scheduled(cron = "0/5 * * * * ?") 15 public static void task() { 16 System.out.println("每一个不曾起舞的日子,都是对生命的辜负"); 17 } 18 }

     

    对于Scheduled属性的说明:

    字段允许值允许的特殊符号
    0-59 ,-*/
    0-59 ,-*/
    小时 0-23 ,-*/
    日期 1-31 ,-*?/LWC
    月份 1-12 ,-*/
    星期 0-7或SUN-SAT 0 7是SUN ,-*?/LC#

     特殊符号的释义如下:

    特殊符号代表含义
    , 枚举
    - 区间
    * 任意
    / 步长
    ? 日/星期冲突匹配
    L 最后
    W 工作日
    C 和Calendar联系后计算过的值
    # 星期 4#2 第2个星期四

     

    示例:

      0 0 0 * * * -- 每天零时执行一次
      0 0/15 14,18 * * ? -- 每天14点整和18点整,每隔15分钟执行一次
      0 15 10 ? * 1-6 -- 每个月的周一到周六 10:15分执行一次
      0 0 2 ? * 6L -- 每个月的最后一个周六凌晨2点执行一次
      0 0 2 LW * ? -- 每个月的最后一个工作日凌晨2点执行一次
      0 0 2-4 ? * 1#1 -- 每个月的第一个周一凌晨2点到4点期间,每个整点都执行一次


    补充注解:

     关于@ResponseBody和@RequestBody的区别

    正常情况下,在控制成的方法一般返回字符串,然后根据配置文件中相关配置,为返回的字符串加上响应的前缀和后缀,组成一个路径;

    但是,当在方法前加上@responseBody,返回的是json格式的数据,并不能跳转。即@ResponseBody:将数据转换成json并输出到响应流中

    @ResponseBody:

    1 @GetMapping("/{empno}")
    2     @ResponseBody
    3     public Emp queryById( @PathVariable("empno") Integer empno){
    4         return empService.selectByPrimaryKey(empno);
    5     }

    而@ResponseBody:将请求中的json数据转换成Java对象,一般用来处理复杂类型的数据;

    @ResponseBody:

     1 //    requestBody测试
     2     function test1() {
     3         //数组
     4         var emps=[];
     5         emps.push({job:"经理1",hiredate:"2018-1-1"});
     6         emps.push({job:"经理2",hiredate:"2018-1-2"});
     7         emps.push({job:"经理3",hiredate:"2018-1-3"});
     8         $.ajax({
     9             type:"post",
    10             url:"${pageContext.request.contextPath}/emp/test1",
    11             data:JSON.stringify(emps),//转成json的字符串传过去
    12             contentType:'application/json',//内容的类型是:json数据
    13             success:function (data) {
    14                 alert(data);
    15             },
    16             error:function (msg) {
    17                 alert('test1函数发生错误:'+msg);
    18             }
    19         })
    20     }
    1 //在控制层的方法中:
    2     @RequestMapping("/test1")
    3     @ResponseBody
    4     public String test1(@RequestBody List<Emp> emps){//借用@RequestBody将传过来的json转换成Emp对象类型
    5         System.out.println(emps);
    6         return "ok";
    7     }

     在进行@RequestBody的测试中,Ajax中将一个Emp对象转换成json格式,再作为参数传递:

    注意书写:1、JSON.stringify(emps):转换成json格式的字符串类型

         2、contentType:'application/json':声明一下内容的类型为json格式数据


    shiro--rememberMe

     在shiro中有一个属性为setRememberMe();即将当前登录用户的信息保存进cookie中;然后可以在shiro的配置文件中指定

    如果将信息保存进cookie中了,关闭浏览器再次打开次地址,可以在不登录的情况下访问定义为user的路径(关闭浏览器不将cookie清空),

    但是如果注销了当前用户的话(在shiro的配置文件里可以定义某路径的属性为logout,即为注销),那么会讲cookie清空。

      先在shiro的配置文件中配置cookie

    <!--+++++++++++++++++ 配置cookies -++++++++++++++++++-->
        <bean id="rememberCookies" class="org.apache.shiro.web.servlet.SimpleCookie">
            <constructor-arg value="rememberMe"></constructor-arg>
            <property name="httpOnly" value="true"></property>
            <property name="maxAge" value="#{60*60*24}"></property>
        </bean>
        <!--++++++++++++++++配置记住我管理器+++++++++++++++++++++-->
        <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
            <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('6ZmI6I2j5Y+R5aSn5ZOlAA==')}"/>
            <property name="cookie" ref="rememberCookies"/>
        </bean>

     在shiro中的安全管理器中进行声明

     1 <!--+++++++++++++++++++安全管理器+++++++++++++++-->
     2     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
     3         <!--缓存管理器-->
     4         <property name="cacheManager" ref="cacheManager"/>
     5 
     6         <!--会话的模式;native:本地-->
     7         <property name="sessionMode" value="native"/>
     8 
     9         <!--配置realm-->
    10         <property name="realm" ref="myRealm"/>
    11 
    12         <!--rememberMe管理器-->
    13         <property name="rememberMeManager" ref="rememberMeManager"/>
    14     </bean>

     定义路径

     1 <!--filterChainDefinitions:过滤器的规则声明-->
     2         <property name="filterChainDefinitions">
     3             <value>
     4                 <!--对某些路径进行何种方式的验证,存在先后顺序,不会覆盖,有重复声明的话按照先声明的来-->
     5                 <!--anon:匿名过滤器,不需要登录     authc:需要进行认证登录
     6                     uesr:使用了rememberMe后可以直接进入此路径-->
     7                 /index.jsp = anon
     8                 /emp/delete = anon
     9                 /logout=logout
    10                 /*.jar = anon
    11                 /common/**=anon
    12                 /static/** =anon
    13                 /emp/**=authc
    14                 /admin/**=authc
    15                 /user1/**=user
    16             </value>
    17         </property>
     1 package com.aaa.controller;
     2 
     3 import com.aaa.service.UserService;
     4 import org.apache.shiro.SecurityUtils;
     5 import org.apache.shiro.authc.*;
     6 import org.apache.shiro.authz.annotation.RequiresPermissions;
     7 import org.apache.shiro.subject.Subject;
     8 import org.slf4j.Logger;
     9 import org.slf4j.LoggerFactory;
    10 import org.springframework.beans.factory.annotation.Autowired;
    11 import org.springframework.stereotype.Controller;
    12 import org.springframework.web.bind.annotation.*;
    13 
    14 import java.util.List;
    15 
    16 /**
    17  * @Author 刘其佳
    18  * 2019/8/12 -- 16:43
    19  * @Version 1.0
    20  */
    21 @Controller
    22 //@RequestMapping("/user")
    24     public class UserController{
    25     @Autowired
    26     private  UserService userService;
    27     //获取日志对象
    28     private static final transient Logger log = LoggerFactory.getLogger(UserController.class);
    29 
    30     @RequestMapping("/login")
    31     public String login(String username,String password,String remFlag){
    32         //创建subject
    33         Subject currentUser= SecurityUtils.getSubject();
    34         // currentUser.isAuthenticated()当前用户是否被认证
    35         // 如果当前用户被认证了,说明用户还是处于登录状态
    36         if (!currentUser.isAuthenticated()) {
    37             //用户名密码令牌:将表单中的用户名和密码封装进token中
    38             UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    39             //记住我
    40             41                 token.setRememberMe(true);
    42 43             try {
    44                 // 调用subject中的login方法来进行匹配用户是否可以登录成功
    45                 // login方法的参数需要接收shiro的UsernamePasswordToken类型
    46                 currentUser.login(token);//找到xml文件中id=shiroFilter对应的realm
    47             } catch (UnknownAccountException uae) {//账号不存在
    48                 log.info("There is no user with username of " + token.getPrincipal());
    49                 throw new UnknownAccountException("账号不存在");
    50 //                return "login";
    51             } catch (IncorrectCredentialsException ice) {//密码错误
    52                 log.info("Password for account " + token.getPrincipal() + " was incorrect!");
    53                 throw new IncorrectCredentialsException("密码错误");
    54 //                return "login";
    55             } catch (LockedAccountException lae) {//账号锁死
    56                 log.info("The account for username " + token.getPrincipal() + " is locked.  " +
    57                         "Please contact your administrator to unlock it.");
    58                 throw new LockedAccountException("账号锁死");
    59             }
    60             catch (AuthenticationException ae) {
    61                 log.info(("The account form username"+token.getPrincipal()+"is locked!"));
    62                 throw new AuthenticationException("账号锁死");
    63             }
    64         }
    65         return "front/ok";
    66     }
    67 
    68     @GetMapping("/delete/{id}")
    69     @ResponseBody
    70     @RequiresPermissions("emp/delete")
    71     public boolean delete(@PathVariable("id") Integer id){
    72         int result=userService.deleteByPrimaryKey(id);
    73         return result>0?true:false;
    74     }
    75 }

    shiro的多次登录错误下账号锁死

    思路:利用缓存记录登录的信息,如果错误次数达到指定数,就抛出异常

    实现:

    1、在资源文件目录下新建一个定义缓存的xml:ehcache.xml,定义缓存的相关信息

      正常情况下的默认缓存是:

    1 <!-- 默认缓存 -->
    2     <defaultCache
    3             maxEntriesLocalHeap="10000"
    4             eternal="false"
    5             timeToIdleSeconds="120"
    6             timeToLiveSeconds="120"
    7             maxEntriesLocalDisk="10000000"
    8             diskExpiryThreadIntervalSeconds="120"
    9             memoryStoreEvictionPolicy="LRU"/>

      自定义缓存

    1  <!-- 登录记录缓存 锁定10分钟 -->
    2     <cache name="passwordRetryCache"
    3            maxEntriesLocalHeap="2000"
    4            eternal="false"
    5            timeToIdleSeconds="360"
    6            timeToLiveSeconds="360"
    7            overflowToDisk="false"
    8            statistics="true">
    9     </cache>

    以上属性的含义:

    maxEntriesLocalHeap:是用来限制当前缓存在堆内存上所能保存的最大元素数量
    eternal:false 设定缓存的elemen是否永远不过期
    timeToLiveSeconds:对象存活时间,指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值为0,表示一直可以访问。(单位:秒)
    timeToIdleSeconds:对象空闲时,指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值为0。(单位:秒)
    新定义一个类
     1 package com.aaa.credentials;
     2 
     3 import com.aaa.entity.Result;
     4 import org.apache.shiro.authc.AuthenticationException;
     5 import org.apache.shiro.authc.AuthenticationInfo;
     6 import org.apache.shiro.authc.AuthenticationToken;
     7 import org.apache.shiro.authc.ExcessiveAttemptsException;
     8 import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
     9 import org.apache.shiro.cache.Cache;
    10 import org.apache.shiro.cache.CacheManager;
    11 
    12 import java.util.concurrent.atomic.AtomicInteger;
    13 
    14 public class MyMatcher extends HashedCredentialsMatcher {
    15 
    16     //Map:key,value
    17     //key:存用户名 value:次数
    18     private Cache<String, AtomicInteger> passwordCache;
    19 
    20     public MyMatcher(CacheManager cacheManager) {
    21         this.passwordCache = cacheManager.getCache("passwordRetryCache");
    22     }
    23 
    24     //密码匹配
    25     @Override
    26     public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
    27         //获取用户名
    28         String username= (String) token.getPrincipal();
    29         //先去缓存中查找是否有该信息
    30         AtomicInteger retryCount= passwordCache.get(username);
    31         //第一次是null
    32         if(retryCount==null){
    33             //初始话:0
    34             retryCount=new AtomicInteger(0);
    35             //存入缓存中
    36             passwordCache.put(username,retryCount);
    37         }
    38         //在retryCount上增加1,并获取该值,当第3次仍然输入错误则锁死账号
    39         if(retryCount.incrementAndGet()>2){
    40             throw new ExcessiveAttemptsException("该账号已锁定");
    41         }
    42         //密码匹配
    43         boolean matcher=super.doCredentialsMatch(token,info);
    44         //如果登录成功
    45         if(matcher){
    46             //清空缓存数据
    47             passwordCache.remove(username);
    48         }
    49         return matcher;
    50     }
    51 }

    控制类中

     1 package com.aaa.controller;
     2 
     3 import com.aaa.service.UserService;
     4 import org.apache.shiro.SecurityUtils;
     5 import org.apache.shiro.authc.*;
     6 import org.apache.shiro.authz.annotation.RequiresPermissions;
     7 import org.apache.shiro.subject.Subject;
     8 import org.slf4j.Logger;
     9 import org.slf4j.LoggerFactory;
    10 import org.springframework.beans.factory.annotation.Autowired;
    11 import org.springframework.stereotype.Controller;
    12 import org.springframework.web.bind.annotation.*;
    13 
    14 import java.util.List;
    15 
    16 /**
    17  * @Author 刘其佳
    18  * 2019/8/12 -- 16:43
    19  * @Version 1.0
    20  */
    21 @Controller
    22 //@RequestMapping("/user")
    23 //public class UserController extends BaseController{
    24     public class UserController{
    25     @Autowired
    26     private  UserService userService;
    27     //获取日志对象
    28     private static final transient Logger log = LoggerFactory.getLogger(UserController.class);
    29 
    30     @RequestMapping("/login")
    31     public String login(String username,String password,String remFlag){
    32         //创建subject
    33         Subject currentUser= SecurityUtils.getSubject();
    34         // currentUser.isAuthenticated()当前用户是否被认证
    35         // 如果当前用户被认证了,说明用户还是处于登录状态
    36         if (!currentUser.isAuthenticated()) {
    37             //用户名密码令牌:将表单中的用户名和密码封装进token中
    38             UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    39             //记住我(如果有值,就存入cookie)
    40             if(remFlag.equals("1")){
    41                 token.setRememberMe(true);
    42             }
    43             try {
    44                 // 调用subject中的login方法来进行匹配用户是否可以登录成功
    45                 // login方法的参数需要接收shiro的UsernamePasswordToken类型
    46                 currentUser.login(token);//找到xml文件中id=shiroFilter对应的realm
    47             } catch (UnknownAccountException uae) {//账号不存在
    48                 log.info("There is no user with username of " + token.getPrincipal());
    49                 throw new UnknownAccountException("账号不存在");
    50 //                return "login";
    51             } catch (IncorrectCredentialsException ice) {//密码错误
    52                 log.info("Password for account " + token.getPrincipal() + " was incorrect!");
    53                 throw new IncorrectCredentialsException("密码错误");
    54 //                return "login";
    55             } catch (LockedAccountException lae) {//账号锁死
    56                 log.info("The account for username " + token.getPrincipal() + " is locked.  " +
    57                         "Please contact your administrator to unlock it.");
    58                 throw new LockedAccountException("账号锁死");
    59             }
    60             catch (AuthenticationException ae) {
    61                 log.info(("The account form username"+token.getPrincipal()+"is locked!"));
    62                 throw new AuthenticationException("账号锁死");
    63             }
    64         }
    65         return "front/ok";
    66     }
    67 
    68     @GetMapping("/delete/{id}")
    69     @ResponseBody
    70     @RequiresPermissions("emp/delete")
    71     public boolean delete(@PathVariable("id") Integer id){
    72         int result=userService.deleteByPrimaryKey(id);
    73         return result>0?true:false;
    74     }
    75 }

    realm:

     1 package com.aaa.realm;
     2 
     3 import com.aaa.service.UserService;
     4 import org.apache.shiro.authc.*;
     5 import org.apache.shiro.crypto.hash.SimpleHash;
     6 import org.apache.shiro.realm.AuthenticatingRealm;
     7 import org.apache.shiro.util.ByteSource;
     8 import org.springframework.beans.factory.annotation.Autowired;
     9 
    10 /**
    11  * @Author 刘其佳
    12  * 2019/8/12 -- 16:28
    13  * @Version 1.0
    14  */
    15 
    16 
    17 public class MyRealm extends AuthenticatingRealm {
    18 
    19     @Autowired
    20     private UserService userService;
    21 
    22     /**
    23      * @param authenticationToken:封装的身份信息(表单中传过来的)
    24      * @return
    25      * @throws AuthenticationException
    26      */
    27     @Override
    28     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    29         /**
    30          * 1、获取subject传递过来的token
    31          * 2、根据token的用户名找到数据库中对应的密码
    32          * 3、返回认证对象
    33          */
    34         UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) authenticationToken;
    35         //获取令牌中的用户名
    36         String username=usernamePasswordToken.getUsername();
    37         //连接数据库根据用户名查询密码
    38         String password=userService.selectByName(username);
    39 //        加盐
    40         ByteSource salt=ByteSource.Util.bytes(username);
    41         //返回认证信息:最后一个参数是当前realm的名字,两种写法
    42 //        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,password,"MyRealm");
    43         SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,password,salt,getName());
    44 
    45 
    46         return info;
    47     }
    48 
    49     public static void main(String[] args){
    50         //盐:salt
    51         String username="admin";
    52         String password="123456";
    53         ByteSource salt=ByteSource.Util.bytes(username);
    54         SimpleHash simpleHash=new SimpleHash("MD5",password,salt);
    55         String str=simpleHash.toHex();
    56         System.out.println(str);
    57     }
    58 }
    乾坤未定,你我皆是黑马
  • 相关阅读:
    PHP实现无限极分类
    html2canvas生成并下载图片
    一次线上问题引发的过程回顾和思考,以更换两台服务器结束
    Intellij IDEA启动项目报Command line is too long. Shorten command line for XXXApplication or also for
    mq 消费消息 与发送消息传参问题
    idea 创建不了 java 文件
    Java switch 中如何使用枚举?
    Collections排序
    在idea 设置 git 的用户名
    mongodb添加字段和创建自增主键
  • 原文地址:https://www.cnblogs.com/liuqijia/p/11355441.html
Copyright © 2011-2022 走看看