I am trying to build my first application using Stormpath and Spring Boot. I don't find how to add a CORS Filter to the Stormpath servlet. As a result, my front end app cannot get the authentication token because the Access-Control-Allow-Origin header is missing.
With logs, I am sure that my CORS filter is called on methods that I control but, not on the request /oauth/token.
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(SimpleCorsFilter.class);
public SimpleCorsFilter() {
log.info("SimpleCORSFilter init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
log.debug("*********Enter Cors Filter***********");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
log.debug("******* Exit Cors Filter ****");
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
I also tried the approach in this blog https://shuaib.me/stormpath-java-backend/ and added the following lines in application.properties.
stormpath.web.accessToken.origin.authorizer.originUris = http://localhost:3002
stormpath.web.filters.cors = something.SimpleCorsFilter
stormpath.web.uris./logout = cors
stormpath.web.uris./register = cors
stormpath.web.uris./oauth/token = cors
I also tried to add a FilterRegistrationBean
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
All those attempts have the same results, they work for the methods in my Controllers but not, for the /oauth/token request.
Finally, this my pom
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>stormpath-basic</groupId>
<artifactId>stormpath-basic</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<stormpath.version>1.1.1</stormpath.version>
</properties>
<dependencies>
<dependency>
<groupId>com.stormpath.spring</groupId>
<artifactId>stormpath-default-spring-boot-starter</artifactId>
<version>${stormpath.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Am I missing something?
Spring Boot supports Cross-Origin Resource Sharing (CORS), but it only works for Spring MVC, not Spring Security. Spring Framework provides a CorsFilter you can use for filter-based frameworks. It looks like you're already doing this with your FilterRegistrationBean
.
I encountered this same issue last week while writing a blog post about it. After debugging, I figured out this was because the main StormpathFilter
comes before the CorsFilter
.
To fix this, add the following to application.properties
.
stormpath.web.stormpathFilter.order=1