📜  url 编码不工作 Spring Boot oauth2 - Java (1)

📅  最后修改于: 2023-12-03 15:35:32.036000             🧑  作者: Mango

问题描述

当使用 Spring Boot oauth2 认证时,url 编码不起作用的问题。

原因分析

在使用 Spring Boot oauth2 认证时,经常需要在 URL 中传递一些参数。由于 URL 中不能直接传递特殊字符,因此需要对参数进行编码,常用的编码方式是 URL 编码。但是,在 Spring Boot oauth2 认证流程中,有一步是根据请求参数构建认证请求 URL,该步骤并没有使用 URL 编码,而是将参数拼接到 URL 上。因此,如果参数中包含特殊字符,就会导致认证请求 URL 构建失败。

解决方案

为了解决该问题,可以重写 Spring Boot oauth2 认证流程中的一些相关类,将参数按照 URL 编码的方式进行拼接。具体步骤如下:

  1. 创建一个自定义的 OAuth2AuthorizationRequestResolver 类。
public class CustomAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
  
  private final String clientRegistrationId
  
  public CustomAuthorizationRequestResolver(String clientRegistrationId, String authorizationUri) {
    this.clientRegistrationId = clientRegistrationId;
    this.authorizationUri = authorizationUri;
  }
  
  @Override
  public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
    ...
    Map<String, Object> additionalParameters = new HashMap<>();
    additionalParameters.put("redirect_uri", "<url_encoded_redirect_uri>");
    ...
    OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.
      authorizationCode().
      ...
      .additionalParameters(additionalParameters)
      .build();
    return authorizationRequest;
  }
}
  1. 创建一个自定义的 OAuth2AuthorizationRequest.Builder 类。
public class CustomAuthorizationRequestBuilder extends OAuth2AuthorizationRequest.Builder {
  
  private final String authorizationUri;
  
  public CustomAuthorizationRequestBuilder(String authorizationUri) {
    this.authorizationUri = authorizationUri;
  }
  
  @Override
  public OAuth2AuthorizationRequest build() {
    ...
    StringBuilder redirectUriBuilder = new StringBuilder(getRedirectUri());
    redirectUriBuilder.append("?client_id=").append(getClientId()).append("&");
    for (Map.Entry<String, String> entry : getAdditionalParameters().entrySet()) {
      redirectUriBuilder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)).append("=").append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)).append("&");
    }
    redirectUriBuilder.deleteCharAt(redirectUriBuilder.length() - 1);
    
    return super.redirectUri(redirectUriBuilder.toString()).build();
  }
}
  1. 在配置类中注册自定义的 OAuth2AuthorizationRequestResolver 和 OAuth2AuthorizationRequest.Builder。
@Configuration
public class OAuth2Config {
  
  @Value("${spring.security.oauth2.client.registration.client-id}")
  private String clientId;
  
  @Value("${spring.security.oauth2.client.registration.client-secret}")
  private String clientSecret;
  
  @Value("${spring.security.oauth2.client.registration.redirect-uri}")
  private String redirectUri;
  
  @Value("${spring.security.oauth2.client.provider.authorization-uri}")
  private String authorizationUri;
  
  @Bean
  public OAuth2AuthorizationRequestResolver authorizationRequestResolver() {
    return new CustomAuthorizationRequestResolver(clientId, authorizationUri);
  }
  
  @Bean
  public OAuth2AuthorizationRequest.Builder authorizationRequestBuilder() {
    return new CustomAuthorizationRequestBuilder(authorizationUri);
  }
}

通过以上步骤,就可以在 Spring Boot oauth2 认证流程中使用 URL 编码来拼接请求参数了。