Shiro认证及加盐加密( 二 )


6、自定义域 继承域
package com.zjy.shiro;import com.zjy.biz.UserBiz;import com.zjy.model.User;import sun.net.www.protocol.http.AuthenticationInfo;/*** @author zjy* @site Bi8boYin* @company xxx公司* @create2022-08-25 14:12*/public class MyRealm extends AuthorizingRealm {private UserBiz userBiz;public UserBiz getUserBiz() {return userBiz;}public void setUserBiz(UserBiz userBiz) {this.userBiz = userBiz;}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("身份认证...");String username = token.getPrincipal().toString();String password = token.getCredentials().toString();User user = userBiz.queryUserByUserName(username);//拿到数据库中的用户信息,放入token凭证中,用于controler进行对比AuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),ByteSource.Util.bytes(user.getSalt()),this.getName());return info;}}
7、配置与shiro的集成文件
/user/login=anon/user/updatePwd.jsp=authc/admin/*.jsp=roles[admin]/user/teacher.jsp=perms["user:update"]
8、编写登陆的控制层代码
package com.zjy.controller;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Controllerpublic class LoginController {@RequestMapping("/login")public String login(HttpServletRequest req, HttpServletResponse resp){String username = req.getParameter("username");String password = req.getParameter("password");UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);Subject subject = SecurityUtils.getSubject();try {subject.login(usernamePasswordToken);req.getRequestDispatcher("main.jsp").forward(req, resp);} catch (Exception e) {req.setAttribute("message", "您的用户名密码输入有误!!!");try {req.getRequestDispatcher("login.jsp").forward(req, resp);} catch (ServletException e1) {e1.printStackTrace();} catch (IOException e1) {e1.printStackTrace();}}return null;}@RequestMapping("/logout")public String logout(HttpServletRequest req, HttpServletResponse resp){Subject subject = SecurityUtils.getSubject();subject.logout();try {resp.sendRedirect(req.getContextPath()+"/login.jsp");} catch (IOException e) {e.printStackTrace();}return null;}}
二、密码加盐加密
盐加密工具类,在做新增用户的时候使用,将加密后的密码、及加密时候的盐放入数据库;
package com.zjy.util;import org.apache.shiro.crypto.RandomNumberGenerator;import org.apache.shiro.crypto.SecureRandomNumberGenerator;import org.apache.shiro.crypto.hash.SimpleHash;public class PasswordHelper {/*** 随机数生成器*/private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();/*** 指定hash算法为MD5*/private static final String hashAlgorithmName = "md5";/*** 指定散列次数为1024次,即加密1024次*/private static final int hashIterations = 1024;/*** true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储*/private static final boolean storedCredentialsHexEncoded = true;/*** 获得加密用的盐** @return*/public static String createSalt() {return randomNumberGenerator.nextBytes().toHex();}/*** 获得加密后的凭证** @param credentials 凭证(即密码)* @param salt盐* @return*/public static String createCredentials(String credentials, String salt) {SimpleHash simpleHash = new SimpleHash(hashAlgorithmName, credentials,salt, hashIterations);return storedCredentialsHexEncoded ? simpleHash.toHex() : simpleHash.toBase64();}/*** 进行密码验证** @param credentials未加密的密码* @param salt盐* @param encryptCredentials 加密后的密码* @return*/public static boolean checkCredentials(String credentials, String salt, String encryptCredentials) {return encryptCredentials.equals(createCredentials(credentials, salt));}public static void main(String[] args) {//盐String salt = createSalt();System.out.println(salt);System.out.println(salt.length());//凭证+盐加密后得到的密码String credentials = createCredentials("123", salt);System.out.println(credentials);System.out.println(credentials.length());boolean b = checkCredentials("123", salt, credentials);System.out.println(b);}}