OAuth2 con Google - CORS error (+ angular de arranque de primavera)

votos
-1

Tengo un problema con el error CORS. Hago solicitud de Google OAuth2 y me sale un error CORS: Quiero conseguir una autentificación Google y generar un token JWT. Cuando lo hago sin utilizar el cliente de todo está bien. Cuando envío peticiones angulares esto es un problema con CORS. Me permito todo tipo de CORS. ¿Por qué recibo este error?

Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=1020159669873-d9r35ssmnejud852bam87d8gqtcj5qf1.apps.googleusercontent.com&scope=openid%20profile%20email&state=8nizHP1X2z9sA8m0vqM4Lzd6VT24R15eSw5flteTywM%3D&redirect_uri=http://localhost:8080/oauth2/callback/google' (redirected from 'http://localhost:8080/oauth2/authorization/google')
from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Cross-Origin Read Blocking (CORB) blocked cross-origin response https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=1020159669873-d9r35ssmnejud852bam87d8gqtcj5qf1.apps.googleusercontent.com&scope=openid%20profile%20email&state=8nizHP1X2z9sA8m0vqM4Lzd6VT24R15eSw5flteTywM%3D&redirect_uri=http://localhost:8080/oauth2/callback/google with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.

Mi solicitud Angular:

 googleLogin(): Observable<LoginResponse> {
    return this.http.get<LoginResponse>
    (environment.baseUrl + '/oauth2/authorization/google')
      .pipe(tap(response => {
        localStorage.setItem('access_token', response.accessToken);
      }));
  }

//...

public onGoogleLogin(): void {
   this.authService.googleLogin().subscribe();
 }

//...

CORS CONFIG:

 @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry
                .addMapping(/**)
                .allowedOrigins(*)
                .allowedMethods(HEAD, OPTIONS, GET, POST, PUT, PATCH, DELETE)
                .maxAge(MAX_AGE_SECS);
    }

configuración de seguridad:

   @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                    .and()
                .csrf()
                    .disable()
                .exceptionHandling()
                    .authenticationEntryPoint(unauthorizedHandler)
                    .and()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                .authorizeRequests()
                    .antMatchers(/,
                /favicon.ico,
                /**/*.png,
                /**/*.gif,
                /**/*.svg,
                /**/*.jpg,
                /**/*.html,
                /**/*.css,
                /**/*.js)
                        .permitAll()
                .antMatchers(/api/v1/oauth0/**)
                        .permitAll()
                .antMatchers(/api/v1/oauth2/**)
                    .permitAll()
                .anyRequest()
                    .authenticated()
                    .and()
                // włączenie obslugi oauth2
                .oauth2Login()
                .successHandler(this.successHandler)
                .redirectionEndpoint()
                    .baseUri(/oauth2/callback/*)
                    .and()
                .userInfoEndpoint()
                    .oidcUserService(customOidcUserService);
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

Manipulador de éxito:

@Autowired
    private UserRepository userRepository;

    @Autowired
    private JwtTokenProvider tokenProvider;

    private final static String URL = http://localhost:8080/api/v1/oauth2/authenticate;

    @Override
    public void onAuthenticationSuccess(
            HttpServletRequest request,
            HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {

        if (response.isCommitted()) {
            return; }

        DefaultOidcUser oidcUser = (DefaultOidcUser) authentication.getPrincipal();
        System.out.println(oidcUser);
        Map attributes = oidcUser.getAttributes();
        String email = attributes.get(email).toString();
        User user = userRepository.findByEmail(email).orElseThrow(
                () -> new ResourceNotFoundException(User, email, email)
        );
        String token = tokenProvider.generateToken(user);
        String redirectionUrl = UriComponentsBuilder.fromUriString(URL).queryParam(token, token)
                .build().toUriString();
        getRedirectStrategy().sendRedirect(request, response, redirectionUrl);
    }
}

Controlador:

@RestController
@RequestMapping(/api/v1/oauth2)
public class OAuth2Controller {

    @GetMapping(/authenticate)
    public ResponseEntity<?> authenticateUser(@RequestParam String token) {
        return ResponseEntity.ok(new JwtAuthenticationResponse(token));
    }
}
Publicado el 09/10/2019 a las 18:49
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
1

No se puede obtener el token en este ejemplo como lo necesario para hacer redirecciones actuales. Hay un par de maneras en que podría eludir este requisito que se detalla en el RFC https://tools.ietf.org/html/rfc6749#section-1.2

  1. Iniciar el flujo de autorización en una ventana emergente y pasar de nuevo el token recibido por el servidor a través de postMessage()la API proporcionada en el navegador, en la ventana emergente de nuevo a la aplicación web.
  2. Guardar el estado, sea lo que sea, redirigir al servidor, que iniciará el flujo de autorización y después de token se intercambia por una subvención, redirigir de nuevo a la aplicación de web con un token como parámetro de cadena de consulta. Luego usarlo y restaurar el estado.
Respondida el 09/10/2019 a las 19:10
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more