带有 Google 的 OAuth2 - CORS 错误(Angular + Spring boot)[重复]
Posted
技术标签:
【中文标题】带有 Google 的 OAuth2 - CORS 错误(Angular + Spring boot)[重复]【英文标题】:OAuth2 with Google - CORS Error (Angular + Spring boot) [duplicate] 【发布时间】:2020-02-07 00:18:13 【问题描述】:我遇到了 CORS 错误的问题。我确实请求了 Google oAuth2,但我收到了一个 CORS 错误: 我想获得谷歌身份验证并生成 JWT 令牌。当我在不使用客户端的情况下执行此操作时,一切都很好。当我发送角度请求时,这是 CORS 的问题。我允许所有类型的 CORS。为什么会出现此错误?
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.
我的 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 配置:
@Override
public void addCorsMappings(CorsRegistry registry)
registry
.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
.maxAge(MAX_AGE_SECS);
安全配置:
@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);
成功处理程序:
@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);
控制器:
@RestController
@RequestMapping("/api/v1/oauth2")
public class OAuth2Controller
@GetMapping("/authenticate")
public ResponseEntity<?> authenticateUser(@RequestParam String token)
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
【问题讨论】:
OAuth 2 需要实际重定向才能工作:tools.ietf.org/html/rfc6749#section-1.2 BTW 错误不是来自您的服务器,而是来自 Google 【参考方案1】:您无法在此示例中获取令牌,因为您需要进行实际重定向。有几种方法可以规避此要求,详细信息请参见 RFC https://www.rfc-editor.org/rfc/rfc6749#section-1.2
-
在弹出窗口中启动授权流程,并通过浏览器中提供的
postMessage()
API 将服务器收到的令牌从弹出窗口传回 web 应用程序。
保存状态,无论它是什么,重定向到服务器,该服务器将启动授权流程,在交换令牌以获得授权后,使用令牌作为查询字符串参数重定向回 webapp。然后使用它并恢复状态。
【讨论】:
我会寻找一些示例代码并尝试这样做。感谢您的时间。如果我成功了,我会通知你以上是关于带有 Google 的 OAuth2 - CORS 错误(Angular + Spring boot)[重复]的主要内容,如果未能解决你的问题,请参考以下文章
带有oauth2 sso和angular 2 CORS问题的spring zuul网关
Google OAuth2:重定向已被 CORS 政策阻止:请求需要预检,不允许遵循跨域重定向
CORS 干扰 Spring Security oauth2
Spring 5,401 返回后带有 Google 刷新访问令牌的 OAuth2