Skip to content

Commit

Permalink
Merge pull request #65 from YAPP-Github/feature/PC-625-security-filte…
Browse files Browse the repository at this point in the history
…r-exception-handling

[PC-625] 시큐리티 필터 예외 처리
  • Loading branch information
devchlee12 authored Feb 17, 2025
2 parents 959d2ad + fe52345 commit fea411e
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 201 deletions.
80 changes: 41 additions & 39 deletions api/src/main/java/org/yapp/global/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
Expand All @@ -20,51 +21,52 @@

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {

private final JwtFilter jwtFilter;
private final JwtFilter jwtFilter;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.csrf(AbstractHttpConfigurer::disable)
.cors(corsConfigurer -> corsConfigurer.configurationSource(corsConfigurationSource()))
.httpBasic(AbstractHttpConfigurer::disable)
.sessionManagement(
configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(registry -> registry
.requestMatchers(getMatcherForUserAndAdmin())
.hasAnyRole("USER", "ADMIN")
.requestMatchers(getMatcherForAnyone())
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.csrf(AbstractHttpConfigurer::disable)
.cors(corsConfigurer -> corsConfigurer.configurationSource(corsConfigurationSource()))
.httpBasic(AbstractHttpConfigurer::disable)
.sessionManagement(
configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(registry -> registry
.requestMatchers(getMatcherForUserAndAdmin())
.hasAnyRole("USER", "ADMIN")
.requestMatchers(getMatcherForAnyone())
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}

private CorsConfigurationSource corsConfigurationSource() {
return request -> {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedHeaders(Collections.singletonList("*"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedOriginPatterns(Collections.singletonList("*"));
return config;
};
}
private CorsConfigurationSource corsConfigurationSource() {
return request -> {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedHeaders(Collections.singletonList("*"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedOriginPatterns(Collections.singletonList("*"));
return config;
};
}

private RequestMatcher getMatcherForAnyone() {
return RequestMatchers.anyOf(antMatcher("/api/login/**"), antMatcher("/api/**"),
antMatcher("/swagger-ui/**"),
antMatcher("/v3/api-docs/**"), antMatcher("/swagger-ui.html"));
}
private RequestMatcher getMatcherForAnyone() {
return RequestMatchers.anyOf(antMatcher("/api/login/**"), antMatcher("/api/**"),
antMatcher("/swagger-ui/**"),
antMatcher("/v3/api-docs/**"), antMatcher("/swagger-ui.html"));
}

private RequestMatcher getMatcherForRegister() {
return RequestMatchers.anyOf(antMatcher("/api/profiles/init"));
}
private RequestMatcher getMatcherForRegister() {
return RequestMatchers.anyOf(antMatcher("/api/profiles/init"));
}

private RequestMatcher getMatcherForUserAndAdmin() {
return RequestMatchers.anyOf(antMatcher("/user") //TODO: 임시이며 추후 url에 따라 수정해야.
);
}
private RequestMatcher getMatcherForUserAndAdmin() {
return RequestMatchers.anyOf(antMatcher("/user") //TODO: 임시이며 추후 url에 따라 수정해야.
);
}
}
68 changes: 34 additions & 34 deletions core/auth/src/main/java/org/yapp/core/auth/jwt/JwtFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,49 @@
@Component
public class JwtFilter extends OncePerRequestFilter {

private final JwtUtil jwtUtil;
private final JwtUtil jwtUtil;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {

String accessToken = request.getHeader("Authorization");
if (accessToken == null || !accessToken.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
accessToken = accessToken.substring(7);
String accessToken = request.getHeader("Authorization");
if (accessToken == null || !accessToken.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
accessToken = accessToken.substring(7);

try {
jwtUtil.isExpired(accessToken);
} catch (ExpiredJwtException e) {
try {
jwtUtil.isExpired(accessToken);
} catch (ExpiredJwtException e) {

PrintWriter writer = response.getWriter();
writer.print("access token expired");
PrintWriter writer = response.getWriter();
writer.print("액세스 토큰이 만료되었습니다.");

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}

String category = jwtUtil.getCategory(accessToken);
if (!category.equals("access_token")) {
PrintWriter writer = response.getWriter();
writer.print("invalid access token");
String category = jwtUtil.getCategory(accessToken);
if (!category.equals("access_token")) {
PrintWriter writer = response.getWriter();
writer.print("토큰의 카테고리가 액세스 토큰이 아닙니다.");

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}

Long userId = jwtUtil.getUserId(accessToken);
String role = jwtUtil.getRole(accessToken);
Long userId = jwtUtil.getUserId(accessToken);
String role = jwtUtil.getRole(accessToken);

Authentication authToken =
new UsernamePasswordAuthenticationToken(userId, null, Collections.singleton(
(GrantedAuthority) () -> role));
Authentication authToken =
new UsernamePasswordAuthenticationToken(userId, null, Collections.singleton(
(GrantedAuthority) () -> role));

SecurityContextHolder.getContext().setAuthentication(authToken);
SecurityContextHolder.getContext().setAuthentication(authToken);

filterChain.doFilter(request, response);
}
filterChain.doFilter(request, response);
}
}
123 changes: 60 additions & 63 deletions core/auth/src/main/java/org/yapp/core/auth/jwt/JwtUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,79 +11,76 @@
@Component
public class JwtUtil {

private final SecretKey secretKey;
private final SecretKey secretKey;

public JwtUtil(@Value("${spring.jwt.secret}") String secret) {
secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8),
Jwts.SIG.HS256.key().build().getAlgorithm());
}
public JwtUtil(@Value("${spring.jwt.secret}") String secret) {
secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8),
Jwts.SIG.HS256.key().build().getAlgorithm());
}

public String getOauthId(String token) {
String oauthId;
try {
oauthId = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().get("oauthId", String.class);
} catch (Exception e) {
throw new RuntimeException();
}
return oauthId;
public String getOauthId(String token) {
String oauthId;
try {
oauthId = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().get("oauthId", String.class);
} catch (Exception e) {
throw new RuntimeException();
}
return oauthId;
}

public String getRole(String token) {
String role;
try {
role = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload()
.get("role", String.class);
} catch (Exception e) {
throw new RuntimeException();
}
return role;
public String getRole(String token) {
String role;
try {
role = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload()
.get("role", String.class);
} catch (Exception e) {
throw new RuntimeException();
}
return role;
}

public Boolean isExpired(String token) {
boolean before;
try {
before = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().getExpiration().before(new Date());
} catch (Exception e) {
throw new RuntimeException();
}
return before;
}
public Boolean isExpired(String token) {
boolean before;

public String createJwt(String category, Long userId, String oauthId, String role,
Long expiredMs) {
return Jwts.builder()
.claim("category", category)
.claim("userId", userId)
.claim("oauthId", oauthId)
.claim("role", role)
.issuedAt(new Date(System.currentTimeMillis()))
.expiration(new Date(System.currentTimeMillis() + expiredMs))
.signWith(secretKey)
.compact();
}
before = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().getExpiration().before(new Date());
return before;
}

public String createJwt(String category, Long userId, String oauthId, String role,
Long expiredMs) {
return Jwts.builder()
.claim("category", category)
.claim("userId", userId)
.claim("oauthId", oauthId)
.claim("role", role)
.issuedAt(new Date(System.currentTimeMillis()))
.expiration(new Date(System.currentTimeMillis() + expiredMs))
.signWith(secretKey)
.compact();
}

public Long getUserId(String token) {
Long userId;
try {
userId = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().get("userId", Long.class);
} catch (Exception e) {
throw new RuntimeException();
}
return userId;
public Long getUserId(String token) {
Long userId;
try {
userId = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().get("userId", Long.class);
} catch (Exception e) {
throw new RuntimeException();
}
return userId;
}

public String getCategory(String token) {
String category;
try {
category = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().get("category", String.class);
} catch (Exception e) {
throw new RuntimeException();
}
return category;
public String getCategory(String token) {
String category;
try {
category = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token)
.getPayload().get("category", String.class);
} catch (Exception e) {
throw new RuntimeException();
}
return category;
}
}

Loading

0 comments on commit fea411e

Please sign in to comment.