Fork me on GitHub

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 }

 

posted @ 2019-08-15 10:10  秋刀  阅读(228)  评论(0编辑  收藏  举报