@Configuration
@EnableMethodSecurity
@Slf4j
public class SecurityConfig {
}
// 导入配置类MethodSecuritySelector
@Import(MethodSecuritySelector.class)
public @interface EnableMethodSecurity {
}
// 导入注解相关的配置类,由配置类导入对应处理注解的拦截器
public class MethodSecuritySelector implements ImportSelector {
// 自动代理的注册器
// 导入创建代理对象的Bean以及每一个注解对应的拦截器的切面对象的Bean
private final AutoProxyRegistrarSelector autoProxy = new AutoProxyRegistrarSelector();
@Override
public String[] selectImports(@NonNull AnnotationMetadata importMetadata) {
// 如果导入类不存在EnableMethodSecurity注解,不处理
if (!importMetadata.hasAnnotation(EnableMethodSecurity.class.getName())) {
return new String[0];
}
// 获取该注解的信息
EnableMethodSecurity annotation = importMetadata.getAnnotations().get(EnableMethodSecurity.class).synthesize();
// 导入创建代理对象的Bean以及每一个注解对应的拦截器的切面对象的Bean
List<String> imports = new ArrayList<>(Arrays.asList(this.autoProxy.selectImports(importMetadata)));
// 判断该注解开启的认证授权注解有哪些
// 如果开启了pre/post,表示开启了Pre|PostAuthorize,Pre|PostFilter
if (annotation.prePostEnabled()) {
imports.add(PrePostMethodSecurityConfiguration.class.getName());
}
// 如果开启了secured,表示启用Secured注解
if (annotation.securedEnabled()) {
imports.add(SecuredMethodSecurityConfiguration.class.getName());
}
// 如果开启了jsr250,表示启用RolesAllowed.class, DenyAll.class, PermitAll.class注解
if (annotation.jsr250Enabled()) {
imports.add(Jsr250MethodSecurityConfiguration.class.getName());
}
// 根据开启的调来导入对应处理的MethodInterceptor拦截器的Bean
return imports.toArray(new String[0]);
}
// 自动代理的注册器
// 导入创建代理对象的Bean以及每一个注解对应的拦截器的切面对象的Bean
private static final class AutoProxyRegistrarSelector extends AdviceModeImportSelector<EnableMethodSecurity> {
// 导入创建代理对象的Bean以及每一个注解对应的拦截器的切面对象的Bean
private static final String[] IMPORTS = new String[]{AutoProxyRegistrar.class.getName(), MethodSecurityAdvisorRegistrar.class.getName()};
private static final String[] ASPECTJ_IMPORTS = new String[]{MethodSecurityAspectJAutoProxyRegistrar.class.getName()};
@Override
public String[] selectImports(@NonNull AdviceMode adviceMode) {
// 代理模式,导入IMPORTS中的两个Bean
if (adviceMode == AdviceMode.PROXY) {
return IMPORTS;
}
// ASPECTJ模式,导入ASPECTJ_IMPORTS的两个Bean
if (adviceMode == AdviceMode.ASPECTJ) {
return ASPECTJ_IMPORTS;
}
throw new IllegalStateException("AdviceMode '" + adviceMode + "' is not supported");
}
}
}
// 负责注入创建AOP对象的BeanPostProcessor
// 事务注解也会注入的这类,它会负责注入创建代理对象的BeanPostProcessor
// 用来给目标类创建代理对象
public class AutoProxyRegistrar {
// 注册Bean
// importingClassMetadata是正在解析的配置类对应的元数据信息,也就是标注@EnableTransactionManagement这个类的配置类
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 获取配置类上的所有注解
Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
for (String annType : annTypes) {
// 遍历所有的注解
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
// 找到一些符合AOP条件的共性,mode,proxyTargetClass等等
Object mode = candidate.get("mode");
Object proxyTargetClass = candidate.get("proxyTargetClass");
// 如果符合这个条件,表示当前类需要进行AOP
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
// 判断当前配置类的代理模式
if (mode == AdviceMode.PROXY) {
// 注册创建AOP代理对象的BeanPostProcessor,InfrastructureAdvisorAutoProxyCreator
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
// 如果proxyTargetClass为true,表示使用CGLIB代理
/*
三种情况
1. proxyTargetClass =false(默认值) 目标实现了接口 JDK代理
2. proxyTargetClass =false(默认值) 目标未实现接口 CGLIB代理
3. proxyTargetClass =true 总是CGLIB代理
*/
if ((Boolean) proxyTargetClass) {
// 强制设置创建代理的使用使用CGLIB代理
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
}
}
// 导入每一个注解对应的拦截器的切面对象的Bean
public class MethodSecurityAdvisorRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册认证授权注解对应的切面或者拦截器
// 命名规则: 注解类名首字符小写 + Authorization +[ Advisor | MethodInterceptor ]
// 例如: preFilterAuthorization要注册的切面或者拦截器为: PreFilterAuthorizationMethodInterceptor,用于处理PreFilter注解
registerAsAdvisor("preFilterAuthorization", registry);
registerAsAdvisor("preAuthorizeAuthorization", registry);
registerAsAdvisor("postFilterAuthorization", registry);
registerAsAdvisor("postAuthorizeAuthorization", registry);
registerAsAdvisor("securedAuthorization", registry);
registerAsAdvisor("jsr250Authorization", registry);
}
/**
* 注册认证授权注解对应的切面
* 命名规则: 注解类名首字符小写 + Authorization +[ Advisor | MethodInterceptor ]
* 例如: preFilterAuthorization要注册的切面或者拦截器为: PreFilterAuthorizationMethodInterceptor,用于处理PreFilter注解
*
* @param prefix 认证授权注解对应的切面对应的前缀,这些注解切面或者切面拦截器按照一定的规则命名的
* @param registry Bean的注册表
*/
private void registerAsAdvisor(String prefix, BeanDefinitionRegistry registry) {
// 先查看是否有指定注解前缀(指定注解名称)类型的切面,如果存在增强该注解的切面,不处理
String advisorName = prefix + "Advisor";
if (registry.containsBeanDefinition(advisorName)) {
return;
}
// 先查看是否有指定注解前缀(指定注解名称)类型的切面拦截器,如果存在增强该注解的切面拦截器,不处理
String interceptorName = prefix + "MethodInterceptor";
if (!registry.containsBeanDefinition(interceptorName)) {
return;
}
// 该注解前缀不存在对应的切面以及拦截器,那么就是用默认的命名规则获得对应的Bean: beanName: 注解前缀(preFilterAuthorization) + 拦截器后缀(MethodInterceptor)
BeanDefinition definition = registry.getBeanDefinition(interceptorName);
// 如果不是RootBeanDefinition类型的Bean定义,不处理
if (!(definition instanceof RootBeanDefinition)) {
return;
}
// 通过拦截器构造上一个切面注册到Spring容器中
RootBeanDefinition advisor = new RootBeanDefinition((RootBeanDefinition) definition);
advisor.setTargetType(Advisor.class);
registry.registerBeanDefinition(prefix + "Advisor", advisor);
}
}
public class PrePostMethodSecurityConfiguration {
// 注册@PreFilter的拦截器
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static MethodInterceptor preFilterAuthorizationMethodInterceptor(
// 设置角色名称前缀的Bean
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
// 注解表达式的处理器
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
// 获取SecurityContextHolder的策略对应的Bean
ObjectProvider<SecurityContextHolderStrategy> strategyProvider, ApplicationContext context) {
// 创建处理@PreFilter的拦截器
PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor();
strategyProvider.ifAvailable(preFilter::setSecurityContextHolderStrategy);
// 设置表达式处理器
preFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
return preFilter;
}
// 注册@PreAuthorize的拦截器
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static MethodInterceptor preAuthorizeAuthorizationMethodInterceptor(
// 设置角色名称前缀的Bean
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
// 注解表达式的处理器
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
// 获取SecurityContextHolder的策略对应的Bean
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
// 授权事件的分发器
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
// 观察者注册表,监控授权过程中的操作
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
// 创建处理PreAuthorize注解的授权管理器
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
// 设置表达式处理器
manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
// 创建PreAuthorize注解的拦截器,其中有@PreAuthorize,@Secured,@DenyAll,@PermitAll,@RolesAllowed效果都是一样,在授权预授权
AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager(manager, registryProvider));
strategyProvider.ifAvailable(preAuthorize::setSecurityContextHolderStrategy);
eventPublisherProvider.ifAvailable(preAuthorize::setAuthorizationEventPublisher);
return preAuthorize;
}
// 注册@PostAuthorize的拦截器
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor(
// 设置角色名称前缀的Bean
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
// 注解表达式的处理器
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
// 获取SecurityContextHolder的策略对应的Bean
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
// 授权事件的分发器
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
// 观察者注册表,监控授权过程中的操作
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
// 创建处理PostAuthorize注解的授权管理器
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
// 设置表达式处理器
manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
// 创建PostAuthorize注解的拦截器
AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager(manager, registryProvider));
strategyProvider.ifAvailable(postAuthorize::setSecurityContextHolderStrategy);
eventPublisherProvider.ifAvailable(postAuthorize::setAuthorizationEventPublisher);
return postAuthorize;
}
// 注册PostFilter的拦截器
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static MethodInterceptor postFilterAuthorizationMethodInterceptor(
// 设置角色名称前缀的Bean
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
// 注解表达式的处理器
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
// 获取SecurityContextHolder的策略对应的Bean
ObjectProvider<SecurityContextHolderStrategy> strategyProvider, ApplicationContext context) {
// 创建处理@PostFilter的拦截器
PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor();
strategyProvider.ifAvailable(postFilter::setSecurityContextHolderStrategy);
// 设置表达式处理器
postFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
return postFilter;
}
// 创建一个延迟观察授权管理器
public static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate, ObjectProvider<ObservationRegistry> registryProvider) {
return new DeferringObservationAuthorizationManager<>(registryProvider, delegate);
}
}
// 延迟的方法注解表达式处理器
public class DeferringMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler {
// 方法注解表达式处理器
private final DefaultMethodSecurityExpressionHandler expressionHandler;
private DeferringMethodSecurityExpressionHandler(
// 方法注解表达式处理器
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
// 角色名称前缀的Bean
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext applicationContext) {
// 如果不存在给定的表达式处理器,那就返回默认的表达式处理器
this.expressionHandler = expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, applicationContext));
}
// 默认的表达式处理器
public static MethodSecurityExpressionHandler defaultExpressionHandler(ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext context) {
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
// 设置指定的角色名前缀
defaultsProvider.ifAvailable((d) -> handler.setDefaultRolePrefix(d.getRolePrefix()));
// 设置上下文
handler.setApplicationContext(context);
return handler;
}
// 获取表达式解析器,返回的就是SpelExpressionParser
@Override
public ExpressionParser getExpressionParser() {
return this.expressionHandler.getExpressionParser();
}
// 创建计算的上下文对象
@Override
public EvaluationContext createEvaluationContext(Authentication authentication, MethodInvocation invocation) {
return this.expressionHandler.createEvaluationContext(authentication, invocation);
}
// 创建计算的上下文对象
@Override
public EvaluationContext createEvaluationContext(Supplier<Authentication> authentication, MethodInvocation invocation) {
return this.expressionHandler.createEvaluationContext(authentication, invocation);
}
// 对目标对象进行过滤操作
@Override
public Object filter(Object filterTarget, Expression filterExpression, EvaluationContext ctx) {
return this.expressionHandler.filter(filterTarget, filterExpression, ctx);
}
// 设置返回结果到计算上下文中
@Override
public void setReturnObject(Object returnObject, EvaluationContext ctx) {
this.expressionHandler.setReturnObject(returnObject, ctx);
}
}
/**
* 实际上该类为{@link DefaultMethodSecurityExpressionHandler}
*/
public class MethodSecurityExpressionHandler {
}
public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpressionHandler<MethodInvocation> implements MethodSecurityExpressionHandler {
// 默认的角色前缀
private String defaultRolePrefix = "ROLE_";
public DefaultMethodSecurityExpressionHandler() {
}
// 创建内置的标准计算上下文对象
@Override
public StandardEvaluationContext createEvaluationContextInternal(Authentication auth, MethodInvocation mi) {
return new MethodSecurityEvaluationContext(auth, mi, getParameterNameDiscoverer());
}
// 创建注解表达式的计算上下文
@Override
public EvaluationContext createEvaluationContext(Supplier<Authentication> authentication, MethodInvocation mi) {
// 创建注解的表达式根对象
MethodSecurityExpressionOperations root = createSecurityExpressionRoot(authentication, mi);
// 创建注解表达式的计算上下文
MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(root, mi, getParameterNameDiscoverer());
// 设置Bean的解析器
ctx.setBeanResolver(getBeanResolver());
return ctx;
}
// 创建注解的表达式根对象
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
return createSecurityExpressionRoot(() -> authentication, invocation);
}
// 创建注解的表达式根对象
private MethodSecurityExpressionOperations createSecurityExpressionRoot(Supplier<Authentication> authentication, MethodInvocation invocation) {
// 保存认证信息
MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(authentication);
// 设置当前方法所在的目标对象
root.setThis(invocation.getThis());
//设置权限表达式计算器
root.setPermissionEvaluator(getPermissionEvaluator());
// 设置解析器
root.setTrustResolver(getTrustResolver());
// 设置角色的层级关系
root.setRoleHierarchy(getRoleHierarchy());
// 设置默认的角色前缀
root.setDefaultRolePrefix(getDefaultRolePrefix());
return root;
}
// 执行过滤操作
@Override
public Object filter(Object filterTarget, Expression filterExpression, EvaluationContext ctx) {
// 获取上下文的根对象
MethodSecurityExpressionOperations rootObject = (MethodSecurityExpressionOperations) ctx.getRootObject().getValue();
// 过滤集合
if (filterTarget instanceof Collection) {
return filterCollection((Collection<?>) filterTarget, filterExpression, ctx, rootObject);
}
// 过滤数组
if (filterTarget.getClass().isArray()) {
return filterArray((Object[]) filterTarget, filterExpression, ctx, rootObject);
}
// 过滤Map
if (filterTarget instanceof Map) {
return filterMap((Map<?, ?>) filterTarget, filterExpression, ctx, rootObject);
}
// 过滤流
if (filterTarget instanceof Stream) {
return filterStream((Stream<?>) filterTarget, filterExpression, ctx, rootObject);
}
// 其他类型不支持过滤
throw new IllegalArgumentException("Filter target must be a collection, array, map or stream type, but was " + filterTarget);
}
// 过滤集合,Set/List/Collection
private <T> Object filterCollection(Collection<T> filterTarget, Expression filterExpression, EvaluationContext ctx, MethodSecurityExpressionOperations rootObject) {
// 需要保留的集合
List<T> retain = new ArrayList<>(filterTarget.size());
// 遍历需要过滤的对象
for (T filterObject : filterTarget) {
// 设置正在过滤的目标对象
rootObject.setFilterObject(filterObject);
// 如果注解的表达式为true,则保留当前这笔数据
if (ExpressionUtils.evaluateAsBoolean(filterExpression, ctx)) {
retain.add(filterObject);
}
}
// 删除过滤之前的所有数据
filterTarget.clear();
// 再保存过滤之后的数据
filterTarget.addAll(retain);
// 返回目标对象
return filterTarget;
}
// 过滤数组
public Object filterArray(Object[] filterTarget, Expression filterExpression, EvaluationContext ctx, MethodSecurityExpressionOperations rootObject) {
// 需要保留的数组
List<Object> retain = new ArrayList<>(filterTarget.length);
// 遍历需要过滤的对象
for (Object filterObject : filterTarget) {
// 设置正在过滤的目标对象
rootObject.setFilterObject(filterObject);
// 如果注解的表达式为true,则保留当前这笔数据
if (ExpressionUtils.evaluateAsBoolean(filterExpression, ctx)) {
// 保留当前这笔数据
retain.add(filterObject);
}
}
// 创建一个新数组
Object[] filtered = (Object[]) Array.newInstance(filterTarget.getClass().getComponentType(), retain.size());
// 将保留符合条件的数据装入数组中
for (int i = 0; i < retain.size(); i++) {
filtered[i] = retain.get(i);
}
// 返回过滤后的数组
return filtered;
}
// 过滤map
public <K, V> Object filterMap(final Map<K, V> filterTarget, Expression filterExpression, EvaluationContext ctx, MethodSecurityExpressionOperations rootObject) {
// 最终需要保留的Map
Map<K, V> retain = new LinkedHashMap<>(filterTarget.size());
// 遍历要过滤的对象
for (Map.Entry<K, V> filterObject : filterTarget.entrySet()) {
// 设置正在过滤的对象
rootObject.setFilterObject(filterObject);
// 如果注解的表达式为true,则保留当前这笔数据
if (ExpressionUtils.evaluateAsBoolean(filterExpression, ctx)) {
retain.put(filterObject.getKey(), filterObject.getValue());
}
}
// 删除过滤之前的所有数据
filterTarget.clear();
// 再保存过滤之后的数据
filterTarget.putAll(retain);
// 返回目标对象
return filterTarget;
}
// 过滤Stream参数
public Object filterStream(final Stream<?> filterTarget, Expression filterExpression, EvaluationContext ctx, MethodSecurityExpressionOperations rootObject) {
// 根据表达式进行过滤
return filterTarget.filter((filterObject) -> {
// 设置过滤的对象
rootObject.setFilterObject(filterObject);
// 根据表达式进行过滤,只过滤符合条件的数据
return ExpressionUtils.evaluateAsBoolean(filterExpression, ctx);
}).onClose(filterTarget::close);
}
// 设置最终的返回值
@Override
public void setReturnObject(Object returnObject, EvaluationContext ctx) {
((MethodSecurityExpressionOperations) ctx.getRootObject().getValue()).setReturnObject(returnObject);
}
// 设置默认的角色前缀,默认为ROLE_
public void setDefaultRolePrefix(String defaultRolePrefix) {
this.defaultRolePrefix = defaultRolePrefix;
}
// 获取默认的角色前缀
protected String getDefaultRolePrefix() {
return this.defaultRolePrefix;
}
}
// 处理@Secured注解拦截器的配置类
public class SecuredMethodSecurityConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static MethodInterceptor securedAuthorizationMethodInterceptor(
// 获取SecurityContextHolder的策略对应的Bean
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
// 观察者注册表,监控授权过程中的操作
ObjectProvider<ObservationRegistry> registryProvider) {
// 处理@Secure注解的授权管理器
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
SecurityContextHolderStrategy strategy = strategyProvider.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
// 创建延迟的授权管理器
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(registryProvider, secured);
// 创建@Secured注解的拦截器,其中有@PreAuthorize,@Secured,@DenyAll,@PermitAll,@RolesAllowed效果都是一样,在授权预授权
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor.secured(manager);
interceptor.setSecurityContextHolderStrategy(strategy);
return interceptor;
}
}
// 处理Jsr250注解拦截器的配置类
public class Jsr250MethodSecurityConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static MethodInterceptor jsr250AuthorizationMethodInterceptor(
// 设置角色名称前缀的Bean
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
// 获取SecurityContextHolder的策略对应的Bean
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
// 观察者注册表,监控授权过程中的操作
ObjectProvider<ObservationRegistry> registryProvider) {
// 处理Jsr250注解的授权管理器
Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager();
// 设置角色前缀
defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));
SecurityContextHolderStrategy strategy = strategyProvider.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
// 创建延迟的授权管理器
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(registryProvider, jsr250);
// 创建jsr250注解的拦截器,其中有@PreAuthorize,@Secured,@DenyAll,@PermitAll,@RolesAllowed效果都是一样,在授权预授权
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor.jsr250(manager);
interceptor.setSecurityContextHolderStrategy(strategy);
return interceptor;
}
}
// 方法拦截之前的授权管理器(其中有@PreAuthorize,@Secured,@DenyAll,@PermitAll,@RolesAllowed)
public class AuthorizationManagerBeforeMethodInterceptor implements Ordered, MethodInterceptor, PointcutAdvisor, AopInfrastructureBean {
// SecurityContextHolderStrategy持久化策略
private Supplier<SecurityContextHolderStrategy> securityContextHolderStrategy = SecurityContextHolder::getContextHolderStrategy;
// 当前拦截器的切点,就是该注解对应的表达式匹配器
private final Pointcut pointcut;
// 授权管理器
private final AuthorizationManager<MethodInvocation> authorizationManager;
// 第一个的顺序
private int order = AuthorizationInterceptorsOrder.FIRST.getOrder();
// 授权的事件分发器,默认不发布任何事件,可以自己设置
private AuthorizationEventPublisher eventPublisher = AuthorizationManagerBeforeMethodInterceptor::noPublish;
public AuthorizationManagerBeforeMethodInterceptor(Pointcut pointcut, AuthorizationManager<MethodInvocation> authorizationManager) {
this.pointcut = pointcut;
this.authorizationManager = authorizationManager;
}
// 创建处理@PreAuthorize注解的拦截器
public static AuthorizationManagerBeforeMethodInterceptor preAuthorize() {
return preAuthorize(new PreAuthorizeAuthorizationManager());
}
// 指定处理@PreAuthorize的授权管理器,并创建AuthorizationManagerBeforeMethodInterceptor对象
public static AuthorizationManagerBeforeMethodInterceptor preAuthorize(AuthorizationManager<MethodInvocation> authorizationManager) {
AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(AuthorizationMethodPointcuts.forAnnotations(PreAuthorize.class), authorizationManager);
interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE.getOrder());
return interceptor;
}
// 创建处理@Secured注解的拦截器
public static AuthorizationManagerBeforeMethodInterceptor secured() {
return secured(new SecuredAuthorizationManager());
}
// 指定处理@Secured的授权管理器,并创建AuthorizationManagerBeforeMethodInterceptor对象
public static AuthorizationManagerBeforeMethodInterceptor secured(AuthorizationManager<MethodInvocation> authorizationManager) {
AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(AuthorizationMethodPointcuts.forAnnotations(Secured.class), authorizationManager);
interceptor.setOrder(AuthorizationInterceptorsOrder.SECURED.getOrder());
return interceptor;
}
// 创建处理Jsr250注解的拦截器
public static AuthorizationManagerBeforeMethodInterceptor jsr250() {
return jsr250(new Jsr250AuthorizationManager());
}
// 创建处理Jsr250注解的拦截器
// 指定处理Jsr250注解的授权管理器,并创建AuthorizationManagerBeforeMethodInterceptor对象
public static AuthorizationManagerBeforeMethodInterceptor jsr250(AuthorizationManager<MethodInvocation> authorizationManager) {
AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(AuthorizationMethodPointcuts.forAnnotations(RolesAllowed.class, DenyAll.class, PermitAll.class), authorizationManager);
interceptor.setOrder(AuthorizationInterceptorsOrder.JSR250.getOrder());
return interceptor;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 尝试授权操作
this.attemptAuthorization(mi);
// 放行到下一个拦截器
return mi.proceed();
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
// 获取通知,就是当前Before拦截器对象
@Override
public Advice getAdvice() {
return this;
}
// 尝试授权操作
private void attemptAuthorization(MethodInvocation mi) {
// 获取到认证信息调用具体的授权管理器进行授权
AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, mi);
// 发布一个授权事件(AuthorizationDeniedEvent)
this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, mi, decision);
// 没有授权
if (decision != null && !decision.isGranted()) {
// 抛出异常
throw new AccessDeniedException("Access Denied");
}
}
// 获取认证信息
private Authentication getAuthentication() {
Authentication authentication = this.securityContextHolderStrategy.get().getContext().getAuthentication();
if (authentication == null) {
throw new AuthenticationCredentialsNotFoundException("An Authentication object was not found in the SecurityContext");
}
return authentication;
}
private static <T> void noPublish(Supplier<Authentication> authentication, T object, AuthorizationDecision decision) {
}
}
// 方法拦截之后的授权管理器(@PostAuthorize注解)
public class AuthorizationManagerAfterMethodInterceptor implements Ordered, MethodInterceptor, PointcutAdvisor, AopInfrastructureBean {
// SecurityContextHolderStrategy持久化策略
private Supplier<SecurityContextHolderStrategy> securityContextHolderStrategy = SecurityContextHolder::getContextHolderStrategy;
// 当前拦截器的切点,就是该注解对应的表达式匹配器
private final Pointcut pointcut;
// 授权管理器
private final AuthorizationManager<MethodInvocationResult> authorizationManager;
// 执行的顺序
private int order;
// 授权的事件分发器,默认不发布任何事件,可以自己设置
private AuthorizationEventPublisher eventPublisher = AuthorizationManagerAfterMethodInterceptor::noPublish;
public AuthorizationManagerAfterMethodInterceptor(Pointcut pointcut, AuthorizationManager<MethodInvocationResult> authorizationManager) {
this.pointcut = pointcut;
this.authorizationManager = authorizationManager;
}
// 创建处理@PostAuthorize注解的拦截器
public static AuthorizationManagerAfterMethodInterceptor postAuthorize() {
return postAuthorize(new PostAuthorizeAuthorizationManager());
}
// 指定处理@PostAuthorize的授权管理器,并创建AuthorizationManagerAfterMethodInterceptor对象
public static AuthorizationManagerAfterMethodInterceptor postAuthorize(AuthorizationManager<MethodInvocationResult> authorizationManager) {
AuthorizationManagerAfterMethodInterceptor interceptor = new AuthorizationManagerAfterMethodInterceptor(AuthorizationMethodPointcuts.forAnnotations(PostAuthorize.class), authorizationManager);
interceptor.setOrder(500);
return interceptor;
}
// 执行当前拦截器
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 放行,获取执行结果
Object result = mi.proceed();
// 尝试授权操作
this.attemptAuthorization(mi, result);
return result;
}
// 获取通知,就是当前AuthorizationManagerAfterMethodInterceptor拦截器对象
@Override
public Advice getAdvice() {
return this;
}
// 尝试授权操作
private void attemptAuthorization(MethodInvocation mi, Object result) {
// 将结果包装
MethodInvocationResult object = new MethodInvocationResult(mi, result);
// 获取到认证信息调用具体的授权管理器进行授权
AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, object);
// 发布一个授权事件(AuthorizationDeniedEvent)
this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, object, decision);
// 没有授权,抛出异常
if (decision != null && !decision.isGranted()) {
throw new AccessDeniedException("Access Denied");
}
}
// 获取认证信息
private Authentication getAuthentication() {
Authentication authentication = this.securityContextHolderStrategy.get().getContext().getAuthentication();
if (authentication == null) {
throw new AuthenticationCredentialsNotFoundException("An Authentication object was not found in the SecurityContext");
}
return authentication;
}
private static <T> void noPublish(Supplier<Authentication> authentication, T object, AuthorizationDecision decision) {
}
}
// 方法拦截之后过滤的的授权管理器(@PostFilter注解)
public class PostFilterAuthorizationMethodInterceptor implements Ordered, MethodInterceptor, PointcutAdvisor, AopInfrastructureBean {
// 获取SecurityContextHolder策略
private Supplier<SecurityContextHolderStrategy> securityContextHolderStrategy = SecurityContextHolder::getContextHolderStrategy;
// @PostFilter注解表达式的属性注册表
private PostFilterExpressionAttributeRegistry registry = new PostFilterExpressionAttributeRegistry();
// 当前拦截器的切点,就是该注解对应的表达式匹配器
private final Pointcut pointcut;
public PostFilterAuthorizationMethodInterceptor() {
this.pointcut = AuthorizationMethodPointcuts.forAnnotations(PostFilter.class);
}
// 设置表达式处理器
public void setExpressionHandler(MethodSecurityExpressionHandler expressionHandler) {
this.registry = new PostFilterExpressionAttributeRegistry(expressionHandler);
}
// 获取当前切点
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public Advice getAdvice() {
return this;
}
// 执行拦截器
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 放行执行目标方法
Object returnedObject = mi.proceed();
// 获取表达式属性值
ExpressionAttribute attribute = this.registry.getAttribute(mi);
// 没有获取到表达式属性,不处理
if (attribute == ExpressionAttribute.NULL_ATTRIBUTE) {
return returnedObject;
}
// 获取到处理@PostFilter注解的表达式处理器
DefaultMethodSecurityExpressionHandler expressionHandler = this.registry.getExpressionHandler();
// 创建表达式计算的上下文对象
EvaluationContext ctx = expressionHandler.createEvaluationContext(this::getAuthentication, mi);
// 将返回结果进行过滤
return expressionHandler.filter(returnedObject, attribute.getExpression(), ctx);
}
// 获取认证信息
private Authentication getAuthentication() {
Authentication authentication = this.securityContextHolderStrategy.get().getContext().getAuthentication();
if (authentication == null) {
throw new AuthenticationCredentialsNotFoundException("An Authentication object was not found in the SecurityContext");
}
return authentication;
}
}
// 方法拦截之前过滤的的授权管理器(@PreFilter注解)
public class PreFilterAuthorizationMethodInterceptor implements Ordered, MethodInterceptor, PointcutAdvisor, AopInfrastructureBean {
// 获取SecurityContextHolder策略
private Supplier<SecurityContextHolderStrategy> securityContextHolderStrategy = SecurityContextHolder::getContextHolderStrategy;
// @PostFilter注解表达式的属性注册表
private PreFilterExpressionAttributeRegistry registry = new PreFilterExpressionAttributeRegistry();
// 当前拦截器的切点,就是该注解对应的表达式匹配器
private final Pointcut pointcut;
public PreFilterAuthorizationMethodInterceptor() {
this.pointcut = AuthorizationMethodPointcuts.forAnnotations(PreFilter.class);
}
// 设置表达式处理器
public void setExpressionHandler(MethodSecurityExpressionHandler expressionHandler) {
this.registry = new PreFilterExpressionAttributeRegistry(expressionHandler);
}
// 获取切点
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
// 获取当前通知拦截器
@Override
public Advice getAdvice() {
return this;
}
// 执行拦截器
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 获取注解的属性值的表达式
PreFilterExpressionAttributeRegistry.PreFilterExpressionAttribute attribute = this.registry.getAttribute(mi);
// 如果没有获取的属性,直接放行
if (attribute == PreFilterExpressionAttributeRegistry.PreFilterExpressionAttribute.NULL_ATTRIBUTE) {
return mi.proceed();
}
// 获取方法注解的表达式处理器
DefaultMethodSecurityExpressionHandler expressionHandler = this.registry.getExpressionHandler();
// 创建表达式的计算上下文对象
EvaluationContext ctx = expressionHandler.createEvaluationContext(this::getAuthentication, mi);
// 查找需要过滤的目标参数对象
Object filterTarget = this.findFilterTarget(attribute.getFilterTarget(), ctx, mi);
// 根据表达式进行过滤
expressionHandler.filter(filterTarget, attribute.getExpression(), ctx);
// 放行继续执行下一个拦截器
return mi.proceed();
}
/**
* 查找需要过滤的目标对象,方法存在多个参数必须加filterTargetName,否则只能有一个参数,并且不能是数组
*
* @param filterTargetName 指定的参数名称
* @param ctx 计算上下文对象
* @param methodInvocation 方法的执行对象
* @return 需要过滤的目标参数对象
*/
private Object findFilterTarget(String filterTargetName, EvaluationContext ctx, MethodInvocation methodInvocation) {
Object filterTarget;
// 如果给定了目标参数对象的名称
if (StringUtils.hasText(filterTargetName)) {
// 根据从上下文中通过变量名获取目标对象
filterTarget = ctx.lookupVariable(filterTargetName);
} else {
// 获取方法的所有参数
Object[] arguments = methodInvocation.getArguments();
// 参数必须只有一个
Assert.state(arguments.length == 1, "Unable to determine the method argument for filtering. Specify the filter target.");
// 获取到第一个参数对象
filterTarget = arguments[0];
// 并且不能为null
Assert.notNull(filterTarget, "Filter target was null. Make sure you passing the correct value in the method argument.");
}
// @Pre只可变的集合,不支持数组
Assert.state(!filterTarget.getClass().isArray(), "Pre-filtering on array types is not supported. Using a Collection will solve this problem.");
return filterTarget;
}
// 获取认证信息
private Authentication getAuthentication() {
Authentication authentication = this.securityContextHolderStrategy.get().getContext().getAuthentication();
if (authentication == null) {
throw new AuthenticationCredentialsNotFoundException("An Authentication object was not found in the SecurityContext");
}
return authentication;
}
}
// 处理@PostAuthorize注解的授权管理器
public class PostAuthorizeAuthorizationManager implements AuthorizationManager<MethodInvocationResult> {
// @PostAuthorize注解属性的注册表
private PostAuthorizeExpressionAttributeRegistry registry = new PostAuthorizeExpressionAttributeRegistry();
public void setExpressionHandler(MethodSecurityExpressionHandler expressionHandler) {
this.registry = new PostAuthorizeExpressionAttributeRegistry(expressionHandler);
}
// 权限校验
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocationResult mi) {
// 获取注解表达式属性
ExpressionAttribute attribute = this.registry.getAttribute(mi.getMethodInvocation());
// 不存在属性表达式,不处理
if (attribute == ExpressionAttribute.NULL_ATTRIBUTE) {
return null;
}
// 获取注解表达式处理器
DefaultMethodSecurityExpressionHandler expressionHandler = this.registry.getExpressionHandler();
// 创建计算上下文对象
EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication, mi.getMethodInvocation());
// 设置返回值对象
expressionHandler.setReturnObject(mi.getResult(), ctx);
// 计算注解的表达式
boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx);
// 如果表达式为true,则授权成功,否则授权失败
return new ExpressionAuthorizationDecision(granted, attribute.getExpression());
}
}
// 处理@Secured注解的授权管理器
public final class SecuredAuthorizationManager implements AuthorizationManager<MethodInvocation> {
// 授权管理器,基于权限列表的授权管理器
private AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
// 缓存的权限信息
private final Map<MethodClassKey, Set<String>> cachedAuthorities = new ConcurrentHashMap<>();
// 设置授权管理器
public void setAuthoritiesAuthorizationManager(AuthorizationManager<Collection<String>> authoritiesAuthorizationManager) {
this.authoritiesAuthorizationManager = authoritiesAuthorizationManager;
}
// 授权校验
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation mi) {
// 获取注解中写的权限列表
Set<String> authorities = this.getAuthorities(mi);
// 如果未填写,返回null,就不会处理
// 如果添加了,使用权限列表的授权管理器进行权限校验,返回授权管理器的校验结果
return authorities.isEmpty() ? null : this.authoritiesAuthorizationManager.check(authentication, authorities);
}
// 获取注解中写的权限列表
private Set<String> getAuthorities(MethodInvocation methodInvocation) {
Method method = methodInvocation.getMethod();
Object target = methodInvocation.getThis();
Class<?> targetClass = (target != null) ? target.getClass() : null;
// 创建缓存Key
MethodClassKey cacheKey = new MethodClassKey(method, targetClass);
// 缓存解析到的注解中的权限信息
return this.cachedAuthorities.computeIfAbsent(cacheKey, (k) -> this.resolveAuthorities(method, targetClass));
}
// 解析注解中的权限信息
private Set<String> resolveAuthorities(Method method, Class<?> targetClass) {
// 获取到目标方法
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 获取方法或者类中的@Secured注解
Secured secured = this.findSecuredAnnotation(specificMethod);
// 如果存在@Secured注解,获取标注了@注解中添加的权限列表
return (secured != null) ? Set.of(secured.value()) : Collections.emptySet();
}
// 获取方法或者类中的@Secured注解
private Secured findSecuredAnnotation(Method method) {
Secured secured = AuthorizationAnnotationUtils.findUniqueAnnotation(method, Secured.class);
return (secured != null) ? secured : AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), Secured.class);
}
}
// 处理@PreAuthorize注解的授权管理器
public class PreAuthorizeAuthorizationManager implements AuthorizationManager<MethodInvocation> {
// PreAuthorize注解属性的注册表
private PreAuthorizeExpressionAttributeRegistry registry = new PreAuthorizeExpressionAttributeRegistry();
public void setExpressionHandler(MethodSecurityExpressionHandler expressionHandler) {
this.registry = new PreAuthorizeExpressionAttributeRegistry(expressionHandler);
}
// 权限校验
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation mi) {
// 获取注解表达式属性
ExpressionAttribute attribute = this.registry.getAttribute(mi);
// 不存在属性表达式,不处理
if (attribute == ExpressionAttribute.NULL_ATTRIBUTE) {
return null;
}
// 创建计算上下文对象
EvaluationContext ctx = this.registry.getExpressionHandler().createEvaluationContext(authentication, mi);
// 计算注解的表达式
boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx);
// 如果表达式为true,则授权成功,否则授权失败
return new ExpressionAuthorizationDecision(granted, attribute.getExpression());
}
}
// 处理@DenyAll,@PermitAll,@RolesAllowed注解的授权管理器
public final class Jsr250AuthorizationManager implements AuthorizationManager<MethodInvocation> {
// JSR250包含的授权注解
private static final Set<Class<? extends Annotation>> JSR250_ANNOTATIONS = new HashSet<>();
static {
JSR250_ANNOTATIONS.add(DenyAll.class);
JSR250_ANNOTATIONS.add(PermitAll.class);
JSR250_ANNOTATIONS.add(RolesAllowed.class);
}
// 注解授权管理器的注册表
private final Jsr250AuthorizationManagerRegistry registry = new Jsr250AuthorizationManagerRegistry();
// 角色前缀
private String rolePrefix = "ROLE_";
// 设置角色前缀
public void setRolePrefix(String rolePrefix) {
this.rolePrefix = rolePrefix;
}
// 授权操作
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation methodInvocation) {
// 获取对应注解的授权管理器
AuthorizationManager<MethodInvocation> delegate = this.registry.getManager(methodInvocation);
/**
* {@link Jsr250AuthorizationManager.Jsr250AuthorizationManagerRegistry#resolveManager}
* 该check直接就是返回在resolveManager已经处理过的结果
*/
return delegate.check(authentication, methodInvocation);
}
// Jsr250注解的授权管理器注册表,该类是用于处理Jsr250注解逻辑,最终返回指定结果的授权管理器
private final class Jsr250AuthorizationManagerRegistry extends AbstractAuthorizationManagerRegistry {
// 获取授权管理器
public AuthorizationManager<MethodInvocation> getManager(MethodInvocation methodInvocation) {
Method method = methodInvocation.getMethod();
Object target = methodInvocation.getThis();
Class<?> targetClass = (target != null) ? target.getClass() : null;
// 生成缓存KEY
MethodClassKey cacheKey = new MethodClassKey(method, targetClass);
// 解析注解并返回指定结果的授权管理器,并缓存
return this.cachedManagers.computeIfAbsent(cacheKey, (k) -> resolveManager(method, targetClass));
}
// 解析注解信息,返回具有指定结果的授权管理器
@NonNull
@Override
public AuthorizationManager<MethodInvocation> resolveManager(Method method, Class<?> targetClass) {
// 查找授权注解信息
Annotation annotation = findJsr250Annotation(method, targetClass);
// 如果是DenyAll,表示拒绝所有,直接不授权就完成
if (annotation instanceof DenyAll) {
return (a, o) -> new AuthorizationDecision(false);
}
// 如果是PermitAll,表示允许所有,直接授权
if (annotation instanceof PermitAll) {
return (a, o) -> new AuthorizationDecision(true);
}
// 如果是RolesAllowed,表示允许注解中权限列表的任意一个即有权限
if (annotation instanceof RolesAllowed) {
RolesAllowed rolesAllowed = (RolesAllowed) annotation;
// 调用AuthorityAuthorizationManager的权限管理器进行校验,返回最终的结果
/**针对所有权限的授权管理器,内部代理了基于权限列表{@link AuthoritiesAuthorizationManager授权管理器*/
return AuthorityAuthorizationManager.hasAnyRole(Jsr250AuthorizationManager.this.rolePrefix, rolesAllowed.value());
}
// 如果不是以上的三个注解,返回一个空AuthorizationDecision
return NULL_MANAGER;
}
// 查找类或者方法中的Jsr250注解信息
private Annotation findJsr250Annotation(Method method, Class<?> targetClass) {
// 获取到目标方法
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 获取方法中的授权注解
Annotation annotation = findAnnotation(specificMethod);
// 如果方法中不存在注解,在获取类中的授权注解,如果都不存在返回null,否则返回注解信息
return (annotation != null) ? annotation : findAnnotation(specificMethod.getDeclaringClass());
}
// 查找方法或者类上的JSR250的授权注解
private Annotation findAnnotation(AnnotatedElement method) {
Set<Annotation> annotations = new HashSet<>();
for (Class<? extends Annotation> annotationClass : JSR250_ANNOTATIONS) {
// 先找方法中的,可以能存在多个,下面会校验,多个抛出异常
Annotation annotation = AuthorizationAnnotationUtils.findUniqueAnnotation(method, annotationClass);
if (annotation != null) {
annotations.add(annotation);
}
}
// 如果没有找到,直接返回null
if (annotations.isEmpty()) {
return null;
}
// 如果找到了多个,抛出异常
if (annotations.size() > 1) {
throw new AnnotationConfigurationException("The JSR-250 specification disallows DenyAll, PermitAll, and RolesAllowed from appearing on the same method.");
}
// 返回唯一的授权注解
return annotations.iterator().next();
}
}
}
// 针对所有权限的授权管理器,内部代理了基于权限列表授权管理器
public final class AuthorityAuthorizationManager<T> implements AuthorizationManager<T> {
// 角色前缀
private static final String ROLE_PREFIX = "ROLE_";
// 代理的基于权限列表授权管理器
private final AuthoritiesAuthorizationManager delegate = new AuthoritiesAuthorizationManager();
// 需要校验的权限列表
private final Set<String> authorities;
private AuthorityAuthorizationManager(String... authorities) {
this.authorities = Set.of(authorities);
}
// 设置角色的层次结构处理器
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
this.delegate.setRoleHierarchy(roleHierarchy);
}
// 校验是否存在指定角色
public static <T> AuthorityAuthorizationManager<T> hasRole(String role) {
// 角色名称不能以ROLE_开头,否则报错
Assert.isTrue(!role.startsWith(ROLE_PREFIX), () -> role + " should not start with " + ROLE_PREFIX + " since " + ROLE_PREFIX + " is automatically prepended when using hasRole. Consider using hasAuthority instead.");
// 拼接角色前缀判断权限
return hasAuthority(ROLE_PREFIX + role);
}
// 是否有权限
public static <T> AuthorityAuthorizationManager<T> hasAuthority(String authority) {
return new AuthorityAuthorizationManager<>(authority);
}
// 是有有给定的角色列表中的任意权限
public static <T> AuthorityAuthorizationManager<T> hasAnyRole(String... roles) {
return hasAnyRole(ROLE_PREFIX, roles);
}
// 是有有给定的权限列表中的任意角色
public static <T> AuthorityAuthorizationManager<T> hasAnyRole(String rolePrefix, String[] roles) {
return hasAnyAuthority(toNamedRolesArray(rolePrefix, roles));
}
// 是有有给定的权限列表中的任意权限
public static <T> AuthorityAuthorizationManager<T> hasAnyAuthority(String... authorities) {
return new AuthorityAuthorizationManager<>(authorities);
}
// 将所有给定的角色添加角色前缀,在进行校验
private static String[] toNamedRolesArray(String rolePrefix, String[] roles) {
String[] result = new String[roles.length];
for (int i = 0; i < roles.length; i++) {
String role = roles[i];
Assert.isTrue(rolePrefix.isEmpty() || !role.startsWith(rolePrefix), () -> role + " should not start with "
+ rolePrefix + " since " + rolePrefix
+ " is automatically prepended when using hasAnyRole. Consider using hasAnyAuthority instead.");
result[i] = rolePrefix + role;
}
return result;
}
// 权限校验,调用代理的基于权限列表授权管理器进行权限校验
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
return this.delegate.check(authentication, this.authorities);
}
}
// 基于权限列表的权限管理器
public final class AuthoritiesAuthorizationManager implements AuthorizationManager<Collection<String>> {
// 默认的角色层次结构处理器为给定权限列表原样返回
// 获得认证用户的所有可访问的授予权限,其中包含角色的层次结构,例如 ADMIN > USER > sys:user:list
// 默认的roleHierarchy实现是不经过任何加工返回指定的权限
// 如果提供了roleHierarchy,则返回经过加工之后的权限列表
private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
// 设置指定的角色层次结构处理器
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
Assert.notNull(roleHierarchy, "roleHierarchy cannot be null");
this.roleHierarchy = roleHierarchy;
}
// 授权校验
@Override
public AuthorityAuthorizationDecision check(Supplier<Authentication> authentication, Collection<String> authorities) {
// 判断当前认证用户是否有权限
boolean granted = this.isGranted(authentication.get(), authorities);
// 返回权限的决策信息
return new AuthorityAuthorizationDecision(granted, AuthorityUtils.createAuthorityList(authorities));
}
// 是否有权限
private boolean isGranted(Authentication authentication, Collection<String> authorities) {
// 如果认证了,并且被授权了,只要认证的用户具有注解中标注的权限列表中的任意一个则有权限
return authentication != null && this.isAuthorized(authentication, authorities);
}
// 是否被授权了,只要认证的用户具有注解中标注的权限列表中的任意一个则有权限
private boolean isAuthorized(Authentication authentication, Collection<String> authorities) {
// 获得认证用户的所有可访问的授予权限,其中包含角色的层次结构,例如 ADMIN > USER > sys:user:list
// 默认的roleHierarchy实现是不经过任何加工返回指定的权限
// 如果提供了roleHierarchy,则返回经过加工之后的权限列表
Collection<? extends GrantedAuthority> grantedAuthorities = this.getGrantedAuthorities(authentication);
// 遍历处理之后用户认证的角色列表
for (GrantedAuthority grantedAuthority : grantedAuthorities) {
// 与注解中写的权限列表进行意义比较,如果有一个包含,那么直接返回true,表示有权限
// 因此@Secured注解中的权限列表式OR的关系,只要存在一个即有权限
if (authorities.contains(grantedAuthority.getAuthority())) {
return true;
}
}
return false;
}
// 获得认证用户的所有可访问的授予权限,其中包含角色的层次结构,例如 ADMIN > USER > sys:user:list
// 默认的roleHierarchy实现是不经过任何加工返回指定的权限
// 如果提供了roleHierarchy,则返回经过加工之后的权限列表
private Collection<? extends GrantedAuthority> getGrantedAuthorities(Authentication authentication) {
return this.roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
}
}
SpringSecutiry的核心注解实现原理解析
最新推荐文章于 2024-08-09 15:29:43 发布