Shiro认证、盐加密

Shiro认证、盐加密

一、

 1.1 导入pom.xml

1.2.5

 


    
      org.apache.shiro
      shiro-core
      ${shiro.version}
    
    
    
      org.apache.shiro
      shiro-web
      ${shiro.version}
    
    
      org.apache.shiro
      shiro-spring
      ${shiro.version}
    

 

1.2 配置web.xml

 1  
 2   
 3     shiroFilter
 4     org.springframework.web.filter.DelegatingFilterProxy
 5     
 6       
 7       targetFilterLifecycle
 8       true
 9     
10   
11   
12     shiroFilter
13     /*
14   

 

 1.3   从数据库表逆向生成对应的model、mapper类

 

二、实践、操作

 2.1 ShiroUserMapper

 1 package com.jy.mapper;
 2 
 3 import com.jy.model.ShiroUser;
 4 import org.apache.ibatis.annotations.Param;
 5 import org.springframework.stereotype.Repository;
 6 
 7 @Repository
 8 public interface ShiroUserMapper {
 9     int deleteByPrimaryKey(Integer userid);
10 
11     int insert(ShiroUser record);
12 
13     int insertSelective(ShiroUser record);
14 
15     ShiroUser selectByPrimaryKey(Integer userid);
16 
17     int updateByPrimaryKeySelective(ShiroUser record);
18 
19     int updateByPrimaryKey(ShiroUser record);
20 
21     ShiroUser queryByName(@Param("uname")String uname);
22 
23 }

 

2.2 ShiroUserMapper.xml


  1 
  2 
  3 
  4   
  5     
  6       
  7       
  8       
  9       
 10       
 11     
 12   
 13   
 14     userid, username, PASSWORD, salt, createdate
 15   
 16   
 22   
 23     delete from t_shiro_user
 24     where userid = #{userid,jdbcType=INTEGER}
 25   
 26   
 27     insert into t_shiro_user (userid, username, PASSWORD, 
 28       salt, createdate)
 29     values (#{userid,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
 30       #{salt,jdbcType=VARCHAR}, #{createdate,jdbcType=TIMESTAMP})
 31   
 32   
 33     insert into t_shiro_user
 34     
 35       
 36         userid,
 37       
 38       
 39         username,
 40       
 41       
 42         PASSWORD,
 43       
 44       
 45         salt,
 46       
 47       
 48         createdate,
 49       
 50     
 51     
 52       
 53         #{userid,jdbcType=INTEGER},
 54       
 55       
 56         #{username,jdbcType=VARCHAR},
 57       
 58       
 59         #{password,jdbcType=VARCHAR},
 60       
 61       
 62         #{salt,jdbcType=VARCHAR},
 63       
 64       
 65         #{createdate,jdbcType=TIMESTAMP},
 66       
 67     
 68   
 69   
 70     update t_shiro_user
 71     
 72       
 73         username = #{username,jdbcType=VARCHAR},
 74       
 75       
 76         PASSWORD = #{password,jdbcType=VARCHAR},
 77       
 78       
 79         salt = #{salt,jdbcType=VARCHAR},
 80       
 81       
 82         createdate = #{createdate,jdbcType=TIMESTAMP},
 83       
 84     
 85     where userid = #{userid,jdbcType=INTEGER}
 86   
 87   
 88     update t_shiro_user
 89     set username = #{username,jdbcType=VARCHAR},
 90       PASSWORD = #{password,jdbcType=VARCHAR},
 91       salt = #{salt,jdbcType=VARCHAR},
 92       createdate = #{createdate,jdbcType=TIMESTAMP}
 93     where userid = #{userid,jdbcType=INTEGER}
 94   
 95 
 96   
102 
103 
104 

 

2.3 Service

 1 package com.jy.service;
 2 
 3 import com.jy.model.ShiroUser;
 4 import org.apache.ibatis.annotations.Param;
 5 
 6 public interface ShiroUserService {
 7 
 8     ShiroUser queryByName(@Param("uname")String uname);
 9 
10     int insert(ShiroUser record);
11 
12 }

 

2.4 Service.impl


package com.jy.service.impl;

import com.jy.mapper.ShiroUserMapper;
import com.jy.model.ShiroUser;
import com.jy.service.ShiroUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("shiroUserService")
public class ShiroUserServiceImpl implements ShiroUserService {
    @Autowired
    private ShiroUserMapper shiroUserMapper;

    @Override
    public ShiroUser queryByName(String uname) {
        return shiroUserMapper.queryByName(uname);
    }

    @Override
    public int insert(ShiroUser record) {
        return shiroUserMapper.insert(record);
    }
}

 

2.5 MyRealm

1 package com.jy.shiro;
 2 
 3 import com.jy.mapper.ShiroUserMapper;
 4 import com.jy.model.ShiroUser;
 5 import com.jy.service.ShiroUserService;
 6 import lombok.ToString;
 7 import org.apache.shiro.authc.AuthenticationException;
 8 import org.apache.shiro.authc.AuthenticationInfo;
 9 import org.apache.shiro.authc.AuthenticationToken;
10 import org.apache.shiro.authc.SimpleAuthenticationInfo;
11 import org.apache.shiro.authz.AuthorizationInfo;
12 import org.apache.shiro.realm.AuthorizingRealm;
13 import org.apache.shiro.subject.PrincipalCollection;
14 import org.apache.shiro.util.ByteSource;
15 import org.springframework.stereotype.Component;
16 
17 
18 /*
19 替换掉.ini的文件,所有用户的身份数据源
20  */
21 public class MyRealm extends AuthorizingRealm {
22     private ShiroUserService shiroUserService;
23 
24     public ShiroUserService getShiroUserService() {
25         return shiroUserService;
26     }
27 
28     public void setShiroUserService(ShiroUserService shiroUserService) {
29         this.shiroUserService = shiroUserService;
30     }
31 
32     /*
33         授权的方法
34          */
35     @Override
36     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
37         return null;
38     }
39 
40     /*
41     身份认证的方法
42      */
43     @Override
44     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
45         String uname = authenticationToken.getPrincipal().toString();
46         String pwd = authenticationToken.getCredentials().toString();
47         ShiroUser shiroUser = shiroUserService.queryByName(uname);
48 
49         AuthenticationInfo info = new SimpleAuthenticationInfo(
50                 shiroUser.getUsername(),
51                 shiroUser.getPassword(),
52                 ByteSource.Util.bytes(shiroUser.getSalt()),
53                 this.getName()
54                 );
55 
56         return info;
57     }
58 
59 }

