mardi 30 août 2016

How do you properly configure Spring Security's OAuth2 system to work with EmberJS

I'm creating an EmberJS app wrapped with Cordova alongside a Rest API provided by Spring Boot. Here is my Spring Code:

@SpringBootApplication
@RestController
public class Application extends SpringBootServletInitializer {

...

@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
         // any calls made to the API must be authenticated
         http.antMatcher("/api/**")
            .authorizeRequests()
            .anyRequest().fullyAuthenticated();

         http
            .cors().disable();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId("b-api");
    }
}

@Configuration
@EnableWebSecurity
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
        // we're hosting a static landing page with Spring so we're removing any security requirements for them
            .antMatchers("/resources/**")
            .antMatchers("/img/**")
            .antMatchers("/*")
            // this is to allow preflight to work but it doesn't seem to be doing the trick...
            .antMatchers(HttpMethod.OPTIONS, "/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest()
            .hasRole("USER");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
        // enable in memory based authentication with a user named "user" and "admin"
            .inMemoryAuthentication()
                .withUser("user")
                    .password("password")
                    .roles("USER")
            .and()
                .withUser("admin")
                .password("password")
                .roles("USER", "ADMIN");
    }
}

@Configuration
@EnableAuthorizationServer
@CrossOrigin(origins = "http://localhost:4200", methods = {RequestMethod.GET, RequestMethod.PUT, RequestMethod.OPTIONS, RequestMethod.HEAD}, allowedHeaders = "**")
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("my-trusted-client")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT", "ROLE_USER")
                .scopes("read", "write", "trust")
                .resourceIds("b-api")
                .accessTokenValiditySeconds(600);
    }
}

}

The frontend code is using EmberJS with ember-simple-auth's oauth2 authenticator.

Currently when I try and authenticate through the frontend Chrome's devtools throw this error:

XMLHttpRequest cannot load http://localhost:8080/oauth/token. 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:4200' is therefore not allowed access. The response had HTTP status code 403.

Any ideas regarding what I'm missing would be appreciated. Thanks :)




Aucun commentaire:

Enregistrer un commentaire