我有以下设置:
- 我有一个Angular前端和Spring Boot后端
- 用户通过正常的Form登录登录到我的后端
- 我正在集成一个需要oauth2身份验证的第三方API,因此用户需要授予我的应用程序权限,这样我就可以代表他们从该第三方加载数据
- 我在
HttpSecurity
配置中配置了oauth2Client()
以启用oauth2
目前发生的情况是:
- 前端调用端点从第三方获取数据,比如
/api/get-library
,它试图访问第三方的受保护资源 - 这将导致来自第三方的
401
,并在Spring中触发oauth流 - 用户被重定向到第三方以授予我的应用程序权限
- 授予权限后,用户首先被重定向到指定为
spring.security.oauth2.client.registration.foobar.redirect-uri
的Url - Spring Boot然后检索令牌并为我的Principal存储它
- 之后,Spring Boot重定向到原始url
/api/get-library
- 但这只是一些
RestController
,因此在浏览器中向用户显示一些JSON数据
所以第6点是我的问题。我不希望用户最终被重定向到某个API端点,我希望他被重定向到我的Angular应用程序的页面。
如果用户拒绝授予权限,也会出现类似的问题。然后,用户被重定向到具有查询参数?error=true
的spring.security.oauth2.client.registration.foobar.redirect-uri
。同样在这种情况下,我希望重定向到我的Angular应用程序。
起初,我想我也可以配置oauth2Login()
,它有failureHandler
和successHandler
,但在我的情况下没有调用它们,因为我没有在这里登录。
有人能帮我吗?如何为oauth2Client
配置自己的重定向?万一成功了,万一失败了?这里有哪些相关的豆子?
我找到了一个解决方案:
要检查的主要Spring类是OAuth2AuthorizationCodeGrantFilter
。当用户在OAuth提供程序授予/拒绝权限时,会调用此筛选器。
不幸的是,没有办法为这个过滤器配置自定义重定向Url,所以我实现了一个破解的解决方案:
- 我将
OAuth2AuthorizationCodeGrantFilter
的实现复制到自己的类中,并使用两个参数对其进行扩展:成功和错误返回Url。然后,我在processAuthorizationResponse
方法中使用这些URL重定向到我的URL - 然后,我将自己的
AppOAuth2AuthorizationCodeGrantFilter
放在HttpSecurityConfig
中的Spring Filter之前,因此使用它而不是Spring版本 - 在我的Angular应用程序中,在调用可能需要OAuth身份验证的Endpoint之前,我会将确切位置存储在应用程序中。因此,当用户代理返回到Angular应用程序时,我可以导航回原始位置
这感觉很粗糙,所以如果有人提出更好的解决方案,我会很高兴听到。:-(
Spring的一些代码片段:
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http.addFilterBefore(oAuth2AuthorizationCodeGrantFilter(), OAuth2AuthorizationCodeGrantFilter.class);
...
}
@Bean @Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public AppOAuth2AuthorizationCodeGrantFilter oAuth2AuthorizationCodeGrantFilter() throws Exception {
return new AppOAuth2AuthorizationCodeGrantFilter(
clientRegistrationRepository,
oAuth2AuthorizedClientRepository,
authenticationManagerBean(),
oauthSuccessRedirectUrl,
oauthErrorRedirectUrl);
}