Skip to content

Commit

Permalink
fix: OAuth 콜백 파라미터로 리다이렉트 위치를 지정하도록 수정 (#685)
Browse files Browse the repository at this point in the history
* feat: 인가 요청 시 추가 파라미터 설정하는 커스텀 리졸버 구현

* feat: 시큐리티 설정에 커스텀 리졸버 등록

* feat: 리다이렉트 시 파라미터로부터 타깃 위치 로드하도록 설정
  • Loading branch information
uwoobeat authored Aug 24, 2024
1 parent fb8b086 commit 2ee4399
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class SecurityConstant {
public static final String GITHUB_NAME_ATTR_KEY = "id";
public static final String ACCESS_TOKEN_HEADER_PREFIX = "Bearer ";
public static final String OAUTH_REDIRECT_PATH_SEGMENT = "/social-login/redirect";
public static final String OAUTH_TARGET_URL_PARAM_NAME = "target";

private SecurityConstant() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.gdschongik.gdsc.domain.member.dao.MemberRepository;
import com.gdschongik.gdsc.global.annotation.ConditionalOnProfile;
import com.gdschongik.gdsc.global.property.BasicAuthProperty;
import com.gdschongik.gdsc.global.security.CustomOAuth2AuthorizationRequestResolver;
import com.gdschongik.gdsc.global.security.CustomSuccessHandler;
import com.gdschongik.gdsc.global.security.CustomUserService;
import com.gdschongik.gdsc.global.security.JwtExceptionFilter;
Expand All @@ -31,6 +32,7 @@
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutFilter;
Expand All @@ -49,6 +51,7 @@ public class WebSecurityConfig {
private final ObjectMapper objectMapper;
private final EnvironmentUtil environmentUtil;
private final BasicAuthProperty basicAuthProperty;
private final ClientRegistrationRepository clientRegistrationRepository;

private void defaultFilterChain(HttpSecurity http) throws Exception {
http.httpBasic(AbstractHttpConfigurer::disable)
Expand Down Expand Up @@ -94,10 +97,11 @@ public SecurityFilterChain prometheusFilterChain(HttpSecurity http) throws Excep
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
defaultFilterChain(http);

http.oauth2Login(
oauth2 -> oauth2.userInfoEndpoint(userInfo -> userInfo.userService(customUserService(memberRepository)))
.successHandler(customSuccessHandler(jwtService, cookieUtil))
.failureHandler((request, response, exception) -> response.setStatus(401)));
http.oauth2Login(oauth2 -> oauth2.authorizationEndpoint(
endpoint -> endpoint.authorizationRequestResolver(customOAuth2AuthorizationRequestResolver()))
.userInfoEndpoint(userInfo -> userInfo.userService(customUserService(memberRepository)))
.successHandler(customSuccessHandler(jwtService, cookieUtil))
.failureHandler((request, response, exception) -> response.setStatus(401)));

http.exceptionHandling(exception ->
exception.authenticationEntryPoint((request, response, authException) -> response.setStatus(401)));
Expand Down Expand Up @@ -140,6 +144,11 @@ public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public CustomOAuth2AuthorizationRequestResolver customOAuth2AuthorizationRequestResolver() {
return new CustomOAuth2AuthorizationRequestResolver(clientRegistrationRepository);
}

@Bean
public CustomUserService customUserService(MemberRepository memberRepository) {
return new CustomUserService(memberRepository);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.gdschongik.gdsc.global.security;

import static com.gdschongik.gdsc.global.common.constant.SecurityConstant.*;

import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;

public class CustomOAuth2AuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {

private final DefaultOAuth2AuthorizationRequestResolver delegate;

public CustomOAuth2AuthorizationRequestResolver(ClientRegistrationRepository clientRegistrationRepository) {
this.delegate =
new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository, "/oauth2/authorization");
}

@Override
public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
OAuth2AuthorizationRequest authorizationRequest = delegate.resolve(request);
return authorizationRequest != null ? customizeAuthorizationRequest(request, authorizationRequest) : null;
}

@Override
public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) {
OAuth2AuthorizationRequest authorizationRequest = delegate.resolve(request, clientRegistrationId);
return authorizationRequest != null ? customizeAuthorizationRequest(request, authorizationRequest) : null;
}

private OAuth2AuthorizationRequest customizeAuthorizationRequest(
HttpServletRequest request, OAuth2AuthorizationRequest authorizationRequest) {

String referer = request.getHeader("Referer");
if (referer == null || referer.isEmpty()) {
return authorizationRequest;
}

Map<String, Object> additionalParameters = new HashMap<>();
additionalParameters.put(OAUTH_TARGET_URL_PARAM_NAME, referer);

return OAuth2AuthorizationRequest.from(authorizationRequest)
.additionalParameters(additionalParameters)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler
public CustomSuccessHandler(JwtService jwtService, CookieUtil cookieUtil) {
this.jwtService = jwtService;
this.cookieUtil = cookieUtil;
setUseReferer(true);
setTargetUrlParameter(OAUTH_TARGET_URL_PARAM_NAME);
}

@Override
Expand Down

0 comments on commit 2ee4399

Please sign in to comment.