Spring Security:基于客户端权限保护端点

时间:2017-08-16 08:45:06

标签: spring-boot spring-security kotlin

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

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

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

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

目的:

只允许具有权限CREATE_USER的客户端A创建用户。用户通过发布到/users来创建。

问题:

问题是当我向/ users端点发送POST请求并使用客户端A的基本身份验证标头时,找不到CREATE_USER权限,因为请求命中AnonymousAuthenticationFilter而且只有ROLE_ANONYMOUS找到的权限是10:38:34.852 [http-nio-9999-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /users; Attributes: [#oauth2.throwOnError(#oauth2.hasAuthority('CREATE_USER))] 10:38:34.852 [http-nio-9999-exec-1] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - 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 o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@a63e3e8, returned: -1 10:38:34.856 [http-nio-9999-exec-1] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point org.springframework.security.access.AccessDeniedException: Access is denied ,我收到以下内容:

CREATE_VIEWER

一个令人难以置信的hacky解决方案是注册一个自定义安全过滤器,该过滤器读取基本auth标头并验证客户端的名称是否等于客户端A,但这不适用于第三个客户端,即客户端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")

}

客户端配置

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
}

WebSecurityConfigurerAdaptor impl

function chk()
{
    var sname = $('#app_for_class').find(":selected").text();
    if(sname==='LKG')
    {
         $('#date').datetimepicker({
        minDate:'2013-01-1',
        maxDate:'2015-11-30',

    });

    }


}

0 个答案:

没有答案