oauth2.0 使用Spring授权服务器显示重定向URI无效的警告

q5lcpyga  于 6个月前  发布在  Spring
关注(0)|答案(1)|浏览(86)

我正在使用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";
    }
}


非常感谢

tquggr8v

tquggr8v1#

要覆盖OAuth2授权端点的错误行为,您可以在configurer中指定自己的.errorResponseHandler(...),它应该实现AuthenticationFailureHandler接口。例如,

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
    OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
        new OAuth2AuthorizationServerConfigurer();
    http.apply(authorizationServerConfigurer);

    authorizationServerConfigurer
        .authorizationEndpoint(authorizationEndpoint ->
            authorizationEndpoint 
                .errorResponseHandler((request, response, exception) -> {
                    // Handle errors with exception which is an instance of
                    // OAuth2AuthorizationCodeRequestAuthenticationException
                }) 
        );

    return http.build();
}

字符串
请参阅OAuth2AuthorizationEndpointFilter中的sendErrorResponse方法,了解默认情况下如何处理它。

更新:

如果您打算呈现与无效作用域相关的错误(例如400、401、403、500等),而不是执行重定向回客户端,则需要允许错误页面。默认情况下,包括错误页面在内的所有端点都需要身份验证。
例如,您可以通过将.requestMatchers("/error").permitAll()添加到第二个过滤器链(defaultSecurityFilterChain)中的授权规则来实现此操作。

相关问题