@@ -0,0 +1,71 @@
+package nextstep.security.authentication;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+import nextstep.security.authentication.OAuth2ClientProperties.Provider;
+import nextstep.security.authentication.OAuth2ClientProperties.Registration;
+import org.springframework.http.HttpMethod;
+import org.springframework.web.filter.GenericFilterBean;
+import org.springframework.web.util.UriComponentsBuilder;
+
+public class OAuth2LoginRedirectFilter extends GenericFilterBean {
+
+  private static final String REQUEST_URI = "/oauth2/authorization";
+
+  private final Map<String, Registration> registrations;
+  private final Map<String, Provider> providers;
+
+  public OAuth2LoginRedirectFilter(OAuth2ClientProperties properties) {
+    this.registrations = properties.getRegistrations();
+    this.providers = properties.getProviders();
+  }
+
+  @Override
+  public void doFilter(ServletRequest request,
+      ServletResponse response,
+      FilterChain chain) throws IOException, ServletException {
+    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+
+    String requestURI = httpServletRequest.getRequestURI();
+    String method = httpServletRequest.getMethod();
+
+    String registrationSource = null;
+    if (requestURI.startsWith(REQUEST_URI)) {
+      registrationSource = getRegistrationId(requestURI);
+    }
+
+    if (registrationSource != null && method.equals(HttpMethod.GET.name())) {
+      Registration registration = registrations.get(registrationSource);
+      Provider provider = providers.get(registrationSource);
+
+      String redirectUri = UriComponentsBuilder.fromHttpUrl(provider.authorizationUri())
+          .queryParam("client_id", registration.clientId())
+          .queryParam("scope", String.join(" ", registration.scope()))
+          .queryParam("response_type", "code")
+          .queryParam("redirect_uri", registration.redirectUri())
+          .build()
+          .toUriString();
+
+      httpServletResponse.sendRedirect(redirectUri);
+      return;
+    }
+
+    chain.doFilter(request, response);
+  }
+
+  private String getRegistrationId(String requestURI) {
+    for (String registrationId : registrations.keySet()) {
+      if (requestURI.contains(registrationId)) {
+        return registrationId;
+      }
+    }
+    return null;
+  }
+}

리뷰: 놀랍게도

여기 grant_type 마저 yml에 등록하고자
```yml
  github:
    provider: "github"
    client-id: "Ov23lijfjg9lkGyYVDXN"
    client-secret: "YOUR_GITHUB_CLIENT_SECRET"
    scope:
      - read:user
    redirect-uri: "http://localhost:8080/login/oauth2/code/github"
    authorization-grant-type: authorization_code
```
작성 한 후 

// **as-is**
```java
  public String getAccessToken(String code, Registration registration, Provider provider) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);

    Map<String, String> params = new HashMap<>();
    params.put("code", code);
    params.put("client_id", registration.clientId());
    params.put("client_secret", registration.clientSecret());
    params.put("redirect_uri", registration.redirectUri());
    params.put("grant_type", "authorization_code");
```

// **to-be**
```java
  public String getAccessToken(String code, Registration registration, Provider provider) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);

    Map<String, String> params = new HashMap<>();
    params.put("code", code);
    params.put("client_id", registration.clientId());
    params.put("client_secret", registration.clientSecret());
    params.put("redirect_uri", registration.redirectUri());
    params.put("grant_type", registration.authorizationGrantType());
```
로 하려던게 어쩌다가 흘러간것 같습니다...😱