• 超级简单学会:盐加密&Shiro认证


    目录

    一、盐加密

    二、Shiro认证


    一、盐加密

            ①数据库密码发展史

    第一个阶段:明文密码        123456  (安全性较低)

    第二个阶段:md5加密        e10adc3949ba59abbe56e057f20f883e (安全性较高)

    第三个阶段:md5加盐加密        (安全性更高)

    第四个阶段:md5加盐加密加次数        (安全性最高)

            ②初步实现盐加密:

     我们使用盐加密,一般是在新增用户数据或会自动修改用户数据时将密码自动加密:

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

    二、Shiro认证

            ①导入POM依赖

    1. <dependency>
    2. <groupId>org.apache.shirogroupId>
    3. <artifactId>shiro-coreartifactId>
    4. <version>1.3.2version>
    5. dependency>
    6. <dependency>
    7. <groupId>org.apache.shirogroupId>
    8. <artifactId>shiro-webartifactId>
    9. <version>1.3.2version>
    10. dependency>
    11. <dependency>
    12. <groupId>org.apache.shirogroupId>
    13. <artifactId>shiro-springartifactId>
    14. <version>1.3.2version>
    15. dependency>

            ②web.xml配置

    1. shiroFilter
    2. org.springframework.web.filter.DelegatingFilterProxy
    3. targetFilterLifecycle
    4. true
    5. shiroFilter
    6. /*

            ③修改配置 

     完成准备工作后逆向生成完我们的数据       

    UserMapper.xml中新增一个方法:

    1. <select id="queryByName" resultType="com.zq.ssm.model.ShiroUser" parameterType="java.lang.String">
    2. select
    3. <include refid="Base_Column_List" />
    4. from t_shiro_user
    5. where userName = #{userName}
    6. select>

    UserMapper.java:

    1. package com.zq.ssm.mapper;
    2. import com.ruojuan.ssm.model.User;
    3. import org.apache.ibatis.annotations.Param;
    4. import org.springframework.stereotype.Repository;
    5. @Repository
    6. public interface UserMapper {
    7. int deleteByPrimaryKey(Integer userid);
    8. int insert(User record);
    9. int insertSelective(User record);
    10. User queryByName(@Param("userName") String userName);
    11. User selectByPrimaryKey(Integer userid);
    12. int updateByPrimaryKeySelective(User record);
    13. int updateByPrimaryKey(User record);
    14. }

    UserBizImpl.java:

    1. package com.zq.ssm.impl;
    2. import com.zq.ssm.biz.UserBiz;
    3. import com.zq.ssm.mapper.UserMapper;
    4. import com.zq.ssm.model.User;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. @Service("userBiz")
    8. public class UserBizImpl implements UserBiz {
    9. @Autowired
    10. private UserMapper userMapper;
    11. @Override
    12. public int deleteByPrimaryKey(Integer userid) {
    13. return userMapper.deleteByPrimaryKey(userid);
    14. }
    15. @Override
    16. public int insert(User record) {
    17. return userMapper.insert(record);
    18. }
    19. @Override
    20. public int insertSelective(User record) {
    21. return userMapper.insertSelective(record);
    22. }
    23. @Override
    24. public User queryByName(String userName) {
    25. return userMapper.queryByName(userName);
    26. }
    27. @Override
    28. public User selectByPrimaryKey(Integer userid) {
    29. return userMapper.selectByPrimaryKey(userid);
    30. }
    31. @Override
    32. public int updateByPrimaryKeySelective(User record) {
    33. return userMapper.updateByPrimaryKeySelective(record);
    34. }
    35. @Override
    36. public int updateByPrimaryKey(User record) {
    37. return userMapper.updateByPrimaryKey(record);
    38. }
    39. }

            ④自定义Realm

    Myrealm.java:

    1. package com.zq.ssm.shiro;
    2. import com.zq.ssm.biz.UserBiz;
    3. import com.zq.ssm.model.User;
    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.SimpleAuthenticationInfo;
    8. import org.apache.shiro.authz.AuthorizationInfo;
    9. import org.apache.shiro.realm.AuthorizingRealm;
    10. import org.apache.shiro.subject.PrincipalCollection;
    11. import org.apache.shiro.util.ByteSource;
    12. public class MyRealm extends AuthorizingRealm{
    13. private UserBiz userBiz;
    14. public UserBiz getUserBiz() {
    15. return userBiz;
    16. }
    17. public void setUserBiz(UserBiz userBiz) {
    18. this.userBiz = userBiz;
    19. }
    20. @Override
    21. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    22. return null;
    23. }
    24. @Override
    25. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    26. System.out.println("身份认证...");
    27. String username = token.getPrincipal().toString();
    28. //String password = token.getCredentials().toString();
    29. User user = userBiz.queryByName(username);
    30. // 拿到数据库中的用户信息,放入token凭证中,用于controler进行对比
    31. AuthenticationInfo info = new SimpleAuthenticationInfo(
    32. user.getUsername(),
    33. user.getPassword(),
    34. ByteSource.Util.bytes(user.getSalt()),
    35. this.getName()
    36. );
    37. return info;
    38. }
    39. }

    applicationContext-shiro.xml

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="shiroRealm" class="com.javaxl.ssm.shiro.MyRealm">
    6. <property name="shiroUserService" ref="shiroUserService" />
    7. <property name="credentialsMatcher">
    8. <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
    9. <property name="hashAlgorithmName" value="md5"/>
    10. <property name="hashIterations" value="1024"/>
    11. <property name="storedCredentialsHexEncoded" value="true"/>
    12. bean>
    13. property>
    14. bean>
    15. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    16. <property name="realm" ref="shiroRealm" />
    17. bean>
    18. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    19. <property name="securityManager" ref="securityManager" />
    20. <property name="loginUrl" value="/login"/>
    21. <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
    22. <property name="filterChainDefinitions">
    23. <value>
    24. /user/login=anon
    25. /user/updatePwd.jsp=authc
    26. /admin/*.jsp=roles[admin]
    27. /user/teacher.jsp=perms["user:update"]
    28. value>
    29. property>
    30. bean>
    31. <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    32. beans>

    controller:

    1. package com.zq.ssm.web;
    2. import org.apache.shiro.SecurityUtils;
    3. import org.apache.shiro.authc.UsernamePasswordToken;
    4. import org.apache.shiro.subject.Subject;
    5. import org.springframework.stereotype.Controller;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import javax.servlet.ServletException;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import java.io.IOException;
    11. @Controller
    12. public class UserController {
    13. @RequestMapping("/login")
    14. public String login(HttpServletRequest req, HttpServletResponse resp){
    15. String username = req.getParameter("username");
    16. String password = req.getParameter("password");
    17. UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
    18. Subject subject = SecurityUtils.getSubject();
    19. try {
    20. subject.login(usernamePasswordToken);
    21. req.getRequestDispatcher("main.jsp").forward(req, resp);
    22. } catch (Exception e) {
    23. req.setAttribute("message", "您的用户名密码输入有误!!!");
    24. try {
    25. req.getRequestDispatcher("login.jsp").forward(req, resp);
    26. } catch (ServletException e1) {
    27. e1.printStackTrace();
    28. } catch (IOException e1) {
    29. e1.printStackTrace();
    30. }
    31. }
    32. return null;
    33. }
    34. @RequestMapping("/logout")
    35. public String logout(HttpServletRequest req, HttpServletResponse resp){
    36. Subject subject = SecurityUtils.getSubject();
    37. subject.logout();
    38. return "login";
    39. }
    40. }

  • 相关阅读:
    Spring总结
    解密Kerberos流量
    Linux下Apache与Nginx服务器配置与优化
    基础会计学知识点汇总
    牛血清白蛋白标记微囊藻毒素(MCLR)(BSA-MCLR)
    架构师之路:中台和微服务区别
    SpringMVC常用注解的详细解析
    Apache Storm 2.5.0 单机安装与配置
    AI与制药相结合,能否弯道超车
    【无标题】
  • 原文地址:https://blog.csdn.net/weixin_66110079/article/details/126541073