ch4mpy / spring-addons

Ease spring OAuth2 resource-servers configuration and testing
Apache License 2.0
521 stars 84 forks source link

Getting response 401 (Unauthorized) for permit-all requests after update #188

Closed TheNullablePrototype closed 6 months ago

TheNullablePrototype commented 6 months ago

Describe the bug I am using the BFF tutorial to develop a SPA Vue.js + Spring Boot. Today I updated spring-addons-starter-oidc from version 7.3.5 to 7.5.+, after restarting all services (REST and Gateway), I found that I get an error message for all permit-all requests after keycloak(docker 23.0.4) authorization (without authorization all requests are 200). In the rest service logs (not gateway) I found the following error:

java.lang.NullPointerException: null
    at java.base/java.util.Objects.requireNonNull(Objects.java:233) ~[na:na]
    at java.base/java.util.Optional.of(Optional.java:113) ~[na:na]
    at com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver.JWTClaimsSetAuthenticationManager$JWTClaimsSetAuthenticationManagerResolver.resolve(JWTClaimsSetAuthenticationManager.java:99) ~[spring-addons-starter-oidc-7.5.1.jar:na]
    at com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver.JWTClaimsSetAuthenticationManager.authenticate(JWTClaimsSetAuthenticationManager.java:63) ~[spring-addons-starter-oidc-7.5.1.jar:na]
    at org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter.doFilterInternal(BearerTokenAuthenticationFilter.java:137) ~[spring-security-oauth2-resource-server-6.2.1.jar:6.2.1]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.3.jar:6.1.3]
    at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) ~[spring-security-web-6.2.1.jar:6.2.1]
    at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) ~[spring-security-web-6.2.1.jar:6.2.1]
    at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) ~[spring-security-web-6.2.1.jar:6.2.1]
    at ...

After studying the source code of the place where the error occurs a little, I came to the conclusion that the aud parameter is expected(requireNonNull): image image

First of all, I studied the current BFF template to find the difference, maybe I missed something when updating, but I couldn't find anything.

REST Service build.gradle:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.2'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'group'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '21'
}

ext {
    set('springaddonsVersion', "7.5.+")
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-batch'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    implementation "com.c4-soft.springaddons:spring-addons-starter-oidc:${springaddonsVersion}"
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.flywaydb:flyway-core'
    implementation 'org.modelmapper:modelmapper:3.2.0'
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'org.postgresql:postgresql'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.batch:spring-batch-test'
    testImplementation 'org.springframework.security:spring-security-test'
    testImplementation "com.c4-soft.springaddons:spring-addons-starter-oidc-test:${springaddonsVersion}"
}

tasks.named('test') {
    useJUnitPlatform()
}

REST Service application.yaml:

scheme: http
gateway-uri: ${scheme}://localhost:${server.port}
issuer: http://localhost:9090/realms/client

com:
  c4-soft:
    springaddons:
      oidc:
        ops:
          - iss: ${issuer}
            authorities:
              - path: $.realm_access.roles
            username-claim: preferred_username
        resourceserver:
          permit-all:
            - /users/me
            - /categories
            - /actuator/health/readiness
            - /actuator/health/liveness
            # for dev time
            - '/v2/api-docs'
            - '/v3/api-docs'
            - '/v3/api-docs/**'
            - '/swagger-resources'
            - '/swagger-resources/**'
            - '/configuration/ui'
            - '/configuration/security'
            - '/swagger-ui/**'
            - '/webjars/**'
            - '/swagger-ui.html'
          cors:
            - path: /**
              allowed-origin-patterns:
                - ${gateway-uri}
                - https://localhost/

Expected behavior Due to the fact that I did not find any difference in the current version of the BFF tutorial and my current version of the project, I expected everything to work as needed.

Additional context image image

ch4mpy commented 6 months ago

@TheNullablePrototype thks for reporting.

Your analysis about the problem cause is the right one: JWTClaimsSetAuthenticationManager should use Optional#ofNullable (and not Optional#of) for all 3 arguments when calling the JWT-decoder factory.

This went under the radar because this is hard to spot in "unit" tests (authorization server is not called) and I "smoke" tested the last release with Auth0 (for which the audience is always provided)...

Should be fixed with the just released 7.5.2. Please confirm and close.

TheNullablePrototype commented 6 months ago

The problem is solved, thank you!