六.自定义realm进行授权(包括散列认证)

来源:互联网 发布:python中tile函数 编辑:程序博客网 时间:2024/04/27 19:03

一.maven的pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.tiglle</groupId>  <artifactId>customRealmMd5</artifactId>  <version>0.0.1-SNAPSHOT</version>  <name>customRealm</name>  <description>自定义realm</description>    <!-- shiro -->   <dependencies>    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->    <dependency>        <groupId>org.apache.shiro</groupId>        <artifactId>shiro-core</artifactId>        <version>1.3.2</version>    </dependency>    <!-- log -->    <dependency>        <groupId>org.slf4j</groupId>        <artifactId>slf4j-log4j12</artifactId>        <version>1.7.12</version>    </dependency>    <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->    <dependency>        <groupId>commons-logging</groupId>        <artifactId>commons-logging</artifactId>        <version>1.2</version>    </dependency>  </dependencies></project>

二.shiro的ini配置文件shiro-realm.ini:

# 自定义realm+散列的配置[main]#散列的配置#1定义凭证匹配器credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher#2散列算法credentialsMatcher.hashAlgorithmName=md5#3散列次数credentialsMatcher.hashIterations=1# 变量名=包名.类名customRealm=com.tiglle.customRealm.CustomRealm# 将凭证匹配器设置到自定义realm中# customRealm.credentialsMatcher = $凭证匹配器变量名customRealm.credentialsMatcher=$credentialsMatcher# 将realm设置到securityManager,相当于spring的属性注入# securityManager.realms = $变量名securityManager.realms=$customRealm

三.log4j的配置文件log4j.properties:

# Configure logging for testing: optionally with log filelog4j.rootLogger=DEBUG, stdout# log4j.rootLogger=WARN, stdout, logfilelog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%nlog4j.appender.logfile=org.apache.log4j.FileAppenderlog4j.appender.logfile.File=target/spring.loglog4j.appender.logfile.layout=org.apache.log4j.PatternLayoutlog4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

四.shiro自带的md5的测试方法java类Md5Test.java:

package com.tiglle.md5test;import org.apache.shiro.crypto.hash.Md5Hash;import org.apache.shiro.crypto.hash.SimpleHash;public class Md5Test {    public static void main(String[] args) {        //原始密码        String sourcePsw = "123456";        //干扰字符串        String salt = "ganRaoStr";        //md5次数        int hashIterations = 1;        /**         * 第一种方法:         * @param1 原始密码         * @param2 干扰字符串         * @param3 散列次数,md5的次数,2时:md5(md5("..."))         */        Md5Hash md5Hash = new Md5Hash(sourcePsw,salt,hashIterations);        String resultMd5_1 = md5Hash.toString();        System.out.println(resultMd5_1);        /**         * 第二种方法:         * @param1 散列算法         * @param2 原始密码         * @param3 干扰字符串         * @param4 散列次数,md5的次数,2时:md5(md5("..."))         */        SimpleHash simpleHash = new SimpleHash("md5",sourcePsw,salt,hashIterations);        String resultMd5_2 = simpleHash.toString();        System.out.println(resultMd5_2);    }}

五.自定义reaml的java类(散列认证+授权)CustomRealm.java:

package com.tiglle.customRealm;import java.util.ArrayList;import java.util.List;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;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.apache.shiro.util.ByteSource;/** * 自定义realm,覆盖默认realm(需要配置),让授权数据从数据库或其他地方获取 * @author Administrator * */public class CustomRealm extends AuthorizingRealm{    /**     * 设置realm的名称,模拟用     */    @Override    public void setName(String name) {        super.setName("customRealm");    }    /**     * 认证     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        //token是用户输入的信息        //1.从token中取出用户身份信息        String userCode = (String) token.getPrincipal();        //2.根据用户身份信息从数据库查询用户信息        //.......根据userCode查询数据库        //模拟从数据库查询到了密码(md5加密后的密码)        /*         * 调用了散列算法后的值         Md5Hash md5Hash = new Md5Hash(sourcePsw,salt,hashIterations);         String resultMd5_1 = md5Hash.toString();         */        String password = "5c04c6a227c484bfc5a25be07bf2fee9";        //模拟从数据库查询到盐(干扰字符串,一般加载密码后在MD5加密)        String salt = "ganRaoStr";        //散列必须转为BatySource类型        ByteSource byteSalt =  ByteSource.Util.bytes(salt);        //3.查询不到,请返回null        if(password==null||password.equals("")){            return null;        }        //4.使用有散列的构造方法(配置文件需要配置相关信息 1凭证匹配器 2散列算法 3散列次数)        /*         相当于:         将token中的密码通过md5算法散列一次后,与数据库取出的之前md5散列过一次的秘密对比         */        SimpleAuthenticationInfo simpleAuthenticationInfo =                 new SimpleAuthenticationInfo(userCode,password,byteSalt,this.getName());        return simpleAuthenticationInfo;    }    /**     * 授权     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {        //认证成功后授权        //从principals中获取主身份信息        String userCode = (String) principals.getPrimaryPrincipal();        //根据身份信息从数据库查询权限信息        //模拟查询了数据库...        //根据身份获得了用户所有的权限信息(List为获取的权限集合)        List<String> permission = new ArrayList<String>();        permission.add("user:create");//=user:create:*        permission.add("user:create:1");        permission.add("product:add");        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();        //返回用户所有的权限        simpleAuthorizationInfo.addStringPermissions(permission);        return simpleAuthorizationInfo;    }}

六:测试自定义reaml的java类ShiroMain.java:

package com.tiglle.shiro;import java.util.Arrays;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.config.IniSecurityManagerFactory;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.Factory;public class ShiroMain {    public static void main(String[] args) {        //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");        //2、得到SecurityManager实例        SecurityManager securityManager = factory.getInstance();        // 并绑定给SecurityUtils          SecurityUtils.setSecurityManager(securityManager);        //3、得到Subject        Subject subject = SecurityUtils.getSubject();        //创建用户名/密码身份验证Token(即用户身份/凭证)        UsernamePasswordToken token = new UsernamePasswordToken("zhang","1234567");        try {            //4、登录,即主体身份验证              subject.login(token);        } catch (Exception e) {            //5、身份验证失败              e.printStackTrace();        }        boolean b = subject.isAuthenticated();        System.out.println("身份验证结果:"+b);        //先验证,在授权        //1.基于资源的授权(自定义realm只配置了这种)        //单个权限判断:是否对user的实例1有create操作        boolean isPpermitted = subject.isPermitted("user:create:1");        System.out.println("单个资源判断:zhang是否拥有user:create:1权限——"+isPpermitted);        //多个权限判断        boolean isPpermittedAll = subject.isPermittedAll("user:create:1","user:update:1");        System.out.println("单个资源判断:zhang是否同时拥有user:create:1,user:update:1权限——"+isPpermittedAll);        //也可以使用check进行授权,授权失败会抛异常        subject.checkPermission("user:create:1");        //6.退出        subject.logout();        System.out.println("退出后的身份验证结果:"+subject.isAuthenticated());    }}
原创粉丝点击