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