angularjs - Spring Security + Angular JS + CORS issue - Error XMLHttpRequest cannot load http://localhost:8080/user. Response for preflight is invalid (redirect) -
note: have omitted http:// in links doesnt allow me post more 2 urls yet.
i have angular ui served out of localhost:5000. have rest apis served out of localhost:8080. authenticate on rest api server using facebook oauth2. subsequently, want access /user endpoint on server authenticated.
for example purpose here, refer spring sample in github.com/spring-guides/tut-spring-boot-oauth2.git. have modified code github example.
i followed blog post , added filter follows
@configuration public class myconfiguration { @bean public filterregistrationbean corsfilter() { urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource(); corsconfiguration config = new corsconfiguration(); config.setallowcredentials(true); config.addallowedorigin("http://localhost"); config.addallowedorigin("http://localhost:5000"); config.addallowedheader("*"); config.addallowedmethod("*"); source.registercorsconfiguration("/**", config); filterregistrationbean bean = new filterregistrationbean(new corsfilter(source)); bean.setorder(0); return bean; } }
the app as-is in spring sample in github directory
package com.example; import java.security.principal; import java.util.arraylist; import java.util.linkedhashmap; import java.util.list; import java.util.map; import javax.servlet.filter; import org.springframework.beans.factory.annotation.autowired; import org.springframework.boot.springapplication; import org.springframework.boot.autoconfigure.springbootapplication; import org.springframework.boot.autoconfigure.security.oauth2.resource.resourceserverproperties; import org.springframework.boot.autoconfigure.security.oauth2.resource.userinfotokenservices; import org.springframework.boot.context.properties.configurationproperties; import org.springframework.boot.context.properties.nestedconfigurationproperty; import org.springframework.boot.web.servlet.filterregistrationbean; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.core.annotation.order; import org.springframework.security.config.annotation.web.builders.httpsecurity; import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter; import org.springframework.security.oauth2.client.oauth2clientcontext; import org.springframework.security.oauth2.client.oauth2resttemplate; import org.springframework.security.oauth2.client.filter.oauth2clientauthenticationprocessingfilter; import org.springframework.security.oauth2.client.filter.oauth2clientcontextfilter; import org.springframework.security.oauth2.client.resource.oauth2protectedresourcedetails; import org.springframework.security.oauth2.client.token.grant.code.authorizationcoderesourcedetails; import org.springframework.security.oauth2.config.annotation.web.configuration.enableauthorizationserver; import org.springframework.security.oauth2.config.annotation.web.configuration.enableoauth2client; import org.springframework.security.oauth2.config.annotation.web.configuration.enableresourceserver; import org.springframework.security.oauth2.config.annotation.web.configuration.resourceserverconfigureradapter; import org.springframework.security.web.authentication.loginurlauthenticationentrypoint; import org.springframework.security.web.authentication.www.basicauthenticationfilter; import org.springframework.security.web.csrf.cookiecsrftokenrepository; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.restcontroller; import org.springframework.web.filter.compositefilter; @springbootapplication @restcontroller @enableoauth2client @enableauthorizationserver @order(6) public class socialapplication extends websecurityconfigureradapter { @autowired oauth2clientcontext oauth2clientcontext; @requestmapping({ "/user", "/me" }) public map<string, string> user(principal principal) { map<string, string> map = new linkedhashmap<>(); map.put("name", principal.getname()); return map; } @override protected void configure(httpsecurity http) throws exception { // @formatter:off http.antmatcher("/**").authorizerequests().antmatchers("/", "/login**", "/webjars/**").permitall().anyrequest() .authenticated().and().exceptionhandling() .authenticationentrypoint(new loginurlauthenticationentrypoint("/")).and().logout() .logoutsuccessurl("/").permitall().and().csrf() .csrftokenrepository(cookiecsrftokenrepository.withhttponlyfalse()).and() .addfilterbefore(ssofilter(), basicauthenticationfilter.class); // @formatter:on } @configuration @enableresourceserver protected static class resourceserverconfiguration extends resourceserverconfigureradapter { @override public void configure(httpsecurity http) throws exception { // @formatter:off http.antmatcher("/me").authorizerequests().anyrequest().authenticated(); // @formatter:on } } public static void main(string[] args) { springapplication.run(socialapplication.class, args); } @bean public filterregistrationbean oauth2clientfilterregistration(oauth2clientcontextfilter filter) { filterregistrationbean registration = new filterregistrationbean(); registration.setfilter(filter); registration.setorder(-100); return registration; } @bean @configurationproperties("github") public clientresources github() { return new clientresources(); } @bean @configurationproperties("facebook") public clientresources facebook() { return new clientresources(); } private filter ssofilter() { compositefilter filter = new compositefilter(); list<filter> filters = new arraylist<>(); filters.add(ssofilter(facebook(), "/login/facebook")); filters.add(ssofilter(github(), "/login/github")); filter.setfilters(filters); return filter; } private filter ssofilter(clientresources client, string path) { oauth2clientauthenticationprocessingfilter oauth2clientauthenticationfilter = new oauth2clientauthenticationprocessingfilter( path); oauth2resttemplate oauth2resttemplate = new oauth2resttemplate(client.getclient(), oauth2clientcontext); oauth2clientauthenticationfilter.setresttemplate(oauth2resttemplate); userinfotokenservices tokenservices = new userinfotokenservices(client.getresource().getuserinfouri(), client.getclient().getclientid()); tokenservices.setresttemplate(oauth2resttemplate); oauth2clientauthenticationfilter.settokenservices(tokenservices); return oauth2clientauthenticationfilter; } } class clientresources { @nestedconfigurationproperty private authorizationcoderesourcedetails client = new authorizationcoderesourcedetails(); @nestedconfigurationproperty private resourceserverproperties resource = new resourceserverproperties(); public authorizationcoderesourcedetails getclient() { return client; } public resourceserverproperties getresource() { return resource; } }
in angular, code follows. after authentication, expect user details /user
$http.get("http://localhost/user").success(function(data) { if (data.name) { self.user = data.name; self.authenticated = true; } else { self.user = "n/a"; self.authenticated = false; } }).error(function() { self.user = "n/a"; self.authenticated = false; });
this gets executed after authenticated using facebook's oauth2.
i error
xmlhttprequest cannot load http://localhost:8080/user. response preflight invalid (redirect)
as 302 happens pre-flight options request
request follows
options /user http/1.1 host: localhost:8080 connection: keep-alive access-control-request-method: origin: http://localhost:5000 user-agent: mozilla/5.0 (x11; linux x86_64) applewebkit/537.36 (khtml, gecko) chrome/51.0.2704.103 safari/537.36 access-control-request-headers: accept, x-requested-with accept: */* dnt: 1 referer: http://localhost:5000/ accept-encoding: gzip, deflate, sdch accept-language: en-us,en;q=0.8,es;q=0.6,ms;q=0.4,hi;q=0.2
response
http/1.1 302 set-cookie: xsrf-token=8a4e7e55-25fb-4293-975d-19979b65327e;path=/ x-content-type-options: nosniff x-xss-protection: 1; mode=block cache-control: no-cache, no-store, max-age=0, must-revalidate pragma: no-cache expires: 0 x-frame-options: deny location: http://localhost:8080/ content-length: 0 date: thu, 17 nov 2016 14:32:35 gmt
the pom in spring sample, except changed spring boot 1.4.0.release 1.4.1.release
<parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>1.4.1.release</version> <relativepath /> <!-- lookup parent repository --> </parent> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-actuator</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-security</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.security.oauth</groupid> <artifactid>spring-security-oauth2</artifactid> </dependency> <dependency> <groupid>org.webjars</groupid> <artifactid>angularjs</artifactid> <version>1.4.3</version> </dependency> <dependency> <groupid>org.webjars</groupid> <artifactid>jquery</artifactid> <version>2.1.1</version> </dependency> <dependency> <groupid>org.webjars</groupid> <artifactid>bootstrap</artifactid> <version>3.2.0</version> </dependency> <dependency> <groupid>org.webjars</groupid> <artifactid>webjars-locator</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-configuration-processor</artifactid> <optional>true</optional> </dependency> </dependencies>
after authentication, on browser tab, if access "localhost:8080/user" right data back. authentication has succeeded.
what missing?
thanks
Comments
Post a Comment