Skip to content

Commit

Permalink
Merge pull request #90 from Tea-Bliss/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
mun9659 authored Jun 22, 2024
2 parents 08749ba + 3d8f06d commit 0816c76
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 21 deletions.
22 changes: 15 additions & 7 deletions src/main/java/store/teabliss/common/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
Expand All @@ -26,6 +25,7 @@
import store.teabliss.common.security.oauth2.handler.OAuth2AuthenticationFailureHandler;
import store.teabliss.common.security.oauth2.handler.OAuth2AuthenticationSuccessHandler;
import store.teabliss.common.security.signin.JwtExceptionFilter;
import store.teabliss.common.security.signin.RequestMatcherHolder;
import store.teabliss.common.security.signin.UsernamePasswordAuthenticationFilter;
import store.teabliss.common.security.signin.handler.SignInFailureHandler;
import store.teabliss.common.security.signin.handler.SignInSuccessHandler;
Expand Down Expand Up @@ -53,6 +53,7 @@ public class SecurityConfig {
private final JwtService jwtService;
private final UserDetailsServiceImpl userDetailService;
private final ObjectMapper objectMapper;
private final RequestMatcherHolder requestMatcherHolder;

private final CustomOAuth2UserService customOAuth2UserService;
private final OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;
Expand Down Expand Up @@ -83,13 +84,20 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
HeadersConfigurer.FrameOptionsConfig::disable).disable())
.sessionManagement(c -> c.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests((request) -> {

// (신버전)
request.requestMatchers(requestMatcherHolder.getRequestMatchersByMinRole(null)).permitAll();
// request.requestMatchers(requestMatcherHolder.getRequestMatchersByMinRole(MemberRole.USER)).hasAnyAuthority(MemberRole.USER.getKey());


// (구버전)
// request.requestMatchers(new AntPathRequestMatcher("/api/**")).permitAll();
request.requestMatchers(antMatcher("/api/member/**")).permitAll();
request.requestMatchers(antMatcher("/api/ingredient/**")).permitAll();
request.requestMatchers(antMatcher(HttpMethod.GET, "/api/tea/**")).permitAll();
request.requestMatchers(antMatcher(HttpMethod.GET, "/api/review/**")).permitAll();
// request.requestMatchers(antMatcher("/api/member/**")).permitAll();
// request.requestMatchers(antMatcher("/api/ingredient/**")).permitAll();
// request.requestMatchers(antMatcher(HttpMethod.GET, "/api/tea/**")).permitAll();
// request.requestMatchers(antMatcher(HttpMethod.GET, "/api/review/**")).permitAll();
// request.requestMatchers(new AntPathRequestMatcher("/api/survey/**")).authenticated();
request.requestMatchers(permitUrl).permitAll();
// request.requestMatchers(permitUrl).permitAll();
// request.requestMatchers(antMatcher("/api/admin/**")).hasRole("ADMIN");
request.anyRequest().authenticated();
}
Expand Down Expand Up @@ -166,7 +174,7 @@ public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter

@Bean
public JwtAuthorizationFilter jwtAuthorizationFilter() {
return new JwtAuthorizationFilter(memberMapper, jwtService);
return new JwtAuthorizationFilter(requestMatcherHolder, memberMapper, jwtService);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@
@RequiredArgsConstructor
public class JwtAuthorizationFilter extends OncePerRequestFilter {

private final RequestMatcherHolder requestMatcherHolder;
private final MemberMapper memberMapper;
private final JwtService jwtService;

private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

private static final String NO_CHECK_URL = "/api/member/sign-up";

@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
return requestMatcherHolder.getRequestMatchersByMinRole(null).matches(request);
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (request.getRequestURI().equals(NO_CHECK_URL) ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package store.teabliss.common.security.signin;

import jakarta.annotation.Nullable;
import org.springframework.http.HttpMethod;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Component;
import store.teabliss.member.entity.MemberRole;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class RequestMatcherHolder {

private static final List<RequestInfo> REQUEST_INFO_LIST = List.of(
// sign-up, sign-in
new RequestInfo(HttpMethod.POST, "/api/member/sign-up", null),
new RequestInfo(HttpMethod.POST, "/api/member/sign-in", null),

// Tea
new RequestInfo(HttpMethod.GET, "/api/tea/**", null),
new RequestInfo(HttpMethod.GET, "/api/review/**", null),

// static resources
new RequestInfo(HttpMethod.GET, "/docs/**", null),
new RequestInfo(HttpMethod.GET, "/*.ico", null),
new RequestInfo(HttpMethod.GET, "/resources/**", null),
new RequestInfo(HttpMethod.GET, "/error", null),

// swagger
new RequestInfo(HttpMethod.GET, "/api-docs", null),
new RequestInfo(HttpMethod.GET, "/api-docs/**", null),
new RequestInfo(HttpMethod.GET, "/v3/api-docs/**", null),
new RequestInfo(HttpMethod.GET, "/swagger-ui.html", null),
new RequestInfo(HttpMethod.GET, "/swagger-ui/**", null)
);
private final ConcurrentHashMap<String, RequestMatcher> reqMatcherCacheMap = new ConcurrentHashMap<>();

public RequestMatcher getRequestMatchersByMinRole(@Nullable MemberRole memberRole) {
var key = getKeyByRole(memberRole);
return reqMatcherCacheMap.computeIfAbsent(key, k ->
new OrRequestMatcher(REQUEST_INFO_LIST.stream()
.filter(reqInfo -> Objects.equals(reqInfo.memberRole(), memberRole))
.map(reqInfo -> new AntPathRequestMatcher(reqInfo.pattern(),
reqInfo.method().name()))
.toArray(AntPathRequestMatcher[]::new)));
}

private String getKeyByRole(@Nullable MemberRole memberRole) {
return memberRole == null ? "VISITOR" : memberRole.name();
}

private record RequestInfo(HttpMethod method, String pattern, MemberRole memberRole) {

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import store.teabliss.common.entity.ErrorMessage;
import store.teabliss.common.security.utils.CookieUtils;
import store.teabliss.member.entity.Member;
import store.teabliss.member.mapper.MemberMapper;
Expand Down Expand Up @@ -149,18 +150,15 @@ public boolean isTokenValid(String token) {
.parseClaimsJws(token);

return true;
} catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) {
throw new RuntimeException("잘못된 JWT 서명입니다.");
// throw new JwtErrorException(JwtErrorStatus.MALFORMED_JWT);
} catch (MalformedJwtException e) {
log.info("MalformedJwtException");
throw new JwtException(ErrorMessage.UNSUPPORTED_TOKEN.getMsg());
} catch (ExpiredJwtException e) {
throw new RuntimeException("만료된 JWT 토큰입니다.");
// throw new JwtErrorException(JwtErrorStatus.EXPIRED_JWT);
} catch (UnsupportedJwtException e) {
throw new RuntimeException("지원되지 않는 JWT 토큰입니다.");
// throw new JwtErrorException(JwtErrorStatus.UNSUPPORTED_JWT);
log.info("ExpiredJwtException");
throw new JwtException(ErrorMessage.EXPIRED_TOKEN.getMsg());
} catch (IllegalArgumentException e) {
throw new RuntimeException("JWT 토큰이 잘못되었습니다.");
// throw new JwtErrorException(JwtErrorStatus.ILLEGAL_ARGUMENT);
log.info("IllegalArgumentException");
throw new JwtException(ErrorMessage.UNKNOWN_ERROR.getMsg());
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/store/teabliss/member/dto/MemberDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@JsonInclude(Include.NON_NULL)
public class MemberDto {

private Long memId;
private Long id;

private String email;

Expand All @@ -40,19 +40,21 @@ public class MemberDto {

public static MemberDto of1(Member member) {
return MemberDto.builder()
.id(member.getMemId())
.email(member.getEmail())
.nickname(member.getNickname())
.address(member.getAddress())
.profile(member.getProfile())
.role(member.getRole().getKey().equalsIgnoreCase("USER") ? "일반 회원" : "관리자")
.build();
}

public static MemberDto of2(Member member) {
return MemberDto.builder()
.memId(member.getMemId())
.id(member.getMemId())
.nickname(member.getNickname())
.email(member.getEmail())
.role(member.getRole().getKey().equalsIgnoreCase("USER") ? "일반 회원" : "관리자" )
.role(member.getRole().getKey().equalsIgnoreCase("USER") ? "일반 회원" : "관리자")
.reviewCount(member.getReviewCount())
.purchaseAmount(member.getPurchaseAmount())
.createDt(member.getCreateDt())
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/mapper/MemberMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

<select id="findByMembers" parameterType="Member">
SELECT
m.mem_id as id,
m.mem_id,
m.email,
m.nickname,
m.address,
Expand Down

0 comments on commit 0816c76

Please sign in to comment.