2.6 applicationContext-shiro.xml


 1 
 2 
 5 
 6     
 7     
 8         
 9         
10         
11         
12         
13         
14             
15                 
16                 
17                 
18                 
19                 
20                 
21             
22         
23     
24 
25     
26     
27         
28     
29 
30     
31     
32         
33         
34         
35         
36         
37         
38         
39         
40         
41         
42             
43                 
47                 
48                 
49                 
50                 /user/login=anon
51                 /user/updatePwd.jsp=authc
52                 /admin/*.jsp=roles[admin]
53                 /user/teacher.jsp=perms["user:update"]
54                 
64             
65         
66     
67 
68     
69     
70 

 

注册、登录

2.7 ShiroUserController

 1 package com.jy.controller;
 2 
 3 
 4 import com.jy.model.ShiroUser;
 5 import com.jy.service.ShiroUserService;
 6 import com.jy.util.PasswordHelper;
 7 import org.apache.shiro.SecurityUtils;
 8 import org.apache.shiro.authc.AuthenticationException;
 9 import org.apache.shiro.authc.UsernamePasswordToken;
10 import org.apache.shiro.subject.Subject;
11 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.stereotype.Controller;
13 import org.springframework.web.bind.annotation.RequestMapping;
14 
15 import javax.servlet.http.HttpServletRequest;
16 import javax.servlet.http.HttpServletResponse;
17 
18 @Controller
19 public class ShiroUserController {
20 
21     @Autowired
22     private ShiroUserService shiroUserService;
23 
24 
25     /*
26     用户登录
27      */
28     @RequestMapping("/login")
29     public String login(HttpServletRequest req){
30         Subject subject = SecurityUtils.getSubject();
31         String uname = req.getParameter("username");
32         String pwd = req.getParameter("password");
33         UsernamePasswordToken token = new UsernamePasswordToken(uname, pwd);
34 
35         try {
36 //            这里会跳转到MyRealm中的认证方法
37             subject.login(token);
38             req.getSession().setAttribute("username", uname);
39             return "main";
40 
41         } catch (AuthenticationException e) {
42             req.setAttribute("message","用户名或密码错误!!!");
43             return "login";
44         }
45 
46     }
47 
48     /*
49     退出登录
50      */
51     @RequestMapping("/logout")
52     public String logout(HttpServletRequest req) {
53         Subject subject = SecurityUtils.getSubject();
54         subject.logout();
55         return "redirect:/login.jsp";
56     }
57 
58 
59     /*
60     用户注册
61      */
62     @RequestMapping("/register")
63     public String register(HttpServletRequest req, HttpServletResponse resp){
64         String uname = req.getParameter("username");
65         String pwd = req.getParameter("password");
66         String salt = PasswordHelper.createSalt();
67         String credentials = PasswordHelper.createCredentials(pwd, salt);
68 
69         ShiroUser shiroUser=new ShiroUser();
70         shiroUser.setUsername(uname);
71         shiroUser.setPassword(credentials);
72         shiroUser.setSalt(salt);
73         int insert = shiroUserService.insert(shiroUser);
74         if(insert>0){
75             req.setAttribute("message","注册成功");
76             return "login";
77         }
78         else{
79             req.setAttribute("message","注册失败");
80             return "register";
81         }
82 }
83 
84 
85 
86 }

 

