How to setup CORS on user login - spring

I'm getting Not injecting HSTS header error but still have no idea after googling this message.
o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#30cc5ff
What I have done is below.
API request http://localhost:8083/api/v1/users/login
Web config
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL)
.permitAll();
http.csrf().disable().addFilterBefore(corsFilter, AuthorizationFilter.class)
.authorizeRequests()
.antMatchers("/api/v1/**").authenticated();
protected AuthenticationFilter getAuthenticationFilter() throws Exception {
final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager());
filter.setFilterProcessesUrl("/api/v1/users/login");
return filter;
}
CorsFilter
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
final HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
// without this header jquery.ajax calls returns 401 even after successful login and SSESSIONID being succesfully stored.
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Authorization, Origin, Content-Type, Version");
response.setHeader("Access-Control-Expose-Headers", "X-Requested-With, Authorization, Origin, Content-Type");
final HttpServletRequest request = (HttpServletRequest) servletRequest;
if (!request.getMethod().equals("OPTIONS")) {
filterChain.doFilter(request, response);
} else {
// do not continue with filter chain for options requests
}
}
#Override
public void destroy() {
}
}

HSTS stands for Http Strict Transport Security and is one of the default headers being included when using Spring Security.
If you have your own security configuration set up and are sure you can disable the HSTS security header, use:
http.headers().httpStrictTransportSecurity().disable();

Related

blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present, but it literally is. SpringBoot

ok i'm quite sure you guys know this error so let's just skip on my solution and the reasons of it not working, I have an Interceptor which is basically a filter, where I did this:
#Component
public class AllRequestInterceptor implements HandlerInterceptor {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if(request.getMethod().equalsIgnoreCase("options")) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "*");
}
for(String header: response.getHeaderNames()) {
System.out.println(header);
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
}
the CORS preflight request actually enters the if block, I get the headers printed afterwards and they're all present, and yet that party-pooper says otherwise, why does it say otherwise?
I'm not sure if this is what you are looking for, but this worked for me.
#Configuration
#Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsInterceptor implements Filter{
public CorsInterceptor() {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
}
CORS must be sent on all requests, not just on OPTIONS: CORS HEADERS present only on preflight or every request
Simply remove if(request.getMethod().equalsIgnoreCase("options")) and its corresponding brackets, and it should work.

Cors error 'No Access-Control-Allow-Origin' works on localhost but not on server

in my spring boot application i have a custom Filter which sets the cors related headers. This works perfectly on localhost, my requests are going through my custom Filter and the headers are filled out.
But when I deploy my application to a server then I get an error, and it seems the preflight request doesn't call my custom Filter.
This is my Filter
#Component
public class CustomAllowAllCorsFilter implements Filter {
final private static Logger logger = LoggerFactory.getLogger(CustomAllowAllCorsFilter.class);
private boolean allowAllOrigins;
public CustomAllowAllCorsFilter() {
logger.info("init filter corsssss");
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
throws IOException, ServletException {
logger.info("doFilter - allowAllOrigins: " + allowAllOrigins);
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (allowAllOrigins) {
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",
"Authorization, Content-Type, Accept, X-Requested-With, remember-me, OCTO-Security-Type, OCTO-Security-Name, OCTO-Security-Token, OCTO-Security-Business");
}
if (request.getMethod().equals("OPTIONS"))
response.setStatus(HttpServletResponse.SC_OK);
else
filterChain.doFilter(request, response);
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
#Value("${cors.allow-all-origins}")
public void setAllowAllOrigins(boolean allowAllOrigins) {
this.allowAllOrigins = allowAllOrigins;
}
}
And this is the error:
Failed to load http://xyz:8080/app/invoices: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://xii.com' is therefore not allowed access.
Does somebody have an idea?

Full authentication exception in spring boot

Hello I have following Security config file.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)
.authorizeRequests()
.antMatchers("/myservices/**/**").permitAll()
.antMatchers("/knowndata").permitAll()
.antMatchers("/guidata/**").permitAll()
.antMatchers("/textdata/**").access("hasRole('ROLE_ADMIN')")
.anyRequest().authenticated()
.and()
.requestCache()
.requestCache(new NullRequestCache())
.and()
.httpBasic();
http.csrf().disable();
}
and the following CORSFilter
#Component
public class CORSFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-auth-token,authorization, content-type, xsrf-token");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
Still I get Full authentication required exception when accessing the myservices.

