AngularJS authentication with Spring Security CORS issues

AngularJS authentication with Spring Security CORS issues



I am using the tutorials on https://spring.io/guides/tutorials/spring-security-and-angular-js to connect AngularJS app to Spring Security backend for authentication.



When I try to log in (the username and password already exist in the backend), I get the following error in browser consoles (am testing my app in Chrome, Firefox and IE, all of them give me the same error).



The error is:


XMLHttpRequest cannot load http://SERVER_URL:4444/test/user.
Response to preflight request doesn't pass access control

check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Origin 'http://localhost:3000' is therefore not allowed access.
The response had HTTP status code 401.



Code:


var auth = angular.module("Admin");

authService.service("AuthService", function($http, $rootScope)

this.login = function(credentials)
var headers = credentials ? authorization: "Basic " + btoa(credentials.username + ":" + credentials.password) : ;

$http.get("http://SERVER_URL:4444/test/user",headers:headers)
.then(function(response)
console.log("success");
$rootScope.authenticated = true;
, function()
console.log("failed");
$rootScope.authenticated = false;
);


;




);



When I access the same link in the browser, I get authenticated box and I type in the username and password and I can see the result. But I don't understand why can't I access the same link via $http() successfully.



What is the correct way to do it? I have read numerous posts and Q&As but none solves the problem. I just don't understand what is going on.





"When i access the same link in the browser ... i can see the result. But i don't understand why can't i access the same link via $http() successfully" So you use the term CORS with knowing what it means. Btw, the tutorial you linked to explains how to add support for CORS, so I wonder why you "have spent days googling".
– a better oliver
Jun 30 '16 at 13:09


CORS




2 Answers
2



You need to register a CORS filter in your Spring Security configuration on your backend to allow the origin of your Angular app access to the backend, since it is making cross-origin requests (it's not coming from the same host and port):


@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter

@Bean
public CorsFilter corsFilter()
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);





Alternatively, if you are using an older version of Spring Security that does not support CorsConfiguration you can accomplish the same thing by implementing a custom filter and injecting it into your filter chain:


CorsConfiguration


@Component
public class CorsFilter implements Filter

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "*");
chain.doFilter(req, res);


public void init(FilterConfig filterConfig)

public void destroy()






Thanks for your quick answer. But why does it work when i access the same address directly from the browser?
– Eddy Freeman
Jun 30 '16 at 12:04






Because CORS is designed to prevent cross-site requests, not requests from browsers. You can read more about it here: html5rocks.com/en/tutorials/cors
– Daniel Cottone
Jun 30 '16 at 12:11





I will mark it if it works. Am still on it
– Eddy Freeman
Jun 30 '16 at 13:15





The probelm we have now is we have configured CORS using the controllers as described here :: spring.io/blog/2015/06/08/cors-support-in-spring-framework. Why do we have to add Filter to it? Can you explain a little bit. Under normal circumstances it has to work but it is not working.
– Eddy Freeman
Jun 30 '16 at 13:19





There's a few different possible issues, it could be that for some reason one of your dependencies are forcing compiling with a version of Spring Framework before 4.2; do a dependency tree to figure out if this is the case. It could also be related to missing the @EnableWebMvc annotation a configuration class, see here: jira.spring.io/browse/SPR-13857 I've not used the CORS annotations before so I'm not sure why those wouldn't be working, but most workarounds I have seen to them failing involve just implementing the filter.
– Daniel Cottone
Jun 30 '16 at 13:52



@EnableWebMvc



By default, the browsers have implemented the security policy, not to execute the scripts loaded from different domains. Even if it's from the same host and different port, it will not allow as it's violates the cross domain policy.



There are many ways to overcome this issue.



Best way is to enable the CORS at the server, so that from the first response onward, the server will instruct the browsers to allow to cross the domain. Refer the link to get more http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server





As per my understanding, when you just enter the url and when you call the url from your scripts are two different types of requests triggered by the browser. When you make request using scripts, its XMLHttpRequest type and if if you just enter it into the browser's address bar it might be a http request
– Tharsan Sivakumar
Jun 30 '16 at 12:11



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)