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

Spring cloud gateway+keycloak正在返回404(未找到)

皇甫波峻
2023-03-14

我将使用此jwt令牌对api-gateway进行另一次调用,以访问受保护的服务。
API gateway
API gateway项目具有以下相关依赖项:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.keycloak.bom</groupId>
                <artifactId>keycloak-adapter-bom</artifactId>
                <version>11.0.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>
      <!-- Gateway functionality -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!-- keycloak Spring Boot Adapter -->
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

我在application-dev.yml中设置了这个配置

server:
  port: 8082
cluster:
  uri-local-be: http://localhost:8083
keycloak:
  enabled: true
  realm: my_realm
  # The value we specify in keycloak.resource matches the client we named in the admin console
  resource: niuma-services
  auth-server-url: http://localhost:8080/auth
  bearer-only: true
  principal-attribute: preferred_username
  public-client: true
spring:
  ...
  cloud:
    gateway:
      routes:
        - id: protected
          uri: ${cluster.uri-local-be}
          predicates:
          - Path=/api/hello/*

您可以看到寻址服务的路由(当时没有服务发现)。我实现了一个SecurityConfig类,如教程中所示:

@Configuration
@EnableWebSecurity(debug = true)
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@Slf4j
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        log.info("SecurityConfig.configureGlobal");
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        log.info("SecurityConfig.KeycloakConfigResolver");
        return new KeycloakSpringBootConfigResolver();
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        log.info("SecurityConfig.sessionAuthenticationStrategy");
        return new NullAuthenticatedSessionStrategy();
    }

    @Bean
    public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
            KeycloakAuthenticationProcessingFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(KeycloakPreAuthActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        log.info("SecurityConfig.configure");
        super.configure(http);
        http.authorizeRequests().antMatchers("/spi*").hasRole("user").anyRequest().permitAll();
    }

    @Bean
    public ServerCodecConfigurer serverCodecConfigurer() {
        return ServerCodecConfigurer.create();
    }

o.s.security.web.FilterChainProxy        : /error at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
o.s.security.web.FilterChainProxy        : /error at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@7102dd3c: Authentication: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@7102dd3c: Principal: ciro; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@42a60ed1; Granted Authorities: ROLE_offline_access, ROLE_user, ROLE_uma_authorization'
...
o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/sso/login']
o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/sso/login'
...
f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
o.k.a.BearerTokenRequestAuthenticator    : Found [1] values in authorization header, selecting the first value for Bearer.
...
o.k.a.BearerTokenRequestAuthenticator    : successful authorized
o.k.adapters.RequestAuthenticator        : User 'ciro' invoking 'http://localhost:8082/error' on client 'niuma-services'
...
o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
...
o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 404, headers={masked}
...

希望我报告了所有需要的信息,我会请求一些帮助,使用从keycloak获得的访问令牌,调用api网关来进行身份验证。

共有1个答案

何博涛
2023-03-14

显然,如应用程序启动日志所示,spring MVC目前与spring Cloud Gateway(版本Hoxton.SR8)不兼容,日志上的消息如下:

在类路径上发现了Spring MVC,此时与Spring云网关不兼容。请删除spring-boot-starter-web依赖项。

您的依赖项keycloak-spring-boot-starter包括spring-boot-starter-web

 类似资料:
  • 我有一个xamarin应用程序,可以从webAPI中提取数据。我多次检查api地址,我确信它是正确的。当我调试代码时,服务器上出现404 not found错误。然而,当我将URL复制并粘贴到浏览器时,我得到了预期的结果。我不明白为什么我的应用程序返回404。 我的方法: 我的桥接方法到HttpClient的PostAsync方法: 代币:正确 API URL:正确(我从调试输出中检查“/”符号。

  • 我正在用Laravel 8制作一个论坛,基本上每当用户在这个论坛上提问时,它应该被重定向到这个问题。 我还想使重定向过程基于问题的字段。

  • 我创建了一个部署、一个服务和一个入口,以便能够从我的主机访问NGINX web服务器,但我一直没有找到404。经过长时间的故障排除,我已经到了一个非常欢迎帮助的地步。 步骤和相关yaml文件如下所示。 启用Minikube NGINX入口控制器 minikube插件支持入口 创建NGINX web服务器部署 创建ClusterIP服务以管理对POD的访问 创建入口以从集群外部访问服务 测验 连接到

  • 我用Spring 4和Spring security设置了一个简单的REST API web.xml AccountController.java mysabisabi-servlet.xml mysabisabi-security.xml 应用程序上下文.xml 日志文件 当我尝试访问 我得到 我已经尝试了 和作为url模式,但仍然相同。 有人能指出我错过了什么吗? 谢了。

  • 我正在按照一些教程从头开始建立一个spring mvc项目。最初,我将web应用程序配置为在Tomcat中运行。我编写了一个简单的controller类,请求点击“/”。但tomcat总是向我显示“HTTP状态404-找不到”错误。 我看了很多这样的问题,但那些答案对我都不起作用 删除tomcat安装并重新配置。当点击localhost:8080/时,我将获得tomcat主页。 检查了代码的拼写

  • 当我从JavaScript客户端调用AWS API网关时,会出现404 not found错误,因为SDK调用了错误的endpoint: https://www.myserver.com/abc123.execute-api.us-east-1.amazonaws.com/dev/status 而不是 https://abc123.execute-api.us-east-1.amazonaws.c