当前位置: 首页 > 知识库问答 >
问题:

只使用keycloak进行身份验证,并使用自定义过滤器进行授权(Spring Boot)

明财
2023-03-14

我试图使用keycloak只用于身份验证,并有自己的自定义过滤器用于授权。因此理想的流程是:首先,Keycloak filter对请求进行身份验证,并在上下文中设置身份验证对象。然后,我的自定义过滤器应该运行,它应该获得现有的身份验证对象,在该身份验证对象中添加权限,并将其设置回上下文中。

@Configuration
@EnableWebSecurity
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
   {
      super.configure(http);
        http
        .cors()
        .and()
        .csrf().ignoringAntMatchers("/","/auth","/auth/logout").csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .authorizeRequests()
        .antMatchers(
                "/",
                "/auth",
                "/password/**",
              "/register/**",
              "/v2/api-docs",
              "/actuator/**",
              "/configuration/ui",
              "/swagger-resources",
              "/configuration/security",
              "/swagger-ui.html",
              "/webjars/**",
              "/swagger-resources/configuration/ui",
              "/swagger-resources/configuration/security",
              "/browser/index.html#",
              "/browser/**").permitAll()
        .antMatchers(HttpMethod.POST, REGISTER).permitAll()
        .antMatchers(HttpMethod.POST, CONFIRM).permitAll()
        .anyRequest().authenticated()
        .and()
        .addFilter(new JWTAuthorizationFilter(authenticationManager(),context))
//      .addFilterAfter(new JWTAuthorizationFilter(authenticationManager(),context), KeycloakAuthenticationProcessingFilter.class)
        .headers()
        .contentSecurityPolicy("script-src 'self'");
}

因此,首先,在speing引导应用程序中使用keycloak是正确的方法吗?如果是,那么如何使我的过滤器在过滤器链中最后运行呢?

共有1个答案

曾德水
2023-03-14

您似乎将两个范例混合在一起,1)使用keycloak作为授权服务器,2)尝试将JWTs用于auth(诱惑化)中的一个或两个。

请参阅Spring Security的Josh Cummings最近制作的关于何时使用JWTs以及如何使用Spring Security 5的视频。另外,请查看JWT示例,它完全替换了JWTauthEnticationFilter,而不使用keycloak-spring-security-adapter。您还可以查看OAuth2登录示例,了解如何使用Spring Security开始进行社交登录。

就具体使用keycloak而言,我建议使用Spring Security 5的内置功能,它与keycloak的授权服务器完全集成,应该可以同时实现这两个目标。

docker run --name keycloak -p 9000:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e DB_VENDOR=h2 -d jboss/keycloak
127.0.0.1       auth-server

使用admin:admin登录到keycloak后,我设置了一个名为MyRealm的领域和一个名为test-client的客户端,该客户端的有效重定向uri为http://localhost:8080/*,另一个作用域为resource:read,生成了一个客户端机密,最后创建了一个具有凭据的用户

TLDR:GitHub示例

要开始,请确保类路径上有以下依赖项:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
server:
  port: 8080

keycloak-server:
  uri: http://auth-server:9000/auth/realms/myrealm
  openid-uri: ${keycloak-server.uri}/protocol/openid-connect

spring:
  security:
    oauth2:
      client:
        registration:
          test-client:
            provider: keycloak
            client-id: test-client
            client-secret: ${TEST_CLIENT_SECRET:your-client-secret}
            client-authentication-method: client_secret_basic
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            scope: resource:read
        provider:
          keycloak:
            # Configure the provider with keycloak
            authorization-uri: ${keycloak-server.openid-uri}/auth
            token-uri: ${keycloak-server.openid-uri}/token
            user-info-uri: ${keycloak-server.openid-uri}/userinfo
            user-info-authentication-method: client_secret_basic
            jwk-set-uri: ${keycloak-server.openid-uri}/certs
            # Alternatively, set issuer-uri (replaces above settings) to use ${keycloak-server.uri}/.well-known/openid-configuration
            # to auto-configure OpenID Connect on startup.
            # issuer-uri: ${keycloak-server.uri}
            # This is required in either case to inform Spring Security about keycloak's username
            user-name-attribute: preferred_username

