Skip to content

Commit

Permalink
Merge pull request #16 from codestates-seb/dev
Browse files Browse the repository at this point in the history
Upstream Pull
  • Loading branch information
KYUNGMINMON authored Jun 23, 2023
2 parents 8a2829b + 489d070 commit 60c77dc
Show file tree
Hide file tree
Showing 19 changed files with 313 additions and 64 deletions.
3 changes: 3 additions & 0 deletions server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
//OAuth 2 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

//스프링 테스트를 위한 의존성추가
testImplementation 'org.springframework.security:spring-security-test'
implementation 'junit:junit:4.13.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.rainbow.sof.domain.user.auth.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rainbow.sof.domain.user.auth.jwt.DelegateTokenService;
import com.rainbow.sof.domain.user.auth.jwt.JwtTokenizer;
import com.rainbow.sof.domain.user.dto.singleDto.UserDto;
import com.rainbow.sof.domain.user.entity.User;
Expand All @@ -22,9 +23,12 @@
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
private final JwtTokenizer tokenizer;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtTokenizer tokenizer) {
public final DelegateTokenService delegateTokenService;

public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtTokenizer tokenizer, DelegateTokenService delegateTokenService) {
this.authenticationManager = authenticationManager;
this.tokenizer = tokenizer;
this.delegateTokenService = delegateTokenService;
}

@Override
Expand All @@ -47,8 +51,8 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR

User user = (User)authResult.getPrincipal();

String accessToken = delegateAccessToken(user);
String refreshToken = delegateRefreshToken(user);
String accessToken = delegateTokenService.delegateAccessToken(user);
String refreshToken = delegateTokenService.delegateRefreshToken(user);

response.setHeader("Authorization", "Bearer " + accessToken);
response.setHeader("Refresh",refreshToken);
Expand All @@ -57,25 +61,26 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR

}

private String delegateAccessToken(User user){
Map<String,Object> claims = new HashMap<>();
claims.put("email",user.getEmail());

Date expiration = tokenizer.getTokenExpiration(tokenizer.getAccessTokenExpirationMinutes());
String base64EncodedSecretKeyString = tokenizer.secretKeyEncodeBase64(tokenizer.getSecretKeySting());
String subject=user.getEmail();

return tokenizer.generateAccessToken(claims,subject,expiration,base64EncodedSecretKeyString);

}

private String delegateRefreshToken(User user){

Date expiration = tokenizer.getTokenExpiration(tokenizer.getAccessTokenExpirationMinutes());
String base64EncodedSecretKeyString = tokenizer.secretKeyEncodeBase64(tokenizer.getSecretKeySting());
String subject=user.getEmail();

return tokenizer.generateRefreshToken(subject,expiration,base64EncodedSecretKeyString);

}
//TODO: 이전 토큰 생성 메서드
// private String delegateAccessToken(User user){
// Map<String,Object> claims = new HashMap<>();
// claims.put("email",user.getEmail());
//
// Date expiration = tokenizer.getTokenExpiration(tokenizer.getAccessTokenExpirationMinutes());
// String base64EncodedSecretKeyString = tokenizer.secretKeyEncodeBase64(tokenizer.getSecretKeySting());
// String subject=user.getEmail();
//
// return tokenizer.generateAccessToken(claims,subject,expiration,base64EncodedSecretKeyString);
//
// }
//
// private String delegateRefreshToken(User user){
//
// Date expiration = tokenizer.getTokenExpiration(tokenizer.getAccessTokenExpirationMinutes());
// String base64EncodedSecretKeyString = tokenizer.secretKeyEncodeBase64(tokenizer.getSecretKeySting());
// String subject=user.getEmail();
//
// return tokenizer.generateRefreshToken(subject,expiration,base64EncodedSecretKeyString);
//
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//package com.rainbow.sof.domain.user.auth.handler.oauthHandler;
//
//import org.springframework.security.core.AuthenticationException;
//import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
//
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//
//public class OAuth2FailureHandler extends SimpleUrlAuthenticationFailureHandler {
// @Override
// public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
// chain.doFilter(httpRequest,response);
// }
//}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.rainbow.sof.domain.user.auth.handler.oauthHandler;

import com.rainbow.sof.domain.user.auth.jwt.DelegateTokenService;
import com.rainbow.sof.domain.user.auth.jwt.JwtTokenizer;
import com.rainbow.sof.domain.user.entity.User;
import com.rainbow.sof.domain.user.service.UserService;
import com.rainbow.sof.global.error.BusinessLogicException;
import com.rainbow.sof.global.error.ExceptionCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.rainbow.sof.domain.user.util.CustomEnumUri.*;

@Slf4j
public class OAuth2SuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private final DelegateTokenService delegateTokenService;
private final UserService userService;

public OAuth2SuccessHandler(DelegateTokenService delegateTokenService, UserService userService) {
this.delegateTokenService = delegateTokenService;
this.userService = userService;
}

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
OAuth2User UserData = (OAuth2User)authentication.getPrincipal();
String email = String.valueOf(UserData.getAttributes().get("email"));
String name = String.valueOf(UserData.getAttributes().get("name"));

User createUser = User.builder().email(email)
.name(name)
.password("Q1234123452234522").build();
User oAuth2User= saveUser(createUser);
log.info("onAuthenticationSuccess: {} ", oAuth2User.getName());
log.info("onAuthenticationSuccess: {}" ,oAuth2User.getEmail());
redirect(request, response,oAuth2User);

}

private User saveUser(User oAuth2User) {
try {
return userService.createUser(oAuth2User);
}catch (BusinessLogicException e){

return e.getExceptionCode().equals(ExceptionCode.USER_EXISTS) ?
userService.findByUserFromEmail(oAuth2User.getEmail()) :
null;
}
}

