spring security关键类

@EnableResourceServer进行资源权限判断,每个微服务视为一个资源
@EnableGlobalMethodSecurity(prePostEnabled = true) 权限验证精确到Controller具体的方法

 @EnableResourceServer会增加自动配置ResourceServerSecurityConfigurer,其中含有过滤器,权限验证管理类,token存储,resourceid等权限验证相关的配置,并且使用OAuth2AuthenticationManager验证权限

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ResourceServerConfiguration.class})
public @interface EnableResourceServer {
}
public final class ResourceServerSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
    private AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
    private AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler();
    private OAuth2AuthenticationProcessingFilter resourcesServerFilter;
    private AuthenticationManager authenticationManager;
    private AuthenticationEventPublisher eventPublisher = null;
    private ResourceServerTokenServices resourceTokenServices;
    private TokenStore tokenStore = new InMemoryTokenStore();
    private String resourceId = "oauth2-resource";
    private SecurityExpressionHandler<FilterInvocation> expressionHandler = new OAuth2WebSecurityExpressionHandler();
    private TokenExtractor tokenExtractor;
    private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource;
    private boolean stateless = true;

 

    private AuthenticationManager oauthAuthenticationManager(HttpSecurity http) {
        OAuth2AuthenticationManager oauthAuthenticationManager = new OAuth2AuthenticationManager();

首先按照resourceId验证权限(ResourceServerSecurityConfigurer中默认的资源id都是相同的) ,

public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if (authentication == null) {
            throw new InvalidTokenException("Invalid token (token not found)");
        } else {
            String token = (String)authentication.getPrincipal();
            OAuth2Authentication auth = this.tokenServices.loadAuthentication(token);
            if (auth == null) {
                throw new InvalidTokenException("Invalid token: " + token);
            } else {
                Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds();
                if (this.resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(this.resourceId)) {
                    throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + this.resourceId + ")");
                } else {
                    this.checkClientDetails(auth);
                    if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
                        OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)authentication.getDetails();
                        if (!details.equals(auth.getDetails())) {
                            details.setDecodedDetails(auth.getDetails());
                        }
                    }

                    auth.setDetails(authentication.getDetails());
                    auth.setAuthenticated(true);
                    return auth;
                }
            }
        }
    }

 

ClientDetailsService

 @EnableGlobalMethodSecurity:

//开启spring security 方法权限验证注解
@EnableGlobalMethodSecurity(prePostEnabled = true)

 

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({GlobalMethodSecuritySelector.class})
@EnableGlobalAuthentication
@Configuration
public @interface EnableGlobalMethodSecurity {
final class GlobalMethodSecuritySelector implements ImportSelector {
    GlobalMethodSecuritySelector() {
    }

    public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
        Class<EnableGlobalMethodSecurity> annoType = EnableGlobalMethodSecurity.class;
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(annoType.getName(), false);
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(annotationAttributes);
        Assert.notNull(attributes, () -> {
            return String.format("@%s is not present on importing class '%s' as expected", annoType.getSimpleName(), importingClassMetadata.getClassName());
        });
        Class<?> importingClass = ClassUtils.resolveClassName(importingClassMetadata.getClassName(), ClassUtils.getDefaultClassLoader());
        boolean skipMethodSecurityConfiguration = GlobalMethodSecurityConfiguration.class.isAssignableFrom(importingClass);
        AdviceMode mode = (AdviceMode)attributes.getEnum("mode");
        boolean isProxy = AdviceMode.PROXY == mode;
        String autoProxyClassName = isProxy ? AutoProxyRegistrar.class.getName() : GlobalMethodSecurityAspectJAutoProxyRegistrar.class.getName();
        boolean jsr250Enabled = attributes.getBoolean("jsr250Enabled");
        List<String> classNames = new ArrayList(4);
        if (isProxy) {
            classNames.add(MethodSecurityMetadataSourceAdvisorRegistrar.class.getName());
        }

        classNames.add(autoProxyClassName);
        if (!skipMethodSecurityConfiguration) {
            classNames.add(GlobalMethodSecurityConfiguration.class.getName());
        }

        if (jsr250Enabled) {
            classNames.add(Jsr250MetadataSourceConfiguration.class.getName());
        }

        return (String[])classNames.toArray(new String[0]);
    }
}

下面两行将import GlobalMethodSecurityConfiguration,然后在配置类中完成配置

boolean skipMethodSecurityConfiguration = GlobalMethodSecurityConfiguration.class.isAssignableFrom(importingClass);
if (!skipMethodSecurityConfiguration) {
    classNames.add(GlobalMethodSecurityConfiguration.class.getName());
}
@Configuration
public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInitializingSingleton, BeanFactoryAware {
    private static final Log logger = LogFactory.getLog(GlobalMethodSecurityConfiguration.class);
    private ObjectPostProcessor<Object> objectPostProcessor = new ObjectPostProcessor<Object>() {
        public <T> T postProcess(T object) {
            throw new IllegalStateException(ObjectPostProcessor.class.getName() + " is a required bean. Ensure you have used @" + EnableGlobalMethodSecurity.class.getName());
        }
    };
    private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();
    private AuthenticationManager authenticationManager;
    private AuthenticationManagerBuilder auth;
    private boolean disableAuthenticationRegistry;
    private AnnotationAttributes enableMethodSecurity;
    private BeanFactory context;
    private MethodSecurityExpressionHandler expressionHandler;
    private MethodSecurityInterceptor methodSecurityInterceptor;

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值