2023-04-22

SpringBoot: JWT Error (Failed to authenticate since the JWT was invalid)

I've been following this tutorial to create a YouTube Clone using Angular+SpringBoot: https://www.youtube.com/watch?v=DW1nQ4o3sCI&t=15427s

What i'm trying to do right is now is to create a user registration endpoint using OAuth, so i can write the user information on my database. However, i'm having some issues with JWT.

Whenever i try to access the endpoint (localhost:8080/api/user/register) i do receive the following error on my console:

[nio-8080-exec-3] o.s.s.o.s.r.a.JwtAuthenticationProvider : Failed to authenticate since the JWT was invalid

Setting some breakpoints and debuggging the application, on SecurityConfig.java the JWT is okay (it returns a valid object). However, when trying to call the endpoint using postman and sending my token as a Bearer token, i do receive the error i sent above. And i can't even debug the UserController ; even setting the breakpoints, when i call the endpoint i don't know what happens but i just receive the error. The only way i can debug trough the controller is if i call using my browse. But when doing so, the authentication is null so it won't work.

UserController.java

package com.pablo.portfolio.youtubeclone.controller;

@RestController
@RequestMapping("/api/user")
@RequiredArgsConstructor
public class UserController {


    private final UserRegistrationService userRegistrationService;
    private final UserService userService;

    @GetMapping("/register")
    @ResponseStatus(HttpStatus.OK)
    public String register(Authentication authentication){

        Jwt jwt = (Jwt)authentication.getPrincipal();
        userRegistrationService.registerUser(jwt.getTokenValue());
        return "User registered successfully";
    }
}

SecurityConfig.java

package com.pablo.portfolio.youtubeclone.config;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Value("${spring.security.oauth2.resourceserver.jwt.issuer.uri}")
    private String issuer;
    @Value("${auth0.audience}")
    private String audience;
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http
                .csrf()
                .disable().authorizeRequests()
                .requestMatchers("/").permitAll()
                .requestMatchers("/api/videos/","/save-video-details/","/upload-video/","/thumbnail/").authenticated()
                .requestMatchers("/api/private-scoped").hasAuthority("SCOPE_read:messages")
                .and().cors()
                .and().oauth2ResourceServer().jwt();
        return http.build();



    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
        configuration.setExposedHeaders(Arrays.asList("Authorization", "content-type"));
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "content-type"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }


    @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;
    }
}

Also, i checked the token o jwt.io and its valid. Here's the response:

Header:
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "7_mQttmzor-VMdGDXMEKN"
}

Payload:
{
  "iss": "https://dev-i63rcznjs255jxgf.us.auth0.com/",
  "sub": "google-oauth2|113855475209558231767",
  "aud": [
    "http://localhost:8080",
    "https://dev-i63rcznjs255jxgf.us.auth0.com/userinfo"
  ],
  "iat": 1681740331,
  "exp": 1681826731,
  "azp": "NJbox1ptzDdadd1Zo9mlBvtkElgge59v",
  "scope": "openid profile email"
}

EDIT: FUll log

