SpringBoot與Shiro整合


一、數據庫設計

​  這里主要涉及到五張表:用戶表,角色表(用戶所擁有的角色),權限表(角色所涉及到的權限),用戶-角色表(用戶和角色是多對多的),角色-權限表(角色和權限是多對多的).表結構建立的sql語句如下:

CREATE TABLE `module` (
  `mid` int(11) NOT NULL AUTO_INCREMENT,
  `mname` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`mid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of module
-- ----------------------------
INSERT INTO `module` VALUES ('1', 'add');
INSERT INTO `module` VALUES ('2', 'delete');
INSERT INTO `module` VALUES ('3', 'query');
INSERT INTO `module` VALUES ('4', 'update');

-- ----------------------------
-- Table structure for module_role
-- ----------------------------
DROP TABLE IF EXISTS `module_role`;
CREATE TABLE `module_role` (
  `rid` int(11) DEFAULT NULL,
  `mid` int(11) DEFAULT NULL,
  KEY `rid` (`rid`),
  KEY `mid` (`mid`),
  CONSTRAINT `mid` FOREIGN KEY (`mid`) REFERENCES `module` (`mid`),
  CONSTRAINT `rid` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of module_role
-- ----------------------------
INSERT INTO `module_role` VALUES ('1', '1');
INSERT INTO `module_role` VALUES ('1', '2');
INSERT INTO `module_role` VALUES ('1', '3');
INSERT INTO `module_role` VALUES ('1', '4');
INSERT INTO `module_role` VALUES ('2', '1');
INSERT INTO `module_role` VALUES ('2', '3');

-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `rid` int(11) NOT NULL AUTO_INCREMENT,
  `rname` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`rid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', 'admin');
INSERT INTO `role` VALUES ('2', 'customer');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'wulifu', '123456');
INSERT INTO `user` VALUES ('2', 'root', '123456');

