angularjs - Spring Security, Angular JS, Tomcat 7, CORS with form login not working -
i have requirement invoke cross domain ajax call angular app, @ localhost:8000. [i using grunt connect:livereload launches web server]
the angular route localhost:8000/user/login displays form login, submission of makes ajax call backend spring rest controller integrated spring security. app hosted @ localhost:8080/mynext-app/login
ajax call inside angular directive: mynextapp-login.validate.js:
angular.module('login').directive('loginvalidate', function() { //jquery.validate.js settings in between. // followed handler submithandler: function(form) { var email = $("#email").val(); var password = $("#pwd").val(); var request = $.ajax({ url: "http://localhost:8080/mynext-app/login", method: "post", contenttype: "application/json", crossdomain:true, data: { email: email, password: password }, datatype: "json" });
my logincontroller:
package com.mynext.mynextapp.config;
@restcontroller public class logincontroller { @requestmapping(value="/login", method=requestmethod.post, produces="application/json") public responseentity<?> dologin() { return new responseentity<>("{\"code\":\"1\",\"msg\":\"login successfully\",\"redirect\":\"http://localhost:9001/\"}", httpstatus.ok); } }
i using java, no web.xml configuration:
webconfig:
@configuration @enablewebmvc @componentscan({"com.mynext.mynextapp.web"}) public class webconfig extends webmvcconfigureradapter { }
rootconfig:
@configuration @componentscan(basepackages={"com.mynext.mynextapp"}, excludefilters={ @filter(type=filtertype.custom, value=webpackage.class) }) public class rootconfig { public static class webpackage extends regexpatterntypefilter { public webpackage() { super(pattern.compile("com\\.mynext\\.mynextapp\\.web")); } } }
springsecurityconfig:
i using form login, no http basic, disabled.
@configuration @enablewebmvcsecurity public class springsecurityconfig extends websecurityconfigureradapter { @override protected void configure(authenticationmanagerbuilder auth) throws exception { auth .inmemoryauthentication() .withuser("thisismyemailid@gmail.com") .password("aaa") .roles("client", "serviceprov"); } @override protected void configure(httpsecurity http) throws exception { http .formlogin() .loginpage("/login") .usernameparameter("email") //.and() //.httpbasic() .and() .authorizerequests() .antmatchers("/") .authenticated() .anyrequest() .permitall() .and() .csrf() .disable(); } }
corsfilter
@component @order(ordered.highest_precedence) class corsfilter implements filter { public void dofilter(servletrequest req, servletresponse res, filterchain chain) { httpservletresponse response = (httpservletresponse) res; httpservletrequest request = (httpservletrequest) req; try { response.setheader("access-control-allow-origin", "*"); response.setheader("access-control-allow-methods", "post, get, put, options, delete"); response.setheader("access-control-max-age", "3600"); response.setheader("access-control-allow-headers", "origin, x-requested-with, content-type, accept"); response.setheader("access-control-allow-credentials", "true"); chain.dofilter(req, res); } catch (exception e) { e.printstacktrace(); } } public void init(filterconfig filterconfig) { } public void destroy() { }
with these classes in place, expect restcontroller @ endpoint /login serve hardcoded json string.
i have @ordered.highest_precedence annotation in corsfilter, should ensure corsfilter loaded before springsecurityconfig. both corsfilter , springsecurityconfig in same package. have them "component-scaned" rootconfig. both can should available part of same webapp context.
my firefox's net console, displays "options" request /login status 200 ok. console shows warnings:
cross-origin request blocked: same origin policy disallows reading remote resource @ http://localhost:8080/mynext-app/login. (reason: cors header 'access-control-allow-origin' missing).
request headers:
accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 accept-encoding gzip, deflate accept-language en-us,en;q=0.5 access-control-request-he... content-type access-control-request-me... post cache-control no-cache connection keep-alive host localhost:8080 origin http://localhost:8000 pragma no-cache user-agent mozilla/5.0 (windows nt 6.3; wow64; rv:41.0) gecko/20100101 firefox/41.0
the missing piece of information can think of, of "jigsaw puzzle" perhaps tomcat 7's corsfilter. not sure if needs implemented well.
i understand browser sends "preflight" request options call. don't seem get, response 200 ok, in spite console displays cors warning. here have wanted json string displayed post following options http method call.
what missing here. pointers appreciated please.
update (03/11/2015) - missing configuration in spring:
@override protected filter[] getservletfilters() { return new filter[] { new corsfilter() }; }
with this, subsequent post call /login post, stuck long spring-security exceptions.
i experimented tomcat corsfilter, spring cors need control csrf me. have worked tomcat quite long time given opportunity have went it, not really.
next try angular $http instead of $ajax , using spring security recommmended resource programming. may solution.
thank you,
Comments
Post a Comment