Not Throwing an Unauthorized Error with Auth0 / Spring Security / RESTEasy

Hi everyone,

I am trying to integrate Auth0 into my REST APIs. We are using JBoss RESTEasy web services with Spring Security and Spring as a container. I followed this Auth0 tutorial and the sample code here. It looks like Auth0 and Spring are intercepting the API calls but it doesn’t return “unauthorized” if it is missing the JWT access token or it is an invalid token. Below is the logging messages I get if it is a missing JWT access token or invalid one:

2019-07-17 23:40:34,842 [http-nio-8080-exec-4] DEBUG com.auth0.spring.security.api.authentication.PreAuthenticatedAuthenticationJsonWebToken - No token was provided to build com.auth0.spring.security.api.authentication.PreAuthenticatedAuthenticationJsonWebToken
2019-07-17 23:40:11,308 [http-nio-8080-exec-2] DEBUG com.auth0.spring.security.api.authentication.PreAuthenticatedAuthenticationJsonWebToken - Failed to decode token as jwt
com.auth0.jwt.exceptions.JWTDecodeException: The token was expected to have 3 parts, but got 1.

But the RESTEasy API code will continue to execute. I tried to search on the web for RESTEasy + Auth0 examples or tutorial but no luck so far. My guess is because I am not using Spring MVC, it is not getting intercepted.

Any advice on what I should try next would be greatly appreciated!

Here is my web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
   <display-name>Identiview Web Services Application</display-name>

   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
         classpath*:com/gemex/**/*-spring-config.xml
      </param-value>
   </context-param>

   <context-param>
      <param-name>resteasy.providers</param-name>
      <param-value>com.gemex.ws.jackson.JacksonObjectMapperConfiguration</param-value>
   </context-param>

   <context-param>
      <param-name>resteasy.servlet.mapping.prefix</param-name>
      <param-value>/</param-value>
   </context-param>

   <filter>
      <filter-name>springSecurityFilterChain</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

   <listener>
       <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>

   <listener>
       <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
    </listener>

   <servlet>
      <servlet-name>Resteasy</servlet-name>
      <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
   </servlet>

   <servlet-mapping>
      <servlet-name>Resteasy</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>

   <session-config>
      <session-timeout>30</session-timeout>
   </session-config>

   <welcome-file-list>
      <welcome-file>index.html</welcome-file>
   </welcome-file-list>

</web-app>

Here is my partial SecurityJavaConfig:

@EnableWebSecurity
@Configuration
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {

   @Value(value = "${auth0.apiAudience}")
   private String apiAudience;

   @Value(value = "${auth0.issuer}")
   private String issuer;

   @Bean
   CorsConfigurationSource corsConfigurationSource() {

      CorsConfiguration configuration = new CorsConfiguration();
      configuration.setAllowedOrigins(Arrays.asList("*"));
      configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
      configuration.setAllowCredentials(true);
      configuration.addAllowedHeader("Authorization");
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      source.registerCorsConfiguration("/**", configuration);
      return source;
   }

   @Override
   protected void configure(HttpSecurity http) throws Exception {
      http.cors();
      JwtWebSecurityConfigurer
            .forRS256(apiAudience, issuer)
            .configure(http)
            .authorizeRequests()
            .antMatchers(HttpMethod.POST, "/idscans").authenticated()
            .antMatchers(HttpMethod.POST, "/idscans/verify/{**}/accepted").authenticated()
            .antMatchers(HttpMethod.POST, "/idscans/verify/{**}/rejected").authenticated()

Here is what my RESTEasy API interface looks like. I added Spring’s @Controller annotation to it but it didn’t do anything.

@Path("/idscans")
public interface IdentiviewScanResource {

   @GET
   @Path("/test")
   @Produces(MediaType.APPLICATION_JSON)
   Response getTest();

   @GET
   @Path("/secure-test")
   @Produces(MediaType.APPLICATION_JSON)
   Response getSecureTest(@HeaderParam("authorization") String authHeaderString);

Thanks,
Ben

Hi there @benw,

In the past the error message you received of The token was expected to have 3 parts, but got 1. has been resolved by checking the following:

Please let me know if this helps you overcome the challenge you are facing. Thanks!

Also good news @benw, we just announced a new Java Spring Security 5 Quickstart!

Hi James,

Thanks for responding, but this isn’t the issue. I was only using that error to demonstrate the API still runs (gets through) even though the token is invalid. Basically, it looks like Spring Security/Auth0 knows it is invalid but the RestEasy API method code runs when it should return “Unauthorized”.

I will try to send in a valid but expired token and see what happens.

Thanks,
Ben

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.