2023-04-19T22:07:32.963-03:00 TRACE 1909589 --- [           main] eGlobalAuthenticationAutowiredConfigurer : Eagerly initializing {securityConfig=com.pablo.portfolio.youtubeclone.config.SecurityConfig$$SpringCGLIB$$0@61d2f267}
2023-04-19T22:07:32.964-03:00 DEBUG 1909589 --- [           main] swordEncoderAuthenticationManagerBuilder : No authenticationProviders and no parentAuthenticationManager defined. Returning null.
2023-04-19T22:07:34.768-03:00 DEBUG 1909589 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [permitAll] for Mvc [pattern='/']
2023-04-19T22:07:34.780-03:00 DEBUG 1909589 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [authenticated] for Mvc [pattern='/api/videos/']
2023-04-19T22:07:34.780-03:00 DEBUG 1909589 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [authenticated] for Mvc [pattern='/save-video-details/']
2023-04-19T22:07:34.780-03:00 DEBUG 1909589 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [authenticated] for Mvc [pattern='/upload-video/']
2023-04-19T22:07:34.780-03:00 DEBUG 1909589 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [authenticated] for Mvc [pattern='/thumbnail/']
2023-04-19T22:07:34.780-03:00 DEBUG 1909589 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [hasAuthority('SCOPE_read:messages')] for Mvc [pattern='/api/private-scoped']
2023-04-19T22:07:34.788-03:00 TRACE 1909589 --- [           main] o.s.s.w.a.i.FilterSecurityInterceptor    : Validated configuration attributes
2023-04-19T22:07:34.789-03:00 TRACE 1909589 --- [           main] o.s.s.w.a.i.FilterSecurityInterceptor    : Validated configuration attributes
2023-04-19T22:07:34.794-03:00  INFO 1909589 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@ecf028c, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7b64bbad, org.springframework.security.web.context.SecurityContextHolderFilter@68f2363, org.springframework.security.web.header.HeaderWriterFilter@d978ab9, org.springframework.web.filter.CorsFilter@71eff6a3, org.springframework.security.web.authentication.logout.LogoutFilter@484302ee, org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter@4cd8db31, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@86377d5, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@87220f1, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@574218f, org.springframework.security.web.access.ExceptionTranslationFilter@d180961, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@35d114f4]
2023-04-19T22:07:34.963-03:00  INFO 1909589 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-04-19T22:07:34.972-03:00  INFO 1909589 --- [           main] c.p.p.y.YoutubeCloneApplication          : Started YoutubeCloneApplication in 5.035 seconds (process running for 5.444)
2023-04-19T22:07:56.036-03:00  INFO 1909589 --- [nio-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-04-19T22:07:56.036-03:00  INFO 1909589 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-04-19T22:07:56.038-03:00  INFO 1909589 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2023-04-19T22:07:56.043-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@ecf028c, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7b64bbad, org.springframework.security.web.context.SecurityContextHolderFilter@68f2363, org.springframework.security.web.header.HeaderWriterFilter@d978ab9, org.springframework.web.filter.CorsFilter@71eff6a3, org.springframework.security.web.authentication.logout.LogoutFilter@484302ee, org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter@4cd8db31, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@86377d5, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@87220f1, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@574218f, org.springframework.security.web.access.ExceptionTranslationFilter@d180961, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@35d114f4]] (1/1)
2023-04-19T22:07:56.044-03:00 DEBUG 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Securing GET /api/user/register
2023-04-19T22:07:56.045-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Invoking DisableEncodeUrlFilter (1/12)
2023-04-19T22:07:56.045-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (2/12)
2023-04-19T22:07:56.047-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Invoking SecurityContextHolderFilter (3/12)
2023-04-19T22:07:56.048-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (4/12)
2023-04-19T22:07:56.050-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Invoking CorsFilter (5/12)
2023-04-19T22:07:56.053-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Invoking LogoutFilter (6/12)
2023-04-19T22:07:56.053-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.s.w.a.logout.LogoutFilter            : Did not match request to Or [Ant [pattern='/logout', GET], Ant [pattern='/logout', POST], Ant [pattern='/logout', PUT], Ant [pattern='/logout', DELETE]]
2023-04-19T22:07:56.053-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Invoking BearerTokenAuthenticationFilter (7/12)
2023-04-19T22:07:56.055-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.s.authentication.ProviderManager     : Authenticating request with JwtAuthenticationProvider (1/2)
2023-04-19T22:07:56.068-03:00 DEBUG 1909589 --- [nio-8080-exec-3] o.s.s.o.s.r.a.JwtAuthenticationProvider  : Failed to authenticate since the JWT was invalid
2023-04-19T22:07:56.070-03:00 TRACE 1909589 --- [nio-8080-exec-3] .s.r.w.a.BearerTokenAuthenticationFilter : Failed to process authentication request

org.springframework.security.oauth2.server.resource.InvalidBearerTokenException: Unable to validate Jwt
    at org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider.getJwt(JwtAuthenticationProvider.java:100) ~[spring-security-oauth2-resource-server-6.0.2.jar:6.0.2]
    at org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider.authenticate(JwtAuthenticationProvider.java:87) ~[spring-security-oauth2-resource-server-6.0.2.jar:6.0.2]
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-6.0.2.jar:6.0.2]
    at org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter.doFilterInternal(BearerTokenAuthenticationFilter.java:137) ~[spring-security-oauth2-resource-server-6.0.2.jar:6.0.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) ~[spring-web-6.0.7.jar:6.0.7]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.7.jar:6.0.7]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
    at java.base/java.lang.Thread.run(Thread.java:1623) ~[na:na]
Caused by: org.springframework.security.oauth2.jwt.JwtValidationException: Unable to validate Jwt
    at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.validateJwt(NimbusJwtDecoder.java:189) ~[spring-security-oauth2-jose-6.0.2.jar:6.0.2]
    at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.decode(NimbusJwtDecoder.java:138) ~[spring-security-oauth2-jose-6.0.2.jar:6.0.2]
    at org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider.getJwt(JwtAuthenticationProvider.java:96) ~[spring-security-oauth2-resource-server-6.0.2.jar:6.0.2]
    ... 58 common frames omitted

2023-04-19T22:07:56.075-03:00 TRACE 1909589 --- [nio-8080-exec-3] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match request to [Is Secure]


No comments:

Post a Comment