将KeycloakSpring适配器与Sping Boot 3配合使用

mcvgt66p  于 2022-12-04  发布在  Spring
关注(0)|答案(2)|浏览(202)

我在一个使用Keycloak Spring适配器的项目中更新到了Sping Boot 3。不幸的是,它没有启动,因为KeycloakWebSecurityConfigurerAdapter扩展了WebSecurityConfigurerAdapter,后者在Spring Security中首先被弃用,然后被删除。目前是否有其他方法可以使用Keycloak实现安全性?或者换句话说:如何将Sping Boot 3与keycloak适配器结合使用?
我搜索了互联网,但找不到任何其他版本的适配器.

ovfsdjhp

ovfsdjhp1#

你不能在spring-boot 3中使用Keycloak适配器,因为你发现的原因,还有一些其他的与可传递依赖相关的原因。作为most Keycloak adapters were deprecated,很可能没有更新发布来修复这个问题。
直接使用spring-security OAuth2代替。不要惊慌,使用spring-boot这是一项简单的任务。

“官方”状态

有两个Spring启动器可以简化所有必需Bean的创建:

  • spring-boot-starter-oauth2-client,如果您的应用使用Thymeleaf或类似工具提供UI。客户端配置也可用于使用客户端凭据(WebClient@FeignClientRestTemplate)设置REST客户端。
  • spring-boot-starter-oauth2-resource-server,如果应用程序是REST API(提供资源,而不是操作资源的UI)。

以下是如何将具有唯一Keycloak领域的资源服务器配置为授权服务器:
第一个

Spring-附加起动器

如上所述,配置相当冗长(如果您使用多租户方案,事情会变得更加复杂),容易出错(例如,易于取消同步CSRF保护和会话配置)和侵入性(如果从属性文件控制所有配置,我编写了wrappers arround "official" starter,它非常精简(每个文件只由三个文件组成),并且极大地简化了资源服务器的配置:
第一个
而且,从issuers属性是一个数组可以猜到,您可以根据需要配置任意多个OIDC授权服务器示例(多个领域或示例,甚至不包括Keycloak)。

Edit:添加客户端配置

如果您的Spring应用程序还公开了您希望通过浏览器(使用OAuth2登录)访问的安全UI元素,则需要添加一个具有“client”配置的FilterChain。
将此添加到pom.xml

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>

(这是一个附加SecurityFilterChain,仅适用于下面的securityMatcher列表,保留上面为REST端点定义的resource-server SecurityFilterChain):

@Order(Ordered.HIGHEST_PRECEDENCE)
    @Bean
    SecurityFilterChain uiFilterChain(HttpSecurity http, ServerProperties serverProperties) throws Exception {

        // @formatter:off
        http.securityMatcher(new OrRequestMatcher(
                // add path to your UI elements instead
                new AntPathRequestMatcher("/ui/**"),
                // those two are required to access Spring generated login page
                // and OAuth2 client callback endpoints
                new AntPathRequestMatcher("/login/**"),
                new AntPathRequestMatcher("/oauth2/**")));

        http.oauth2Login();
        http.authorizeHttpRequests()
                .requestMatchers("/ui/index.html").permitAll()
                .requestMatchers("/login/**").permitAll()
                .requestMatchers("/oauth2/**").permitAll()
                .anyRequest().authenticated();
        // @formatter:on

        // If SSL enabled, disable http (https only)
        if (serverProperties.getSsl() != null && serverProperties.getSsl().isEnabled()) {
            http.requiresChannel().anyRequest().requiresSecure();
        } else {
            http.requiresChannel().anyRequest().requiresInsecure();
        }

        // Many defaults are kept compared to API filter-chain:
        // - sessions (and CSRF protection) are enabled
        // - unauthorized requests to secured resources will be redirected to login (302 to login is Spring's default response when access is denied)

        return http.build();
    }

和上次客户端属性:

spring.security.oauth2.client.provider.keycloak.issuer-uri=https://localhost:8443/realms/master

spring.security.oauth2.client.registration.spring-addons-public.provider=keycloak
spring.security.oauth2.client.registration.spring-addons-public.client-name=spring-addons-public
spring.security.oauth2.client.registration.spring-addons-public.client-id=spring-addons-public
spring.security.oauth2.client.registration.spring-addons-public.scope=openid,offline_access,profile
spring.security.oauth2.client.registration.spring-addons-public.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.spring-addons-public.redirect-uri=http://bravo-ch4mp:8080/login/oauth2/code/spring-addons-public
bfrts1fy

bfrts1fy2#

使用标准的Spring Security OAuth2客户端而不是特定的Keycloak适配器,使用SecurityFilterChain而不是WebSecurityAdapter
大概是这样的:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true)
class OAuth2SecurityConfig {

@Bean
fun customOauth2FilterChain(http: HttpSecurity): SecurityFilterChain {
    log.info("Configure HttpSecurity with OAuth2")

    http {
        oauth2ResourceServer {
            jwt { jwtAuthenticationConverter = CustomBearerJwtAuthenticationConverter() }
        }
        oauth2Login {}

        csrf { disable() }

        authorizeRequests {
            // Kubernetes
            authorize("/readiness", permitAll)
            authorize("/liveness", permitAll)
            authorize("/actuator/health/**", permitAll)
            // ...
            // everything else needs at least a valid login, roles are checked at method level
            authorize(anyRequest, authenticated)
        }
    }

    return http.build()
}

然后在application.yml中:

spring:
  security:
    oauth2:
      client:
        provider:
          abc:
            issuer-uri: https://keycloak.../auth/realms/foo
        registration:
          abc:
            client-secret: ...
            provider: abc
            client-id: foo
            scope: [ openid, profile, email ]
      resourceserver:
        jwt:
          issuer-uri: https://keycloak.../auth/realms/foo

相关问题