spring security权限配置问题

问题描述

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = http.authorizeRequests();
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry1 = http.authorizeRequests();
        http.authorizeRequests()
//                .antMatchers(PERMIT_ALL_MAPPING)
//                .permitAll()
                .antMatchers( "/api/data")
                // USER 和 ADMIN 都可以访问
                .hasAnyAuthority(USER)
                .antMatchers("/api/user/**",  "/api/logout")
                // USER 和 ADMIN 都可以访问
                .hasAnyAuthority("all")
//                .hasAnyAuthority("all")// 允许所有权限
                .antMatchers("/api/admin/**", "/api/**")
                // 只有 ADMIN 才可以访问
                .hasAnyAuthority(ADMIN, USER, "asdfasd")
                .anyRequest()
                .authenticated()
                .and()
                // 添加过滤器链,前一个参数过滤器, 后一个参数过滤器添加的地方
                // 登陆过滤器
                .addFilterBefore(new JwtLoginFilter("/api/login", authenticationManager(), loginCountService), UsernamePasswordAuthenticationFilter.class)
                // 请求过滤器
                .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                // 开启跨域
                .cors()
                .and()
                // 开启 csrf
                .csrf()
                 .disable()
//                .ignoringAntMatchers(PERMIT_ALL_MAPPING)
//                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
//                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

按照上述方式配置权限,一个具有ADMIN权限的账户访问/api/data接口时是否能够成功?
观点1:/api/data接口符合这段配置,所以应该仅限USER权限才能访问

                .antMatchers( "/api/data")
                // USER 和 ADMIN 都可以访问
                .hasAnyAuthority(USER)

观点2:/api/data接口符合这段配置,ADMIN权限可以访问

                .antMatchers("/api/admin/**", "/api/**")
                // 只有 ADMIN 才可以访问
                .hasAnyAuthority(ADMIN, USER, "asdfasd")

观点1和观点2冲突

结论

无法访问。程序会按照下面的对/api/data这个请求仅限校验。

                .antMatchers( "/api/data")
                // USER 和 ADMIN 都可以访问
                .hasAnyAuthority(USER)

当一个url匹配多个规则时,先配置的规则有效。先配置的那个规则校验成功,那么就有权限访问资源,否则就没有权限访问资源。
此外,若antMatchers中有完全一模一样的url同时被配置多次,且权限不同,程序会按照最后那个为准。
比如下面这段代码把/api/data的权限配置了三次,当运行时会按照(ADMIN, USER, “asdfasd”)仅限权限校验。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = http.authorizeRequests();
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry1 = http.authorizeRequests();
        http.authorizeRequests()
//                .antMatchers(PERMIT_ALL_MAPPING)
//                .permitAll()
                .antMatchers( "/api/data")
                // USER 和 ADMIN 都可以访问
                .hasAnyAuthority(USER)
                .antMatchers("/api/data")
                // USER 和 ADMIN 都可以访问
                .hasAnyAuthority("all")
//                .hasAnyAuthority("all")// 允许所有权限
                .antMatchers("/api/data")
                // 只有 ADMIN 才可以访问
                .hasAnyAuthority(ADMIN, USER, "asdfasd")
                .anyRequest()
                .authenticated()
                .and()
                // 添加过滤器链,前一个参数过滤器, 后一个参数过滤器添加的地方
                // 登陆过滤器
                .addFilterBefore(new JwtLoginFilter("/api/login", authenticationManager(), loginCountService), UsernamePasswordAuthenticationFilter.class)
                // 请求过滤器
                .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                // 开启跨域
                .cors()
                .and()
                // 开启 csrf
                .csrf()
                 .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

代码分析

初始化阶段将配置的权限信息保存成一个list,然后根据list生成map。处理请求时根据map校验权限。

生成list

根据配置生成org.springframework.security.config.annotation.web.configurers.AbstractConfigAttributeRequestMatcherRegistry#urlMappings这个list

调用org.springframework.security.config.annotation.web.configurers.AbstractConfigAttributeRequestMatcherRegistry#addMapping(org.springframework.security.config.annotation.web.configurers.AbstractConfigAttributeRequestMatcherRegistry.UrlMapping)将配置中的权限信息设置到list中

生成map

应用启动时根据list生成org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource#requestMap这个map

先调用org.springframework.security.config.annotation.web.configurers.AbstractConfigAttributeRequestMatcherRegistry#createRequestMap将list转换成map

然后调用org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource#DefaultFilterInvocationSecurityMetadataSource将数据设置到org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource#requestMap,以便之后对请求进行权限校验
在这里插入图片描述

根据map判断权限

org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource#getAttributes
在这里插入图片描述

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值