持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
【2.2.3】编写DefinitionRealm
在DefinitionRealm中修改doGetAuthorizationInfo方法如下
/**
* @Description 授权方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//拿到用户认证凭证信息
String loginName = (String) principals.getPrimaryPrincipal();
//从数据库中查询对应的角色和资源
SecurityService securityService = new SecurityServiceImpl();
List<String> roles = securityService.findRoleByloginName(loginName);
List<String> permissions = securityService.findPermissionByloginName(loginName);
//构建资源校验
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addRoles(roles);
authorizationInfo.addStringPermissions(permissions);
return authorizationInfo;
}
【2.2.4】编写HelloShiro
package com.itheima.shiro;
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;
import org.junit.Assert;
import org.junit.Test;
/**
* @Description:shiro的第一个例子
*/
public class HelloShiro {
@Test
public void testPermissionRealm() {
Subject subject = shiroLogin("jay", "123");
//判断用户是否已经登录
System.out.println("是否登录成功:" + subject.isAuthenticated());
//---------检查当前用户的角色信息------------
System.out.println("是否有管理员角色:"+subject.hasRole("admin"));
//---------如果当前用户有此角色,无返回值。若没有此权限,则抛 UnauthorizedException------------
try {
subject.checkRole("coder");
System.out.println("有coder角色");
}catch (Exception e){
System.out.println("没有coder角色");
}
//---------检查当前用户的权限信息------------
System.out.println("是否有查看订单列表资源:"+subject.isPermitted("order:list"));
//---------如果当前用户有此权限,无返回值。若没有此权限,则抛 UnauthorizedException------------
try {
subject.checkPermissions("order:add", "order:del");
System.out.println("有添加和删除订单资源");
}catch (Exception e){
System.out.println("没有有添加和删除订单资源");
}
}
/**
* @Description 登录方法
*/
private Subject shiroLogin(String loginName,String password) {
//导入权限ini文件构建权限工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//工厂构建安全管理器
SecurityManager securityManager = factory.getInstance();
//使用SecurityUtils工具生效安全管理器
SecurityUtils.setSecurityManager(securityManager);
//使用SecurityUtils工具获得主体
Subject subject = SecurityUtils.getSubject();
//构建账号token
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginName, password);
//登录操作
subject.login(usernamePasswordToken);
return subject;
}
}
【2.3】授权源码追踪
(1)客户端调用 subject.hasRole("admin"),判断当前用户是否有"admin"角色权限。
(2)Subject门面对象接收到要被验证的角色信息"admin",并将其委托给securityManager中验证。
(3)securityManager将验证请求再次委托给内部的小弟:内部组件Authorizer authorizer
(4)内部小弟authorizer也是个混子,将其委托给了我们自定义的Realm去做
(5) 先拿到PrincipalCollection principal对象,同时传入校验的角色循环校验,循环中先创建鉴权信息
(6)先看缓存中是否已经有鉴权信息
【3】小结
1、鉴权需要实现doGetAuthorizationInfo方法
2、鉴权使用门面subject中方法进行鉴权
以check开头的会抛出异常
以is和has开头会返回布尔值