Spring Security:基于客户机权限的安全端点

我目前正在使用Spring Security的OAuth2来实现跨多个微服务的授权。 我们的AuthService使用OAuth2令牌执行所有的身份验证,并可以创建用户。

考虑两个客户端:客户端A和客户端B.

客户端A具有权限: CREATE_USER, CREATE_POST客户端B具有权限: READ_USER

(是的,我们可以使用范围,但这只是一个例子!)

目标:

只有拥有权限CREATE_USER客户端A才能被允许创建一个用户。 用户正在通过张贴到/users创建。

问题:

问题是,当我发送一个POST请求到用户A的基本身份验证头的/用户端点时, CREATE_USER权限,因为请求命中了AnonymousAuthenticationFilter ,唯一发现的权限是ROLE_ANONYMOUS ,我收到以下内容:

 10:38:34.852 [http-nio-9999-exec-1] DEBUG osswaiFilterSecurityInterceptor - Secure object: FilterInvocation: URL: /users; Attributes: [#oauth2.throwOnError(#oauth2.hasAuthority('CREATE_USER))] 10:38:34.852 [http-nio-9999-exec-1] DEBUG osswaiFilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS 10:38:34.854 [http-nio-9999-exec-1] DEBUG ossaccess.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@a63e3e8, returned: -1 10:38:34.856 [http-nio-9999-exec-1] DEBUG osswaExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point org.springframework.security.access.AccessDeniedException: Access is denied 

一个令人难以置信的解决方法是注册一个自定义的安全过滤器,读取基本的auth头,并验证客户端的名称是否等于客户端A,但这不会为第三个客户端,即也具有CREATE_VIEWER权限的客户端C在这里验证的名称,而不是当局。

 // UsersController.kt @PostMapping("/users") @ResponseStatus(HttpStatus.OK) @ResponseBody fun createUser(): String { return "Created user!" } 

客户端配置

 override fun configure(clients: ClientDetailsServiceConfigurer?) { clients!!.inMemory() .withClient("ClientA") .scopes("all") .authorities("CREATE_USER", "CREATE_POST") .authorizedGrantTypes("refresh_token", "password") .and() .withClient("ClientB") .scopes("all") .authorities("READ_USER") .authorizedGrantTypes("refresh_token", "password") } 

WebSecurityConfigurerAdaptor impl

 override fun configure(http: HttpSecurity) { http.requestMatchers().antMatchers("/oauth/authorize", "/oauth/confirm_access") .and() .authorizeRequests() .antMatchers("/users").access("hasAuthority('CREATE_USER')") .anyRequest().authenticated() .and() .csrf().disable() } override fun configure(auth: AuthenticationManagerBuilder) { auth.authenticationProvider(authenticationProvider()) } @Bean open fun authenticationProvider(): DaoAuthenticationProvider { val authProvider = DaoAuthenticationProvider() authProvider.setUserDetailsService(userCredentialService) authProvider.setPasswordEncoder(passwordEncoderService) return authProvider }