shiro--身份授权的基本流程

身份授权基本流程

  1. 先调用Subject.isPermitted/hasRole接口,其会委托给SecurityManager
  2. SecurityManager再交给Authorizer
  3. Authorizer再交给Realm去做,Realm才是真正干活的
  4. Realm将用户请求的参数封装成权限对象。再从我们重写的doGetAuthorizationInfo方法中获取从数据库中查到的权限集合
  5. Realm将用户传入的权限和数据库中查到的权限进行对比,如果传入的权限对象在数据库查到的权限集合中,则返回true,否则返回false

demo

DefinitionRealm自定义Realm类

package realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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;
import service.SecurityService;
import service.impl.SecurityServiceImpl;
import tools.DigestsUtil;

import java.util.List;
import java.util.Map;

public class DefinitionRealm extends AuthorizingRealm {

    // 在构造函数中修改密码比较器
    public DefinitionRealm(){
        // 指定密码匹配方式sha1
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(DigestsUtil.SHA1);
        // 指定密码迭代次数
        matcher.setHashIterations(DigestsUtil.ITERATIONS);
        // 使用父层方法是匹配方式生效
        setCredentialsMatcher(matcher);
    }

    /***
     *  鉴权方法
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 拿到用户凭证信息
        String loginName = (String) principalCollection.getPrimaryPrincipal();
        // 从数据库中查询对应的角色和权限
        SecurityService securityService = new SecurityServiceImpl();
        List<String> roles = securityService.findRoleByLoginName(loginName);
        List<String> Permissions = securityService.findPermissionByLoginName(loginName);
        // 构建资源校验对象
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(Permissions);
        return info;
    }

    /***
     *  认证方法
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected SimpleAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取登录名
        String username = (String) authenticationToken.getPrincipal();
        SecurityService service = new SecurityServiceImpl();
        Map<String,String> map = service.findPasswordByUsername(username);
        if(map.isEmpty()){
            throw new UnknownAccountException("账号不存在!");
        }
        String password = map.get("password");
        String salt = map.get("salt");
        return new SimpleAuthenticationInfo(username, password, ByteSource.Util.bytes(salt), getName());
    }
}

service 和serviceImpl

package service;

import java.util.List;
import java.util.Map;

// 模拟数据库操作
public interface SecurityService {
    Map<String,String> findPasswordByUsername(String username);

    // 查询角色
    List<String> findRoleByLoginName(String username);

    // 查询资源
    List<String> findPermissionByLoginName(String username);
}
package service.impl;

import service.SecurityService;
import tools.DigestsUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class SecurityServiceImpl implements SecurityService {
    @Override
    public Map<String,String> findPasswordByUsername(String username) {
        return DigestsUtil.entryptPassword("123");
    }

    @Override
    public List<String> findRoleByLoginName(String username) {
        List<String> roles = new ArrayList<>();
        roles.add("admin");
        roles.add("dev");
        return roles;
    }

    @Override
    public List<String> findPermissionByLoginName(String username) {
        List<String> permissions = new ArrayList<>();
        permissions.add("order:add");
        permissions.add("order:list");
        permissions.add("order:del");
        return permissions;
    }
}

demo类

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.junit.Test;

public class ShiroDemo {
    public Subject shiroLogin( ){
        //1.导入权限ini文件,创建SecurityManagerFactory
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //2.获取SecurityManager,绑定到SecurityUtils中
        SecurityManager securityManager =factory.getInstance();
        SecurityUtils.setSecurityManager( securityManager);
        //3.获取一个用户主体
        Subject currentUser = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("guest", "123");
        currentUser.login(token);
        System.out.println("是否登录成功:"+currentUser.isAuthenticated());
        return currentUser;
    }

    @Test
    public void testPermissionRealm() {
        Subject currentUser = shiroLogin();
        // 校验当前用户是否有管理员角色
        System.out.println("是否有管理员角色:"+currentUser.hasRole("admin"));
        // 校验当前用户没有的角色
        try {
            currentUser.checkRole("coder");
            System.out.println("当前用户有coder角色");
        }catch (Exception e){
            System.out.println("当前用户没有coder角色");
        }
        // 校验当前用户的权限信息
        System.out.println("是否有查询权限:"+currentUser.isPermitted("order:list"));
        // 校验当前用户没有的权限
        try {
            currentUser.checkPermission("order:update");
            System.out.println("当前用户有修改的权限");
        }catch (Exception e){
            System.out.println("当前用户没有修改的权限");
        }
    }
}

运行结果

TP858@L3JF_U44F9L~V5

posted @ 2026-01-07 21:06  NE_STOP  阅读(22)  评论(0)    收藏  举报