-
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.
- Loading branch information
Showing
12 changed files
with
242 additions
and
5 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
src/main/java/com/nice/petudio/api/member/service/MemberServiceUtils.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,15 @@ | ||
package com.nice.petudio.api.member.service; | ||
|
||
import com.nice.petudio.domain.member.Member; | ||
import com.nice.petudio.domain.member.repository.MemberRepository; | ||
import com.nice.petudio.global.exception.NotFoundException; | ||
import com.nice.petudio.global.exception.error.ErrorCode; | ||
|
||
public class MemberServiceUtils { | ||
|
||
public static Member findMemberById(MemberRepository memberRepository, Long memberId) { | ||
return memberRepository.findById(memberId) | ||
.orElseThrow(() -> new NotFoundException(ErrorCode.NOT_FOUND_MEMBER_EXCEPTION, | ||
String.format("====> 존재하지 않는 memberId(%d) 입니다.", memberId))); | ||
} | ||
} |
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
14 changes: 14 additions & 0 deletions
14
src/main/java/com/nice/petudio/global/auth/admin/Admin.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,14 @@ | ||
package com.nice.petudio.global.auth.admin; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Role이 Admin 인지 확인하기 위한 애노테이션 | ||
*/ | ||
@Target(ElementType.METHOD) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface Admin { | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/nice/petudio/global/auth/admin/AdminAuthInterceptor.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,35 @@ | ||
package com.nice.petudio.global.auth.admin; | ||
|
||
import com.nice.petudio.domain.member.MemberRole; | ||
import com.nice.petudio.global.auth.handler.AuthCheckHandler; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.method.HandlerMethod; | ||
import org.springframework.web.servlet.HandlerInterceptor; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class AdminAuthInterceptor implements HandlerInterceptor { | ||
|
||
private final AuthCheckHandler authHandler; | ||
|
||
@Override | ||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { | ||
if (handler instanceof HandlerMethod) { | ||
HandlerMethod handlerMethod = (HandlerMethod) handler; | ||
Optional<Admin> adminAuth = Optional.ofNullable( | ||
handlerMethod.getMethodAnnotation(Admin.class)); | ||
|
||
if (adminAuth.isEmpty()) { | ||
return true; | ||
} | ||
authHandler.validateAuthority(request, List.of(MemberRole.ADMIN)); | ||
return true; | ||
} | ||
return true; | ||
} | ||
} |
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,14 @@ | ||
package com.nice.petudio.global.auth.auth; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* 서비스의 회원이 맞는지 확인하기 위한 애노테이션 | ||
*/ | ||
@Target(ElementType.METHOD) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface Auth { | ||
} |
37 changes: 37 additions & 0 deletions
37
src/main/java/com/nice/petudio/global/auth/auth/AuthInterceptor.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,37 @@ | ||
package com.nice.petudio.global.auth.auth; | ||
|
||
import com.nice.petudio.domain.member.MemberRole; | ||
import com.nice.petudio.global.auth.handler.AuthCheckHandler; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.method.HandlerMethod; | ||
import org.springframework.web.servlet.HandlerInterceptor; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class AuthInterceptor implements HandlerInterceptor { | ||
|
||
private final AuthCheckHandler authCheckHandler; | ||
public static final String MEMBER_ID = "memberId"; | ||
|
||
@Override | ||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { | ||
if(handler instanceof HandlerMethod) { | ||
HandlerMethod handlerMethod = (HandlerMethod) handler; | ||
Optional<Auth> auth = Optional.ofNullable( | ||
handlerMethod.getMethodAnnotation(Auth.class)); | ||
|
||
if(auth.isEmpty()) { | ||
return true; | ||
} | ||
Long memberId = authCheckHandler.validateAuthority(request, List.of(MemberRole.values())); | ||
request.setAttribute(MEMBER_ID, memberId); | ||
return true; | ||
} | ||
return true; | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
src/main/java/com/nice/petudio/global/auth/handler/AuthCheckHandler.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,62 @@ | ||
package com.nice.petudio.global.auth.handler; | ||
|
||
import com.nice.petudio.api.member.service.MemberServiceUtils; | ||
import com.nice.petudio.domain.member.Member; | ||
import com.nice.petudio.domain.member.MemberRole; | ||
import com.nice.petudio.domain.member.repository.MemberRepository; | ||
import com.nice.petudio.global.jwt.JwtTokenService; | ||
import com.nice.petudio.global.exception.ForbiddenException; | ||
import com.nice.petudio.global.exception.UnauthorizedException; | ||
import com.nice.petudio.global.exception.ValidationException; | ||
import com.nice.petudio.global.exception.error.ErrorCode; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.util.StringUtils; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class AuthCheckHandler { | ||
|
||
private final JwtTokenService jwtTokenService; | ||
private final MemberRepository memberRepository; | ||
|
||
public final String AUTH_HEADER = "Authorization"; | ||
public final String TOKEN_PREFIX = "Bearer "; | ||
private Long memberId; | ||
|
||
public Long validateAuthority(HttpServletRequest request, List<MemberRole> requiredRoles) { | ||
String jwtAccessToken = getJwtAccessTokenFromHttpHeader(request); | ||
if (hasAuthority(jwtAccessToken, requiredRoles)) { | ||
return memberId; | ||
} | ||
throw new ForbiddenException(ErrorCode.FORBIDDEN_EXCEPTION, ""); | ||
} | ||
|
||
private String getJwtAccessTokenFromHttpHeader(HttpServletRequest request) { | ||
String bearerToken = request.getHeader(AUTH_HEADER); | ||
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) { | ||
return bearerToken.substring(TOKEN_PREFIX.length()); | ||
} | ||
throw new ValidationException(ErrorCode.INVALID_TOKEN_EXCEPTION, ""); | ||
} | ||
|
||
public boolean hasAuthority(String jwtAccessToken, List<MemberRole> requiredRoles) { | ||
if (jwtTokenService.validateToken(jwtAccessToken)) { | ||
Optional<Long> memberId = jwtTokenService.parseMemberId(jwtAccessToken); | ||
if(memberId.isPresent()) { | ||
Member member = MemberServiceUtils.findMemberById(memberRepository, memberId.get()); | ||
this.memberId = memberId.get(); | ||
return isRoleMatch(member, requiredRoles); | ||
} | ||
} | ||
throw new UnauthorizedException(ErrorCode.UNAUTHORIZED_TOKEN_EXCEPTION, ""); | ||
} | ||
|
||
private static boolean isRoleMatch(Member member, List<MemberRole> requiredRoles) { | ||
return requiredRoles.contains(member.getRole()); | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/nice/petudio/global/auth/resolver/MemberId.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,19 @@ | ||
package com.nice.petudio.global.auth.resolver; | ||
|
||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* JWT를 파싱하여 MemberId를 흭득하도록 유도하는 애노테이션 | ||
* Auth 애노테이션과 함께 사용한다. | ||
* | ||
* ex) | ||
* void methodName(@MemberId final Long memberId) {} | ||
*/ | ||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface MemberId { | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/java/com/nice/petudio/global/auth/resolver/MemberIdResolver.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,39 @@ | ||
package com.nice.petudio.global.auth.resolver; | ||
|
||
import static com.nice.petudio.global.auth.auth.AuthInterceptor.MEMBER_ID; | ||
|
||
import com.nice.petudio.global.auth.auth.Auth; | ||
import com.nice.petudio.global.exception.InternalServerException; | ||
import com.nice.petudio.global.exception.error.ErrorCode; | ||
import java.util.Optional; | ||
import org.springframework.core.MethodParameter; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.bind.support.WebDataBinderFactory; | ||
import org.springframework.web.context.request.NativeWebRequest; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.method.support.ModelAndViewContainer; | ||
|
||
@Component | ||
public class MemberIdResolver implements HandlerMethodArgumentResolver { | ||
|
||
@Override | ||
public boolean supportsParameter(MethodParameter parameter) { | ||
return parameter.hasParameterAnnotation(MemberId.class) && Long.class.equals(parameter.getParameterType()); | ||
} | ||
|
||
@Override | ||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, | ||
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { | ||
Optional<Auth> auth = Optional.ofNullable(parameter.getMethodAnnotation(Auth.class)); | ||
if (auth.isEmpty()) { | ||
throw new InternalServerException(ErrorCode.INTERNAL_SERVER_EXCEPTION, | ||
"@MemberId 애노테이션을 적용한 메서드에 Auth 관련 애노테이션이 존재하지 않습니다."); | ||
} | ||
|
||
Optional<Object> object = Optional.ofNullable(webRequest.getAttribute(MEMBER_ID, 0)); | ||
return object.orElseThrow(() -> | ||
new InternalServerException(ErrorCode.INTERNAL_SERVER_EXCEPTION, | ||
"memberId를 확인할 수 없습니다. Auth 관련 로직을 확인해주세요.")); | ||
|
||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...e/petudio/global/util/redis/RedisKey.java → ...lobal/config/redis/constant/RedisKey.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
6 changes: 3 additions & 3 deletions
6
...udio/global/auth/jwt/JwtTokenService.java → ...e/petudio/global/jwt/JwtTokenService.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
.../nice/petudio/global/util/jwt/JwtKey.java → ...e/petudio/global/jwt/constant/JwtKey.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