private void redirect(HttpServletRequest request, HttpServletResponse response, User user) throws IOException {
String accessToken = delegateTokenService.delegateAccessToken(user);
String refreshToken = delegateTokenService.delegateRefreshToken(user);


String uri = createURI().toString();
response.setHeader("Authorization", "Bearer " + accessToken);
response.setHeader("Refresh",refreshToken);

getRedirectStrategy().sendRedirect(request, response, "/mypage");
String s = getRedirectStrategy().toString();
}

//TODO: 클라이언트 주소로 변경 필요
private URI createURI() {
return UriComponentsBuilder
.newInstance()
.scheme("http")
.host("localhost")
// .port(80)
.path("/receive-token.html")
.build()
.toUri();
}


}
// Map<String, String> oAuth2UserData = new HashMap<>();
// oAuth2UserData.put("email", String.valueOf(oAuth2User.getAttributes().get("email")));
// oAuth2UserData.put("name", String.valueOf(oAuth2User.getAttributes().get("name")));
// User createUser= saveUser(oAuth2UserData);
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.rainbow.sof.domain.user.auth.jwt;

import com.rainbow.sof.domain.user.entity.User;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Component
public class DelegateTokenService {
private final JwtTokenizer tokenizer;

public DelegateTokenService(JwtTokenizer tokenizer) {
this.tokenizer = tokenizer;
}

public String delegateAccessToken(User user){
Map<String,Object> claims = new HashMap<>();
claims.put("email",user.getEmail());

Date expiration = tokenizer.getTokenExpiration(tokenizer.getAccessTokenExpirationMinutes());
String base64EncodedSecretKeyString = tokenizer.secretKeyEncodeBase64(tokenizer.getSecretKeySting());
String subject=user.getEmail();

return tokenizer.generateAccessToken(claims,subject,expiration,base64EncodedSecretKeyString);

}

public String delegateRefreshToken(User user){

Date expiration = tokenizer.getTokenExpiration(tokenizer.getAccessTokenExpirationMinutes());
String base64EncodedSecretKeyString = tokenizer.secretKeyEncodeBase64(tokenizer.getSecretKeySting());
String subject=user.getEmail();

return tokenizer.generateRefreshToken(subject,expiration,base64EncodedSecretKeyString);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.jsonwebtoken.security.Keys;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
Expand All @@ -18,19 +19,21 @@
public class JwtTokenizer {

@Getter
@Value("${User.mail.admin}")
private static String ADMIN_SUBJECT = "ADMIN@ADMIN.com";

@Getter
@Value("${User.mail.disable}")
private static String USER_DISABLE_MAIL="disable@disable.com";
@Getter
@Value("thisIsTestScretKeythisIsTestScretKeythisIsTestScretKeythisIsTestScretKey")
@Value("${jwt.key.secret}")
private String secretKeySting;

@Getter
@Value("60")
@Value("${jwt.access-token-expiration-minutes}")
private int accessTokenExpirationMinutes;
@Getter
@Value("300")
@Value("${jwt.refresh-token-expiration-minutes}")
private int refreshTokenExpirationMinutes;

//시크릿키로 이용할 무작위 문자열을 바이트배열로 변환
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,47 @@
import com.rainbow.sof.domain.user.auth.filter.JwtVerificationFilterV2;
import com.rainbow.sof.domain.user.auth.handler.loginhandle.UserAuthenticationFailureHandler;
import com.rainbow.sof.domain.user.auth.handler.loginhandle.UserAuthenticationSuccessHandler;
import com.rainbow.sof.domain.user.auth.handler.oauthHandler.OAuth2SuccessHandler;
import com.rainbow.sof.domain.user.auth.jwt.DelegateTokenService;
import com.rainbow.sof.domain.user.auth.jwt.JwtTokenizer;
import com.rainbow.sof.domain.user.service.UserService;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.stereotype.Component;


@Component
public class CustomFilterConfigurer extends AbstractHttpConfigurer<CustomFilterConfigurer, HttpSecurity> {
private final JwtTokenizer jwtTokenizer;
public final DelegateTokenService delegateTokenService;



public CustomFilterConfigurer(JwtTokenizer jwtTokenizer) {

public CustomFilterConfigurer(JwtTokenizer jwtTokenizer, DelegateTokenService delegateTokenService) {
this.jwtTokenizer = jwtTokenizer;
this.delegateTokenService = delegateTokenService;

}

@Override
public void configure(HttpSecurity builder) throws Exception {
AuthenticationManager authenticationManager = builder.getSharedObject(AuthenticationManager.class);
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager,jwtTokenizer);
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager,jwtTokenizer,delegateTokenService);

jwtAuthenticationFilter.setFilterProcessesUrl("/api/v1/login");
jwtAuthenticationFilter.setAuthenticationSuccessHandler(new UserAuthenticationSuccessHandler());
jwtAuthenticationFilter.setAuthenticationFailureHandler(new UserAuthenticationFailureHandler());

JwtVerificationFilterV2 jwtVerificationFilterV2 = new JwtVerificationFilterV2(jwtTokenizer);

builder.addFilter(jwtAuthenticationFilter)
.addFilterAfter(jwtVerificationFilterV2,JwtAuthenticationFilter.class);
builder.addFilterAfter(jwtVerificationFilterV2, OAuth2LoginAuthenticationFilter.class)
.addFilterBefore(jwtAuthenticationFilter,JwtVerificationFilterV2.class);
}

//.addFilter(jwtAuthenticationFilter)
// .addFilterAfter(jwtVerificationFilterV2,JwtAuthenticationFilter.class);

}
Loading

0 comments on commit 60c77dc

Please sign in to comment.