自定义Realm实战

一 新建pom


    
        org.apache.shiro
        shiro-core
        1.4.0
    
    
        junit
        junit
        RELEASE
    
    
        mysql
        mysql-connector-java
        5.1.45
    
    
        com.alibaba
        druid
        1.0.20
    

二 新建自定义Realm类

package com.myimooc.shiro.test.realm;

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.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @className: CustomRealm
 * @description: 自定义Realm
 * @date: 2020/5/12
 * @author: cakin
 */
// 仿照jdbcRealm继承 AuthorizingRealm
public class CustomRealm extends AuthorizingRealm {
    /**
     * 在map中放权限数据,模拟数据库
     */
    private Map userMap = new HashMap<>();

    {
        userMap.put("Mark", "283538989cef48f3d7d8a1c1bdf2008f");
        super.setName("customRealm");
    }

/**
 * 功能描述:授权
 *
 * @author cakin
 * @date 2020/5/12
 * @param principals 主要是从中取得用户姓名
 * @return AuthorizationInfo 认证信息,里面封装了角色和权限信息
 */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals ) {
        String userName = (String) principals.getPrimaryPrincipal();
        // 通过用户名获取角色数据
        Set roles = getRolesByUserName(userName);
        // 通过用户名获取权限数据
        Set permissions = getPermissionsByUserName(userName);
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }

    /**
     * 模拟从数据库或缓存中获取权限数据,某用户管关联的权限
     *
     * @param userName 用户名
     * @return 权限数据
     */
    private Set getPermissionsByUserName( String userName ) {
        Set permissions = new HashSet<>();
        permissions.add("user:delete");
        permissions.add("user:add");
        return permissions;
    }

    /**
     * 模拟从数据库或缓存中获取角色数据,某用户管理的角色
     *
     * @param userName 用户名
     * @return 角色数据
     */
    private Set getRolesByUserName( String userName ) {
        Set roles = new HashSet<>();
        roles.add("admin");
        roles.add("user");
        return roles;
    }

    /**
     * 认证
     *
     * @param token 主体传送过来的认证信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token ) throws AuthenticationException {
        // 获取用户名
        String userName = (String) token.getPrincipal();
        // 通过用户名到数据库中获取凭证
        String password = getPasswordByUserName(userName);
        if (password == null) {
            return null;
        }
        // 从数据库查询得到的认证信息,封装到authenticationInfo中
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo("Mark", password, "customRealm");
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("Mark"));
        return authenticationInfo;
    }

    /**
     * 模拟数据库查询凭证
     *
     * @param userName 用户名
     * @return 凭证
     */
    private String getPasswordByUserName( String userName ) {
        // 实际开发中需访问数据库
        return userMap.get(userName);
    }

    public static void main( String[] args ) {
        Md5Hash md5Hash = new Md5Hash("123456", "Mark");
        System.out.println(md5Hash.toString());
    }

}

三 测试自定义Realm类

package com.myimooc.shiro.test;

import com.myimooc.shiro.test.realm.CustomRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;

/**
 * @className: CustomRealmTest
 * @description: 自定义Realm测试
 * @date: 2020/5/12
 * @author: cakin
 */
public class CustomRealmTest {

    @Test
    public void testAuthentication() {
        CustomRealm customRealm = new CustomRealm();

        // 构建 SecurityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        // 设置自定义Realm
        defaultSecurityManager.setRealm(customRealm);

        // 定义一个认证算法
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(1);

        // 设置认证算法
        customRealm.setCredentialsMatcher(matcher);

        // 主体提交认证请求
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        Subject subject = SecurityUtils.getSubject();

        // 登录认证
        UsernamePasswordToken token = new UsernamePasswordToken("Mark", "123456");
        subject.login(token);

        // 认证是否通过
        System.out.println("isAuthenticated:" + subject.isAuthenticated());

        // 鉴权相关测试
        subject.checkRole("admin");
        subject.checkRoles("admin", "user");
        subject.checkPermission("user:delete");
        subject.checkPermission("user:add");
        subject.checkPermissions("user:add", "user:delete");
    }
}

四 测试结果

isAuthenticated:true

Process finished with exit code 0

你可能感兴趣的:(安全,Shiro)