CORS error in Spring Oauth2

I'm using Spring security and Oauth2. But I'm new to Spring Oauth2, I Got the CORS error when front-end attends to access resource.
I'm using the below filter to allow other domains to access the resource:
#Component
#Order(Integer.MAX_VALUE)
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Credentials", "True");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
I wrote the below code to allow public resource in my SecurityConfiguration.java.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/social/facebook/**","/register/**","/public/**").permitAll().and()
.authorizeRequests().antMatchers("/user/**").hasRole("USER").and()
.exceptionHandling()
.accessDeniedPage("/login.jsp?authorization_error=true")
.and()
.csrf()
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable();
}
For Oauth2, the below codes is for protecting user's resource in my OAuth2ServerConfig.java.
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/user/**")
.and()
.authorizeRequests()
.antMatchers("/user/**").access("#oauth2.hasScope('read')")
.regexMatchers(HttpMethod.DELETE, "/oauth/users/([^/].*?)/tokens/.*")
.access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')")
.regexMatchers(HttpMethod.GET, "/oauth/clients/([^/].*?)/users/.*")
.access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')")
.regexMatchers(HttpMethod.GET, "/oauth/clients/.*")
.access("#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')");
}
When I open the index.html file in the browser, like following:(Sorry I don't have at least 10 reputation to post images, so I paste links here)
http://i.stack.imgur.com/yQKJM.png
it successfully get the public data, that means other domains are allowed to access "/public/**" data.
But it failed to get "/user/**" data (protected by Oauth2). It gives me below error says "Cross-Origin Request Blocked".
http://i.stack.imgur.com/XIVx1.png
When I move the front-end files to the same domain of the Spring server. It works fine to get both "public" and "user" data as below:
http://i.stack.imgur.com/Q2n7F.png
The front-end and Back-end should be separated. But the CORS is blocked to access projected data. Can anyone give me some suggestions? Thanks very much. I'm guessing the filter is not working on Oauth2? still spend a lot of time on looking for solutions.
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {
#Override
public void init(FilterConfig fc) throws ServletException {
}
#Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "PATCH,POST,GET,OPTIONS,DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, resp);
}
}
#Override
public void destroy() {
}
}
I added the headers to the endpoints
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.addInterceptor(new HandlerInterceptorAdapter() {
#Override
public boolean preHandle(HttpServletRequest hsr, HttpServletResponse rs, Object o) throws Exception {
rs.setHeader("Access-Control-Allow-Origin", "*");
rs.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
rs.setHeader("Access-Control-Max-Age", "3600");
rs.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
return true;
}
});
}
The OAuth filter was called first and throw an Exception which has been prevented from running your CORS filter.
you must add this annotation
#Order(Ordered.HIGHEST_PRECEDENCE)
to your CORS filter.

Add headers to oauth/token response (spring-security)

I would like to add custom headers to Oauth2 token response for my spring application. Specifically it involves CORS headers i.e. Access-Control-Allow-Origin... I have managed to add them to 401 responses but have no luck with 200 ones.
I have looked everywhere and debugged the project with no result. I have tried adding those headers through interceptor but response still does not contain them.
Any ideas?
I'm using Spring security with annotation configuration.
I have asked similar question here: Allow OPTIONS HTTP Method for oauth/token request where you can check my spring configuration.
Use this Cors Filter (or maybe it works if you add the last lines of my version to your version) and you don't have the problem you mention in you other linked post!
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
public SimpleCorsFilter() {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
}
It turned out I was using wrong method in my interceptor
for anyone interested, my working code is as follows:
return new AuthorizationServerConfigurer() {
...
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
...
endpoints.addInterceptor(new HandlerInterceptorAdapter() {
#Override
public boolean preHandle(HttpServletRequest hsr, HttpServletResponse rs, Object o) throws Exception {
rs.setHeader("Access-Control-Allow-Origin", "*");
rs.setHeader("Access-Control-Allow-Methods", "GET");
rs.setHeader("Access-Control-Max-Age", "3600");
rs.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
return true;
}
});
}
}
}

Resources