I want to create a simple webapp based on Angular. That is able to retrieve data from the with oauth secured battlenet resource server.
My planned structure is like.
- Angular
- Spring boot as oauth2 client using spring webflux
- Battlenet authentication + resource server
I was able to setup my spring boot app, that I'm able to retrieve data by direct endpoint calls via browser.
If I try to do the same via angular app, I'm getting cross origin errors while oauth authentication.
Browser info from inspect -> network
My configuration
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain configure(ServerHttpSecurity http) {
return http.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.authorizeExchange(auth -> auth.anyExchange().authenticated())
.oauth2Login(withDefaults())
.build();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:4200"));
configuration.setAllowedMethods(List.of("*"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setMaxAge(3600L);
configuration.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public WebClient webClient(ReactiveClientRegistrationRepository clientRegistrationRepo,
ServerOAuth2AuthorizedClientRepository authorizedClientRepo) {
ServerOAuth2AuthorizedClientExchangeFilterFunction filter =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrationRepo,
authorizedClientRepo);
return WebClient.builder()
.baseUrl("https://eu.api.blizzard.com")
.filter(filter)
.build();
}
}
My rest controller
@RestController
public class UserController {
@GetMapping("/user")
public Mono<String> getUserName(@AuthenticationPrincipal Mono<OAuth2User> oauth2User) {
return oauth2User
.mapNotNull(OAuth2User::getName)
.map(name -> String.format("Hi, %s", name));
}
}
My Angular App Demo call
sendRequest() {
const headers= new HttpHeaders()
.set('Access-Control-Allow-Origin', 'http://localhost:4200');
const requestOptions = { headers: headers };
this.http.get('http://localhost:8080/user')
.subscribe(response => this.apiResponse = response);
}
Please, help me to solve this cors issue.
Your CORS error is on a request to battle.net. It can't be fixed with the configuration of your Angular or Spring applications.
Instead of following redirects to battle.net within your app:
window.location.hrefto the battle.net authorization endpoint. That way origin will be battle.net (and not your Angular app)http://127.0.0.1:8080/login/oauth2/code/your-registration-id)http://localhost:4200/, unless your Spring client is aspring-cloud-gatewayalso proxying your Angular app with route likehttp://localhost:8080/ui)I have written a tutorial with an Angular app querying a Spring reactive OAuth2 client (a
spring-cloud-gatewayinstance). You can see how login is initiated in the Angular app there.