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
posted @ 2018-11-07 15:13  Slive  阅读(1313)  评论(0编辑  收藏  举报