-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[#5][FEATURE] Spring Security로 로그인 필터 추가
- Loading branch information
Showing
25 changed files
with
638 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
src/main/java/com/moin/remittance/application/v1/util/Bcrypt.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.moin.remittance.application.v1.util; | ||
|
||
public class Bcrypt { | ||
// BCrypt | ||
} |
2 changes: 1 addition & 1 deletion
2
...mittance/util/ExchangeRateCalculator.java → ...ation/v1/util/ExchangeRateCalculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ava/com/moin/remittance/util/JwtUtil.java → ...mittance/application/v1/util/JwtUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package com.moin.remittance.util; | ||
package com.moin.remittance.application.v1.util; | ||
|
||
|
||
public class JwtUtil { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
src/main/java/com/moin/remittance/core/configration/JwtConfigProps.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.moin.remittance.core.configration; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class JwtConfigProps { | ||
|
||
@Schema(description = "jwt 암호화 키") | ||
@Value("${spring.jwt.SECRET_KEY}") | ||
public String SECRET_KEY; | ||
|
||
@Value("${spring.jwt.AUTH_LOGIN_END_POINT}") | ||
public String AUTH_LOGIN_END_POINT; | ||
|
||
@Value("${spring.jwt.AUTH_TOKEN_HEADER}") | ||
public String AUTH_TOKEN_HEADER; | ||
|
||
@Value("${spring.jwt.AUTH_TOKEN_PREFIX}") | ||
public String AUTH_TOKEN_PREFIX; | ||
|
||
@Value("${spring.jwt.AUTH_TOKEN_TYPE}") | ||
public String AUTH_TOKEN_TYPE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
src/main/java/com/moin/remittance/core/jwt/application/AuthUserDetailService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.moin.remittance.core.jwt.application; | ||
|
||
|
||
import com.moin.remittance.core.jwt.provider.AuthUserDetailsProvider; | ||
import com.moin.remittance.domain.entity.member.v2.MemberEntityV2; | ||
import com.moin.remittance.exception.NotFoundMemberException; | ||
import com.moin.remittance.repository.v2.MemberRepositoryV2; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.security.authentication.InternalAuthenticationServiceException; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.security.core.userdetails.UserDetailsService; | ||
import org.springframework.stereotype.Service; | ||
|
||
import static com.moin.remittance.domain.vo.HttpResponseCode.BAD_NOT_MATCH_MEMBER; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class AuthUserDetailService implements UserDetailsService { | ||
|
||
private final MemberRepositoryV2 memberRepositoryV2; | ||
|
||
/** | ||
* Spring Security => 유저 정보 조회 => 인증 처리 | ||
* */ | ||
@Override | ||
public UserDetails loadUserByUsername(String userId) throws InternalAuthenticationServiceException { | ||
log.info("'" + userId + "' 조회 중......"); | ||
|
||
MemberEntityV2 member = memberRepositoryV2.findByUserId(userId); | ||
|
||
/* | ||
* @Exception NotFoundMemberException: DB에 일치하는 유저 없는 경우 | ||
* */ | ||
if(member == null) { | ||
throw new NotFoundMemberException(BAD_NOT_MATCH_MEMBER); | ||
} | ||
|
||
log.info("'" + userId + "' 존재"); | ||
|
||
return new AuthUserDetailsProvider(member); | ||
} | ||
} |
142 changes: 142 additions & 0 deletions
142
src/main/java/com/moin/remittance/core/jwt/filter/JwtAuthenticationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package com.moin.remittance.core.jwt.filter; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.moin.remittance.core.configration.JwtConfigProps; | ||
import com.moin.remittance.core.jwt.provider.AuthUserDetailsProvider; | ||
import com.moin.remittance.core.jwt.provider.JwtTokenProvider; | ||
import com.moin.remittance.domain.dto.responsebody.HttpResponseBody; | ||
import com.moin.remittance.exception.NotFoundMemberException; | ||
import com.moin.remittance.exception.dto.ErrorResponseDTO; | ||
import jakarta.servlet.FilterChain; | ||
import jakarta.servlet.ServletException; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
import org.springframework.stereotype.Component; | ||
|
||
|
||
import java.io.IOException; | ||
import java.util.Iterator; | ||
|
||
import static com.moin.remittance.domain.vo.HttpResponseCode.BAD_NOT_MATCH_MEMBER; | ||
import static com.moin.remittance.domain.vo.HttpResponseCode.SUCCESS_MEMBER_LOGIN; | ||
|
||
|
||
@Slf4j | ||
@Component | ||
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { | ||
|
||
@Autowired | ||
private final AuthenticationManager authenticationManager; | ||
|
||
private final JwtTokenProvider jwtTokenProvider; | ||
|
||
private final JwtConfigProps jwtConfigProps; | ||
|
||
private final ObjectMapper objectMapper; | ||
|
||
public JwtAuthenticationFilter(AuthenticationManager authenticationManager, | ||
JwtTokenProvider jwtTokenProvider, | ||
JwtConfigProps jwtConfigProps, ObjectMapper objectMapper | ||
) { | ||
this.authenticationManager = authenticationManager; | ||
this.jwtTokenProvider = jwtTokenProvider; | ||
this.jwtConfigProps = jwtConfigProps; | ||
this.objectMapper = objectMapper; | ||
|
||
super.setAuthenticationManager(authenticationManager); | ||
|
||
log.info("authenticationManager" + authenticationManager); | ||
setFilterProcessesUrl(jwtConfigProps.AUTH_LOGIN_END_POINT); | ||
} | ||
|
||
/** | ||
* 🔐 인증 시도 메소드 | ||
* /login 엔드포인트로 요청 => 필터 => 인증 시도 | ||
*/ | ||
@Override | ||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { | ||
|
||
String userId = obtainUsername(request); | ||
String password = obtainPassword(request); | ||
|
||
log.info("userId: " + userId); | ||
log.info("password: " + password); | ||
|
||
// 인증정보 객체 생성: 스프링 시큐리티에서 username, password 검증하기 위해서는 token에 담아야 함 | ||
Authentication authentication = new UsernamePasswordAuthenticationToken(userId, password); | ||
log.info("authentication: " + authentication); | ||
|
||
// 사용자 인증 여부를 판단하는 객체 | ||
authentication = authenticationManager.authenticate(authentication); | ||
|
||
log.info("인증 여부: " + authentication.isAuthenticated()); | ||
|
||
if (!authentication.isAuthenticated()) { | ||
log.info("인증 실패!!!"); | ||
throw new NotFoundMemberException(BAD_NOT_MATCH_MEMBER); | ||
} | ||
|
||
return authentication; | ||
} | ||
|
||
@Override | ||
protected void successfulAuthentication( | ||
HttpServletRequest request, | ||
HttpServletResponse response, | ||
FilterChain filterChain, | ||
Authentication authentication | ||
) throws IOException, ServletException { | ||
AuthUserDetailsProvider member = (AuthUserDetailsProvider) authentication.getPrincipal(); | ||
|
||
Iterator<? extends GrantedAuthority> iterator = member.getAuthorities().iterator(); | ||
String idType = iterator.next().getAuthority(); | ||
String userId = member.getUsername(); | ||
|
||
String jwt = jwtTokenProvider.createAuthorizationToken(userId, idType, 60 * 60 * 30); | ||
|
||
log.info("jwt: " + jwt); | ||
|
||
|
||
//스프링 시큐리티 인증 토큰 생성 | ||
Authentication authToken = new UsernamePasswordAuthenticationToken(member, null); | ||
|
||
SecurityContextHolder.getContext().setAuthentication(authToken); | ||
|
||
// JSON 으로 변환하여 응답 본문에 작성 | ||
response.addHeader(jwtConfigProps.AUTH_TOKEN_HEADER, jwtConfigProps.AUTH_TOKEN_PREFIX + jwt); | ||
response.setStatus(SUCCESS_MEMBER_LOGIN.getStatusCode()); | ||
response.setContentType("application/json;charset=UTF-8"); | ||
response.getWriter().write(objectMapper.writeValueAsString(HttpResponseBody.builder() | ||
.statusCode(SUCCESS_MEMBER_LOGIN.getStatusCode()) | ||
.message(SUCCESS_MEMBER_LOGIN.getMessage()) | ||
.codeName(SUCCESS_MEMBER_LOGIN.getCodeName()) | ||
.token(jwt) | ||
.build() | ||
) | ||
); | ||
} | ||
|
||
@Override | ||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException { | ||
// JSON 으로 변환하여 응답 본문에 작성 | ||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST); | ||
response.setContentType("application/json;charset=UTF-8"); | ||
response.getWriter().write(objectMapper.writeValueAsString(ErrorResponseDTO.builder() | ||
.code(BAD_NOT_MATCH_MEMBER.getStatusCode()) | ||
.message(BAD_NOT_MATCH_MEMBER.getMessage()) | ||
.codeName(BAD_NOT_MATCH_MEMBER.getCodeName()) | ||
.build() | ||
) | ||
); | ||
} | ||
} |
Oops, something went wrong.