logging:
  level:
    org.springframework.security: trace

下面是一个示例控制器来证明它是有效的:

java prettyprint-override">@RestController
public class ExampleController {
    @GetMapping("/")
    public Map<String, String> home(@AuthenticationPrincipal DefaultOAuth2User user) {
        return Map.of("message", "You are logged in, " + user.getName() + "!");
    }

    @GetMapping("/token")
    public OAuth2AccessToken token(@RegisteredOAuth2AuthorizedClient("test-client") OAuth2AuthorizedClient testClient) {
        return testClient.getAccessToken();
    }
}

这通常足以使用KeyCloak进行身份验证。如果希望对Spring Security性进行更细粒度的控制,请使用以下配置开始:

@EnableWebSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .authorizeRequests(authorizeRequests -> authorizeRequests
                .antMatchers("/token").hasAuthority("SCOPE_resource:read")
                .anyRequest().authenticated()
            )
            .oauth2Client(withDefaults())
            .oauth2Login(withDefaults());
        // @formatter:on

        return http.build();
    }

}

这个示例使用Spring Security5对OAuth2.0和OpenID Connect1.0的开箱即用支持和KeyCloak。

请注意,您不需要自定义筛选器来从keycloak获得权限,我们只是请求resource:read作用域可用,Spring Security与keycloak一起工作,以确保我们拥有该权限。我们也没有使用JWTs进行身份验证,而是使用标准会话管理,这是推荐的。

 类似资料:
  • 在过去的几周里,我一直在努力掌握KeyClope,这样我就可以实现一种使用遗留提供商(基于Oracle,带有会话表和各种奇怪的东西)对用户进行身份验证的方法。我们计划在不久的将来解决这个问题,但目前我们必须解决这个问题,所以我们的想法是在前线使用KeyClope——利用它提供的主要好处,比如SSO——在需要身份验证的应用程序中省略传统的身份验证提供程序。 我读了一些关于构建自定义OIDC身份提供程

  • 我实现了一个自定义的身份验证过滤器,效果很好。在设置会话并将身份验证对象添加到安全上下文后,我使用外部身份提供程序并重定向到最初请求的URL。 安全配置 过滤逻辑 目前,我的自定义过滤器(身份确认后)只需硬编码一个角色: 然后将该身份验证对象(上面返回)添加到我的SecurityContext,然后再重定向到所需的endpoint: SecurityContextHolder.getContext

  • 我正在尝试使用Sprint安全框架在Spring Boot中为我的HTTP请求设置授权。我是Spring Security的新手,我找不到任何关于我的情况的文档。 我知道我们必须重写WebSecurity配置适配器方法-configure(AuthenticationManagerBuilder) 这是我试图建立的流程。我的前端和后端托管在不同的域中,所以我也在寻找跨来源的授权。通过发布到REST

  • 我有一个移动(本机)和Web应用程序(SPA),它与后端微服务(在核心2.0中开发)对话,以进行身份验证/授权和其他与域相关的功能,该功能已使用Opendi的配置。这两个应用程序都获得了访问令牌。我遇到的问题是,所有微服务都应该接受无记名访问令牌和登录用户的身份验证/授权(中央身份验证服务),在身份验证微服务中生成的访问令牌(开放身份验证2.*)。那么,我在微服务中缺少哪些更改,其中REST AP

  • 本文向大家介绍JSP使用Servlet过滤器进行身份验证的方法,包括了JSP使用Servlet过滤器进行身份验证的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JSP使用Servlet过滤器进行身份验证的方法。分享给大家供大家参考,具体如下: 1、Servlet过滤器的作用描述 (1)在HttpServletRequest到达Servlet 之前,拦截客户的HttpServletRe

  • 在我使用RESTful webservices的Spring Boot应用程序中,我将Spring Security与Spring Social和一起配置了。 现在我有两种身份验证/授权方式--通过用户名/密码和通过社交网络,比如Twitter。 为了通过Spring MVC REST控制器中自己的RESTfulendpoint实现身份验证/授权,我添加了以下方法: 但我不确定在成功调用endpo