-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `uid` int(11) DEFAULT NULL,
  `rid` int(11) DEFAULT NULL,
  KEY `u_fk` (`uid`),
  KEY `r_fk` (`rid`),
  CONSTRAINT `r_fk` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`),
  CONSTRAINT `u_fk` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('1', '1');
INSERT INTO `user_role` VALUES ('2', '2');
View Code

二、功能要求

admin要求只有具有admin角色的用戶才能訪問,update需要有update權限的用戶才能訪問,login、loginUser都不做攔截。

預期目標:

wulifu是有admin角色和所有權限,所以用wulifu登錄后,可以訪問update和admin,但是不能訪問guest;而root是customer角色,只有add和query權限,所以不能訪問admin和update。

三、添加依賴,配置文件

1、springboot項目,項目結構如下:

2、添加依賴

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.20</version>
        </dependency>
        <!--常用的工具包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <!--spring的上下文工具包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!--對jsp的處理-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
    </dependencies>
View Code

3、application.yml

server:
  port: 8010
  tomcat.uri-encoding: UTF-8

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shiro?characterEncoding=UTF-8
    username: root
    password: 123456
  mvc:
    view:
      prefix: /WEB-INF/jsp/
      suffix: .jsp
mybatis:
  mapper-locations: mappers/*.xml
  # mapper.xml中的resultType中經常會用到一些自定義POJO,你可以用完全限定名來指定這些POJO的引用,例如
  #  <select id="getUsers" resultType="com.majing.learning.mybatis.entity.User">,
  # 又或者你可以通過在application.yml中指定POJO掃描包來讓mybatis自動掃描到自定義POJO,如下:
  #  mybatis:type-aliases-package: com.majing.learning.mybatis.entity
  type-aliases-package: com.example.springbootshiro.pojo
View Code

三、項目設計

1、pojo層

User.java

public class User implements Serializable {
    private Integer uid;
    private String username;
    private String password;
    private Set<Role> roles = new HashSet<>();
}

Role.java

public class Role implements Serializable {
    private  Integer rid;
    private  String rname;
    private Set<Module> modules = new HashSet<>();
}

Module.java

public class Module implements Serializable {
    private  Integer mid;
    private  String mname;
}

2、dao層

UserMapper.java

import com.example.springbootshiro.pojo.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper {
    User findByUserName(String username);
}
View Code

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springbootshiro.dao.UserMapper">

    <resultMap id="userMap" type="com.example.springbootshiro.pojo.User">
        <id property="uid" column="uid"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <collection property="roles" ofType="com.example.springbootshiro.pojo.Role">
            <id property="rid" column="rid"/>
            <result property="rname" column="rname"/>
            <collection property="modules" ofType="com.example.springbootshiro.pojo.Module">
                <id property="mid" column="mid"/>
                <result property="mname" column="mname"/>
            </collection>
        </collection>
    </resultMap>

    <select id="findByUserName" parameterType="string" resultMap="userMap">
        SELECT u.*,r.*,m.* FROM user u
        inner join user_role ur on ur.uid=u.uid
        inner join role r on r.rid=ur.rid
        inner join module_role mr on mr.rid=r.rid
        inner join module m on mr.mid=m.mid
        WHERE username=#{username};
    </select>

</mapper>
View Code

圖中紅框內可能會報錯,但是依然可以正常運行。

3、service層

IUserService.Interface

public interface IUserService {
    User findByUserName(String username);
}
View Code

UserServiceImpl.java

@Service("iUserService")
public class UserServiceImpl implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public User findByUserName(String username) {
        return userMapper.findByUserName(username);
    }
}
View Code

4、controller層

TestController.java

@Controller
public class TestController {

    @RequestMapping("/login")
    public String login(){
        return "login";
    }

    @RequestMapping("/index")
    public String index(){
        return "index";
    }

    @RequestMapping("/unauthorized")
    public String unauthorized() {
        return "unauthorized";
    }

    /**
     * 擁有admin角色的人才能訪問
     * @return
     */
    @RequestMapping("/admin")
    public String admin(){
        return "admin";
    }

    /**
     * 擁有update權限的人才能訪問
     * @return
     */
    @RequestMapping("/update")
    public String update(){
        return "update";
    }


    @RequestMapping("/logout")
    public String logout(){
        Subject subject = SecurityUtils.getSubject();//取出當前驗證主體
        if(subject != null){
            subject.logout(); //執行一次logout的操作,將session全部清空
        }
        return "login";
    }

    /**
     *  整個form表單的驗證流程:
     *  將登陸的用戶/密碼傳入UsernamePasswordToken,當調用subject.login(token)開始,
     *  調用Relam的doGetAuthenticationInfo方法,開始密碼驗證
     *  此時這個時候執行我們自己編寫的CredentialMatcher(密碼匹配器),
     *  執行doCredentialsMatch方法,具體的密碼比較實現在這實現
     */
    @RequestMapping(value = "/loginUser")
    public String loginUser(@RequestParam("username") String username,
                            @RequestParam("password") String password,
                            HttpSession session) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token); //登陸成功的話,放到session中
            User user = (User) subject.getPrincipal();
            session.setAttribute("user", user);
            return "index";
        }catch (Exception e) {
            return "login";
        }
    }
}
View Code

5、jsp頁面

login.jsp(登錄頁面)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
</head>
<body>
<form action="/loginUser" method="post">
    <input type="text" name="username"> <br>
    <input type="password" name="password"> <br>
    <input type="submit" value="提交">
</form>
</body>
</html>
View Code

index.jsp(登錄成功后跳轉的頁面)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登錄</title>
</head>
<body>
<h1> 歡迎登錄, ${user.username} </h1>
</body>
</html>
View Code

unauthorized.jsp (無權訪問跳轉的頁面)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
Unauthorized!
</body>
</html>
View Code

admin.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>admin</title>
</head>
<body>
admin!
</body>
</html>
View Code

update.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>update</title>
</head>
<body>
update!
</body>
</html>
View Code

四、配置Shiro

1、核心配置類:ShiroConfiguration.java

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;

@Configuration
public class ShiroConfiguration {

    /**
     *  @Qualifier("XXX") Spring的Bean注入配置注解,該注解指定注入的Bean的名稱,
     *  Spring框架使用byName方式尋找合格的bean,這樣就消除了byType方式產生的歧義。
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        System.out.println(bean);
        bean.setSecurityManager(manager);

        bean.setLoginUrl("/login"); //提供登錄到url
        bean.setSuccessUrl("/index"); //提供登陸成功的url
        bean.setUnauthorizedUrl("/unauthorized");

        /**
         * 可以看DefaultFilter,這是一個枚舉類,定義了很多的攔截器authc,anon等分別有對應的攔截器
         */
        //配置訪問權限
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/index", "authc"); //代表着前面的url路徑,用后面指定的攔截器進行攔截
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/loginUser", "anon");
        filterChainDefinitionMap.put("/admin", "roles[admin]"); //admin的url,要用角色是admin的才可以登錄,對應的攔截器是RolesAuthorizationFilter
        filterChainDefinitionMap.put("/update", "perms[update]"); //擁有update權限的用戶才有資格去訪問
        //filterChainDefinitionMap.put("/druid/**", "anon"); //所有的druid請求,不需要攔截,anon對應的攔截器不會進行攔截
        filterChainDefinitionMap.put("/**", "user"); //所有的路徑都攔截,被UserFilter攔截,這里會判斷用戶有沒有登陸
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);//設置一個攔截器鏈

        return bean;
    }

    /**
     * 定義安全管理器securityManager,注入自定義的realm
     * @param authRealm
     * @return
     */
    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
        //這個DefaultWebSecurityManager構造函數,會對Subject,realm等進行基本的參數注入
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(authRealm);//往SecurityManager中注入Realm,代替原本的默認配置
        return manager;
    }


    //自定義的Realm
    @Bean("authRealm")
    //@DependsOn("lifecycleBeanPostProcessor") //可選
    public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialMatcher matcher) {
        AuthRealm authRealm = new AuthRealm();
        //這邊可以選擇是否將認證的緩存到內存中,現在有了這句代碼就將認證信息緩存的內存中了
        //authRealm.setCacheManager(new MemoryConstrainedCacheManager());
        //最簡單的情況就是明文直接匹配,然后就是加密匹配,這里的匹配工作則就是交給CredentialsMatcher來完成
        authRealm.setCredentialsMatcher(matcher);
        return authRealm;
    }

    /**
     * Realm在驗證用戶身份的時候,要進行密碼匹配
     * 最簡單的情況就是明文直接匹配,然后就是加密匹配,這里的匹配工作則就是交給CredentialsMatcher來完成
     * 支持任意數量的方案,包括純文本比較、散列比較和其他方法。除非該方法重寫,否則默認值為
     * @return
     */
    @Bean("credentialsMatcher")
    public CredentialMatcher credentialsMatcher() {
        CredentialMatcher credentialsMatcher = new CredentialMatcher();
        return credentialsMatcher;
    }


    /**
     * 配置shiro跟spring的關聯
     * 以下AuthorizationAttributeSourceAdvisor,DefaultAdvisorAutoProxyCreator兩個類是為了支持shiro注解
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    /**
     * Spring的一個bean , 由Advisor決定對哪些類的方法進行AOP代理
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

    /**
     * lifecycleBeanPostProcessor是負責生命周期的 , 初始化和銷毀的類
     * (可選)
     * @return
     */
    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

}
View Code

這個SecurityManager的導包是org.apache.shiro.mgt.SecurityManager,不要導了java的包。

2、自定義域:AuthRealm.java

​ 編寫AuthRealm完成根據用戶名去數據庫的查詢,並且將用戶信息放入shiro中,供核心配置類:ShiroConfiguration調用。有認證與授權的方法。

import com.example.springbootshiro.pojo.Module;
import com.example.springbootshiro.pojo.Role;
import com.example.springbootshiro.pojo.User;
import com.example.springbootshiro.service.IUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

//AuthenticatingRealm是抽象類,用於認證授權
public class AuthRealm extends AuthorizingRealm {

    @Autowired
    private IUserService iUserService;

    /**
     * 用戶授權
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //獲取前端輸入的用戶信息,封裝為User對象
        User userweb = (User) principals.getPrimaryPrincipal();
        //獲取前端輸入的用戶名
        String username = userweb.getUsername();
        //根據前端輸入的用戶名查詢數據庫中對應的記錄
        User user = iUserService.findByUserName(username);
        if(user != null){
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //因為addRoles和addStringPermissions方法需要的參數類型是Collection
            //所以先創建兩個collection集合
            Collection<String> rolesCollection = new HashSet<String>();
            Collection<String> perStringCollection = new HashSet<String>();
            //獲取user的Role的set集合
            Set<Role> roles = user.getRoles();
            //遍歷集合
            for (Role role : roles){
                //將每一個role的name裝進collection集合
                rolesCollection.add(role.getRname());
                //獲取每一個Role的permission的set集合
                Set<Module> permissionSet =  role.getModules();
                //遍歷集合
                for (Module permission : permissionSet){
                    //將每一個permission的name裝進collection集合
                    perStringCollection.add(permission.getMname());
                    System.out.println(permission.getMname());
                }
                //為用戶授權
                info.addStringPermissions(perStringCollection);
            }
            //為用戶授予角色
            info.addRoles(rolesCollection);
            return info;

        }
        return null;
    }

    /**
     * 用於認證登錄,認證接口實現方法,該方法的回調一般是通過subject.login(token)方法來實現的
     * AuthenticationToken 用於收集用戶提交的身份(如用戶名)及憑據(如密碼):
     * AuthenticationInfo是包含了用戶根據username返回的數據信息,用於在匹馬比較的時候進行相互比較
     *
     * shiro的核心是java servlet規范中的filter,通過配置攔截器,使用攔截器鏈來攔截請求,如果允許訪問,則通過。
     * 通常情況下,系統的登錄、退出會配置攔截器。登錄的時候,調用subject.login(token),token是用戶驗證信息,
     * 這個時候會在Realm中doGetAuthenticationInfo方法中進行認證。這個時候會把用戶提交的驗證信息與數據庫中存儲的認證信息,將所有的數據拿到,在匹配器中進行比較
     * 這邊是我們自己實現的CredentialMatcher類的doCredentialsMatch方法,返回true則一致,false則登陸失敗
     * 退出的時候,調用subject.logout(),會清除回話信息
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //token攜帶了用戶信息
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        //獲取前端輸入的用戶名
        String username  = usernamePasswordToken.getUsername();
        //根據用戶名查詢數據庫中對應的記錄
        User user = iUserService.findByUserName(username);

        /*//當前realm對象的name
        String realmName = getName();
        //鹽值
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername());
        //封裝用戶信息,構建AuthenticationInfo對象並返回
        AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user, user.getPassword(),
                credentialsSalt, realmName);*/
        return new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());
    }

}
View Code

3、數據庫密碼為明文時密碼匹配類:CredentialMatcher.java

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;

public class CredentialMatcher extends SimpleCredentialsMatcher {
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        UsernamePasswordToken utoken=(UsernamePasswordToken) token;
        //獲得用戶輸入的密碼:(可以采用加鹽(salt)的方式去檢驗)
        String inPassword = new String(utoken.getPassword());
        //獲得數據庫中的密碼
        String dbPassword=(String) info.getCredentials();
        //進行密碼的比對
        return this.equals(inPassword, dbPassword);
    }
}
View Code

4、數據庫為加密加鹽時

authRealm引用的密碼匹配需要更換。

以下密碼匹配直接寫在核心配置類:ShiroConfiguration.java中

    /**
     * 密碼校驗規則HashedCredentialsMatcher
     * 這個類是為了對密碼進行編碼的 ,
     * 防止密碼在數據庫里明碼保存 , 當然在登陸認證的時候 ,
     * 這個類也負責對form里輸入的密碼進行編碼
     * 處理認證匹配處理器:如果自定義需要實現繼承HashedCredentialsMatcher
     */
    @Bean("hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //指定加密方式為MD5
        credentialsMatcher.setHashAlgorithmName("MD5");
        //加密次數
        credentialsMatcher.setHashIterations(1024);
        credentialsMatcher.setStoredCredentialsHexEncoded(true);
        return credentialsMatcher;
    }
View Code

附上明文轉密文的代碼:

public static void main(String[] args) {
        String hashAlgorithName = "MD5";
        String password = "登錄時輸入的密碼";
        int hashIterations = 1;//加密次數
        ByteSource credentialsSalt = ByteSource.Util.bytes("登錄時輸入的用戶名");
        Object obj = new SimpleHash(hashAlgorithName, password, credentialsSalt, hashIterations);
        System.out.println(obj);
    }
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM