SpringSecurityOAuth2(4) Dynamic permission judgment based on request URI (supplement)

GitHub address

Code cloud address

above address

In addition to the optimization of judging access permissions based on URIs above, the above method can only obtain a single permission based on URIs, and cannot satisfy requests that URIs can access based on multiple ORs.

Optimization content: first increase the level of access to the uri and then determine what permissions are required for the uri, multiple and multiple permissions, etc., and then intercept and judge through the permission judger

Create a new custom url permission to judge MyFilterInvocationSecurityMetadataSource to implement FilterInvocationSecurityMetadataSource

/**
 * @Description 根据url获取 url需要访问的权限
 * @Author wwz
 * @Date 2019/08/01
 * @Param
 * @Return
 */
@Component
public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    private AntPathMatcher antPathMatcher = new AntPathMatcher(); // 模糊匹配 如何 auth/**   auth/auth

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        Set<ConfigAttribute> set = new HashSet<>();

        String requestUrl = ((FilterInvocation) object).getRequest().getMethod() + ((FilterInvocation) object).getRequest().getRequestURI();
        System.out.println("requestUrl >> " + requestUrl);

        // 这里获取对比数据可以从数据库或者内存 redis等等地方获取 目前先写死后面优化
        String url = "GET/auth/**";
        if (antPathMatcher.match(url, requestUrl)) {
            SecurityConfig securityConfig = new SecurityConfig("ROLE_ADMIN");
            set.add(securityConfig);
        }
        if (ObjectUtils.isEmpty(set)) {
            return SecurityConfig.createList("ROLE_LOGIN");
        }
        return set;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }
}

Modify the original decision of MySecurityAccessDecisionManager, and change the permission from the url obtained to the obtained permission. Other judgments remain unchanged

    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

        System.out.println("collection>>" + configAttributes);

        for (ConfigAttribute configAttribute : configAttributes) {
            // 当前请求需要的权限
            String needRole = configAttribute.getAttribute();
            // 当前用户所具有的权限
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            System.out.println("authorities=" + authorities);
            for (GrantedAuthority grantedAuthority : authorities) {
                if (grantedAuthority.getAuthority().equals(needRole)) {
                    return;
                }
                if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
                    return;
                }

            }
        }
        throw new AccessDeniedException("无访问权限");
    }

Override method to register MyFilterInvocationSecurityMetadataSource to MySecurityResourceServerConfig

 public void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // 另外,如果不设置,那么在通过浏览器访问被保护的任何资源时,每次是不同的SessionID,并且将每次请求的历史都记录在OAuth2Authentication的details的中
                .and()
                .authorizeRequests().antMatchers("/actuator/health").permitAll().anyRequest().authenticated()  // httpSecurity 放过健康检查,其他都需要验证  设置了.anyRequest().authenticated()才回进入自定义的权限判断
                .and()
                .requestMatchers().antMatchers("/auth/**") // .requestMatchers().antMatchers(...) OAuth2设置对资源的保护如果是用 /**的话 会把上面的也拦截掉
                .and()
                .authorizeRequests()
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {       // 重写做权限判断
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                        o.setSecurityMetadataSource(filterInvocationSecurityMetadataSource); // 请求需要权限
                        o.setAccessDecisionManager(accessDecisionManager);      // 权限判断
                        return o;
                    }
                })
                .and()
                .httpBasic();

        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
    }

Try and request print info:

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324136431&siteId=291194637