Search code examples
springspring-securityoauth-2.0auth0

Unauthorized 401 error for permitAll() URLs


I am getting unauthorized error even for permit all URLs.

This is my security config file:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Value("${auth0.audience}")
    private String audience;

    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuer;

    @Bean
    JwtDecoder jwtDecoder() {

        NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(issuer);

        OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(audience);
        OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
        OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);

        jwtDecoder.setJwtValidator(withAudience);

        return jwtDecoder;
    }

    @Bean
    public DefaultSecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         
      http
        .csrf(csrf -> csrf.disable())
        .authorizeHttpRequests(auth-> auth
            .requestMatchers("/api/public/**","/login","/register").permitAll().anyRequest().authenticated())
        .oauth2ResourceServer()
            .jwt();
        

    return http.build();    
    }
    
}

This is my validator file:

class AudienceValidator implements OAuth2TokenValidator<Jwt> {
    private final String audience;

    AudienceValidator(String audience) {
        this.audience = audience;
    }

    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null);
        
        if (jwt.getAudience().contains(audience)) {
            return OAuth2TokenValidatorResult.success();
        }
        return OAuth2TokenValidatorResult.failure(error);
    }
}

And these are the Log files

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
[32m :: Spring Boot :: [39m              [2m (v3.0.1)[0;39m

[2m2023-02-19T22:23:00.142+05:30[0;39m [32m INFO[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mc.r.apigateway.ApiGatewayApplication    [0;39m [2m:[0;39m Starting ApiGatewayApplication using Java 17.0.6 with PID 16708 (C:\PM\api-gateway - Copy\target\classes started by KrishnaGopikaUrlagan in C:\PM\api-gateway - Copy)
[2m2023-02-19T22:23:00.142+05:30[0;39m [32m INFO[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mc.r.apigateway.ApiGatewayApplication    [0;39m [2m:[0;39m No active profile set, falling back to 1 default profile: "default"
[2m2023-02-19T22:23:00.669+05:30[0;39m [32m INFO[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mo.s.cloud.context.scope.GenericScope    [0;39m [2m:[0;39m BeanFactory id=54aac986-e0d5-38c2-b07e-9736a12b46b1
[2m2023-02-19T22:23:01.470+05:30[0;39m [32m INFO[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mtrationDelegate$BeanPostProcessorChecker[0;39m [2m:[0;39m Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2m2023-02-19T22:23:01.471+05:30[0;39m [32m INFO[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mtrationDelegate$BeanPostProcessorChecker[0;39m [2m:[0;39m Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactorDeferringLoadBalancerFilterConfig' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactorDeferringLoadBalancerFilterConfig] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2m2023-02-19T22:23:01.471+05:30[0;39m [32m INFO[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mtrationDelegate$BeanPostProcessorChecker[0;39m [2m:[0;39m Bean 'reactorDeferringLoadBalancerExchangeFilterFunction' of type [org.springframework.cloud.client.loadbalancer.reactive.DeferringLoadBalancerExchangeFilterFunction] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2m2023-02-19T22:23:01.538+05:30[0;39m [32mDEBUG[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mswordEncoderAuthenticationManagerBuilder[0;39m [2m:[0;39m No authenticationProviders and no parentAuthenticationManager defined. Returning null.
[2m2023-02-19T22:23:02.904+05:30[0;39m [32m INFO[0;39m [35m16708[0;39m [2m---[0;39m [2m[  restartedMain][0;39m [36mo.s.s.web.DefaultSecurityFilterChain    [0;39m [2m:[0;39m Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@5c9f1e10, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@9658b45, org.springframework.security.web.context.SecurityContextHolderFilter@291e1f26, org.springframework.security.web.header.HeaderWriterFilter@1d58f1b7, org.springframework.security.web.authentication.logout.LogoutFilter@2de04a13, org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter@738072a1, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@240b8e76, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@2ed115b5, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2c68f8e0, org.springframework.security.web.access.ExceptionTranslationFilter@4f68b71d, org.springframework.security.web.access.intercept.AuthorizationFilter@733ad243]
[2m2023-02-19T22:23:26.660+05:30[0;39m [32mDEBUG[0;39m [35m16708[0;39m [2m---[0;39m [2m[     parallel-1][0;39m [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher[0;39m [2m:[0;39m Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=POST}
[2m2023-02-19T22:23:26.660+05:30[0;39m [32mDEBUG[0;39m [35m16708[0;39m [2m---[0;39m [2m[     parallel-1][0;39m [36mathPatternParserServerWebExchangeMatcher[0;39m [2m:[0;39m Request 'GET /api/public/allergy' doesn't match 'POST /logout'
[2m2023-02-19T22:23:26.660+05:30[0;39m [32mDEBUG[0;39m [35m16708[0;39m [2m---[0;39m [2m[     parallel-1][0;39m [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher[0;39m [2m:[0;39m No matches found
[2m2023-02-19T22:23:26.661+05:30[0;39m [32mDEBUG[0;39m [35m16708[0;39m [2m---[0;39m [2m[     parallel-1][0;39m [36ma.DelegatingReactiveAuthorizationManager[0;39m [2m:[0;39m Checking authorization on '/api/public/allergy' using org.springframework.security.authorization.AuthenticatedReactiveAuthorizationManager@69b0d355
[2m2023-02-19T22:23:26.661+05:30[0;39m [32mDEBUG[0;39m [35m16708[0;39m [2m---[0;39m [2m[     parallel-1][0;39m [36mebSessionServerSecurityContextRepository[0;39m [2m:[0;39m No SecurityContext found in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@2da15e91'
[2m2023-02-19T22:23:26.661+05:30[0;39m [32mDEBUG[0;39m [35m16708[0;39m [2m---[0;39m [2m[     parallel-1][0;39m [36mo.s.s.w.s.a.AuthorizationWebFilter      [0;39m [2m:[0;39m Authorization failed: Access Denied

This the pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>api-gateway-auth0</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>api-gateway</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2022.0.1</spring-cloud.version>
    </properties>
      <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <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>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>netflix-candidates</id>
      <name>Netflix Candidates</name>
      <url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

</project>

I tried to permit all public URLs and authenticate all the private URLs. but even though I permitted the public URLs I am getting a 401 error. I took out the webflux dependency, added the @Configuration annotation and made some more changes based on the suggestions I got from the comments. But still, the same problem.

Please help me solve this error.


Solution

  • If you are using Spring Security 6.x, you may be missing an @Configuration on your SecurityConfig. I added a comment explaining the discrepancy between your logs and your config, so if the missing annotation is your problem, you may face further configuration issues afterwards.

    See the 5.8 migration guide (which should be used when upgrading to 6.0) for more info.


    Edit:

    Upon discussing further in comments and reviewing your updated question, it appears that you are building an application using spring-boot-starter-gateway (Spring Cloud Gateway), which builds on Spring WebFlux and requires a corresponding security configuration using @EnableWebFluxSecurity. Explicit WebFlux Security Configuration in the reference contains an example configuration to get you started with Spring WebFlux.