我正在使用Spring Authorization for OAuth2,当对/authorize
端点的请求具有无效的重定向URI时,我想向用户显示警告,即URI未为客户端注册。
下面是我的授权服务器配置:
@Configuration
public class SecurityConfiguration {
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
// Enable OpenID Connect 1.0
.oidc(Customizer.withDefaults())
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.errorResponseHandler(new CustomErrorResponseHandler()));
http
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer((resourceServer) -> resourceServer.jwt(Customizer.withDefaults()));
return http.cors(Customizer.withDefaults()).build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/css/**").permitAll()
.requestMatchers("/").permitAll()
.anyRequest().authenticated()
)
// Form login handles the redirect to the login page from the
// authorization server filter chain
.formLogin(form -> form.loginPage("/login").permitAll())
.logout(logout -> logout.logoutUrl("/logout"));
return http.cors(Customizer.withDefaults()).build();
}
}
字符串
而CustomErrorResponseHandler
如下
public class CustomErrorResponseHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
OAuth2AuthorizationCodeRequestAuthenticationException authorizationCodeRequestAuthenticationException =
(OAuth2AuthorizationCodeRequestAuthenticationException) exception;
OAuth2Error error = authorizationCodeRequestAuthenticationException.getError();
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
authorizationCodeRequestAuthenticationException.getAuthorizationCodeRequestAuthentication();
if (authorizationCodeRequestAuthentication == null ||
!StringUtils.hasText(authorizationCodeRequestAuthentication.getRedirectUri())) {
response.sendError(500);
}
else {
response.sendError(HttpStatus.FORBIDDEN.value());
}
}
}
型
当我使用Postman来测试授权代码流时,我故意请求无效的作用域。然而,我没有收到500的状态代码,而是得到302重定向到/error
。为什么response.sendError(500)
被忽略了?
我也试图恢复错误控制器中的状态码,但它总是空的。
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
int statusCode = Integer.parseInt(status.toString());
System.out.println("Status code "+statusCode);
}
else {
System.out.println("No status code");
}
return "error";
}
}
型
非常感谢
1条答案
按热度按时间tquggr8v1#
要覆盖OAuth2授权端点的错误行为,您可以在configurer中指定自己的
.errorResponseHandler(...)
,它应该实现AuthenticationFailureHandler
接口。例如,字符串
请参阅
OAuth2AuthorizationEndpointFilter
中的sendErrorResponse方法,了解默认情况下如何处理它。更新:
如果您打算呈现与无效作用域相关的错误(例如400、401、403、500等),而不是执行重定向回客户端,则需要允许错误页面。默认情况下,包括错误页面在内的所有端点都需要身份验证。
例如,您可以通过将
.requestMatchers("/error").permitAll()
添加到第二个过滤器链(defaultSecurityFilterChain
)中的授权规则来实现此操作。