java - 为什么我收到 Spring Security 和 Keycloak 的“访问被拒绝”错误?
问题描述
我用 Docker 设置了一个 Keycloak 服务器。配置领域和客户端等。我成功地为一些 RestControllers 编写了 Spring Boot 服务。工作等等。
但是当我尝试将 Spring Security 与 Keycloak Adapter 一起使用时,我被卡住了。
这是我的安全配置:
@KeycloakConfiguration
class SecurityConfig : KeycloakWebSecurityConfigurerAdapter() {
@Autowired
lateinit var keycloakClientRequestFactory: KeycloakClientRequestFactory
@Bean
fun keycloakConfigResolver(): KeycloakSpringBootConfigResolver = KeycloakSpringBootConfigResolver()
@Bean
override fun sessionAuthenticationStrategy(): SessionAuthenticationStrategy =
NullAuthenticatedSessionStrategy()
@Autowired
@Throws(Exception::class)
fun configureGlobal(auth: AuthenticationManagerBuilder) {
val keycloakAuthProvider: KeycloakAuthenticationProvider = keycloakAuthenticationProvider()
keycloakAuthProvider.setGrantedAuthoritiesMapper(SimpleAuthorityMapper())
auth.authenticationProvider(keycloakAuthProvider)
}
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
super.configure(http)
http.cors().disable()
.csrf().disable()
.exceptionHandling().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionAuthenticationStrategy(sessionAuthenticationStrategy()).and()
.formLogin().disable()
.authorizeRequests()
.antMatchers("/apps/manual-data-collection/**").hasRole("user")
.anyRequest().permitAll()
}
/**
* https://www.keycloak.org/docs/latest/securing_apps/index.html#avoid-double-bean-registration
*/
@Bean
@ConditionalOnMissingBean(HttpSessionManager::class)
override fun httpSessionManager(): HttpSessionManager = HttpSessionManager()
}
现在我尝试访问服务器,但得到 403 Forbidden Error。以下是春季的日志:
2020-01-08 14:08:01.817 DEBUG 12396 --- [nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/apps/manual-data-collection/document-templates'; against '/apps/manual-data-collection/**'
2020-01-08 14:08:01.817 DEBUG 12396 --- [nio-8080-exec-5] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /apps/manual-data-collection/document-templates; Attributes: [hasRole('ROLE_user')]
2020-01-08 14:08:01.817 DEBUG 12396 --- [nio-8080-exec-5] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@bc432bbc: Principal: willy; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@42db7613; Not granted any authorities
2020-01-08 14:08:01.818 DEBUG 12396 --- [nio-8080-exec-5] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@3d0602a7, returned: -1
2020-01-08 14:08:01.818 DEBUG 12396 --- [nio-8080-exec-5] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is not anonymous); delegating to AccessDeniedHandler
org.springframework.security.access.AccessDeniedException: Access is denied
让我感到困惑的是,它说:Not granted any authorities
. 如果我省略部分,一切正常。必要的角色(在本例中为“用户”)存储在领域中。JWT 令牌也提供这些。我不知道为什么它不起作用。
编辑:我应该提一下。Spring Boot Server 只能用作 Angular 应用程序的 REST 服务器,因此STATELESS
.
解决方案
好吧,我发现了我的错误。我在 application.yml 中激活了以下内容:
keycloak.use-resource-role-mappings=true
但它必须是false
。Keycloak 文档如下:
use-resource-role-mappings - 如果设置为 true,适配器将在令牌内部查找用户的应用程序级角色映射。如果为 false,它将查看域级别的用户角色映射。这是可选的。默认值为假。
推荐阅读
- java - 无法连接到主机,端口:smtp.gmail.com, 587;超时 -1
- android - 片段回栈和替换
- batch-file - 我需要找到并插入一个值
- javascript - Cypress.io - 使用 JavaScript window.prompt 保存价值
- flutter - 在cmd上执行flutter build apk时构建失败
- php - 如何使用队列将数据传递到邮件视图?
- spring-boot - 谷歌日历域范围访问 401 日历
- vue.js - 特定条件下的类和样式绑定
- r - 恢复多次导入期间导入的文件数量
- django - Django forms.ModelMultipleChoiceField 没有保存任何东西