三、盐加密的工具类

3.1 PasswordHelper


 1 package com.jy.util;
 2 
 3 import org.apache.shiro.crypto.RandomNumberGenerator;
 4 import org.apache.shiro.crypto.SecureRandomNumberGenerator;
 5 import org.apache.shiro.crypto.hash.SimpleHash;
 6 
 7 public class PasswordHelper {
 8 
 9     /**
10      * 随机数生成器
11      */
12     private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
13 
14     /**
15      * 指定hash算法为MD5
16      */
17     private static final String hashAlgorithmName = "md5";
18 
19     /**
20      * 指定散列次数为1024次,即加密1024次
21      */
22     private static final int hashIterations = 1024;
23 
24     /**
25      * true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储
26      */
27     private static final boolean storedCredentialsHexEncoded = true;
28 
29     /**
30      * 获得加密用的盐
31      *
32      * @return
33      */
34     public static String createSalt() {
35         return randomNumberGenerator.nextBytes().toHex();
36     }
37 
38     /**
39      * 获得加密后的凭证
40      *
41      * @param credentials 凭证(即密码)
42      * @param salt        盐
43      * @return
44      */
45     public static String createCredentials(String credentials, String salt) {
46         SimpleHash simpleHash = new SimpleHash(hashAlgorithmName, credentials,
47                 salt, hashIterations);
48         return storedCredentialsHexEncoded ? simpleHash.toHex() : simpleHash.toBase64();
49     }
50 
51 
52     /**
53      * 进行密码验证
54      *
55      * @param credentials        未加密的密码
56      * @param salt               盐
57      * @param encryptCredentials 加密后的密码
58      * @return
59      */
60     public static boolean checkCredentials(String credentials, String salt, String encryptCredentials) {
61         return encryptCredentials.equals(createCredentials(credentials, salt));
62     }
63 
64     public static void main(String[] args) {
65         //盐
66         String salt = createSalt();
67         System.out.println(salt);
68         System.out.println(salt.length());
69         //凭证+盐加密后得到的密码
70         String credentials = createCredentials("123", salt);
71         System.out.println(credentials);
72         System.out.println(credentials.length());
73         boolean b = checkCredentials("123", salt, credentials);
74         System.out.println(b);
75     }
76 }

 

页面展示

3.2 login.jsp


 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 
 3 
 4     Title
 5 
 6 
 7     

用户登陆

8
${message}
9
10 帐号:
11 密码:
12 13 14
15 16

 

3.3 register.jsp


 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 
 3 
 4     Title
 5 
 6 
 7 

用户注册

8
${message}
9
10 帐号:
11 密码:
12 13 14
15 16

 

3.4 main.jsp

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 <%@taglib prefix="r" uri="http://shiro.apache.org/tags" %>
 3 
 4 
 5     Title
 6 
 7 
 8 

主界面<%=System.currentTimeMillis()%>,欢迎您:[${sessionScope.username}]

9 33 58 59

 

 

Shiro认证、盐加密_第1张图片

你可能感兴趣的:(Shiro认证、盐加密)