Skip to content

Commit a7a0cfb

Browse files
committed
feat: spring security whitelist filtering (#20)
* dev: whitelist url consts * dev: whitelist method and url pair class * dev: security exception remove token cookie & whitelist check * test: mocking servlet req/resp for authFilter * dev: request null check before whitelist pass * dev: remove request null check in filter
1 parent 09e3d39 commit a7a0cfb

File tree

4 files changed

+73
-14
lines changed

4 files changed

+73
-14
lines changed

bm-controller/src/main/java/org/benchmarker/security/JwtAuthFilter.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22

33
import jakarta.servlet.FilterChain;
44
import jakarta.servlet.ServletException;
5+
import jakarta.servlet.http.Cookie;
56
import jakarta.servlet.http.HttpServletRequest;
67
import jakarta.servlet.http.HttpServletResponse;
78
import lombok.extern.slf4j.Slf4j;
9+
import org.benchmarker.security.util.MethodUrlPair;
810
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
911
import org.springframework.security.core.context.SecurityContextHolder;
1012
import org.springframework.security.core.userdetails.UserDetails;
13+
import org.springframework.security.core.userdetails.UsernameNotFoundException;
1114
import org.springframework.web.filter.OncePerRequestFilter;
1215

1316
import java.io.IOException;
1417

1518
import static org.benchmarker.security.constant.TokenConsts.ACCESS_TOKEN_COOKIE_NAME;
19+
import static org.benchmarker.security.constant.URLConsts.WHITE_LIST_URLS;
1620

1721
@Slf4j
1822
public class JwtAuthFilter extends OncePerRequestFilter {
@@ -30,18 +34,34 @@ public JwtAuthFilter(BMUserDetailsService userDetailsService,
3034
@Override
3135
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
3236
FilterChain filterChain) throws ServletException, IOException {
33-
String userId = jwtTokenProvider.validateTokenAndGetUserId(request,
34-
ACCESS_TOKEN_COOKIE_NAME);
35-
if (userId != null) {
36-
log.info("userId : {}", userId);
37-
38-
UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
39-
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
40-
userDetails, null, userDetails.getAuthorities());
41-
SecurityContextHolder.getContext().setAuthentication(auth);
42-
43-
log.info("SecurityContextHolder.getContext().getAuthentication() : {}",
44-
SecurityContextHolder.getContext().getAuthentication());
37+
38+
for (MethodUrlPair methodUrlPair : WHITE_LIST_URLS) {
39+
if (methodUrlPair.getMethod().contains(request.getMethod()) &&
40+
methodUrlPair.getUrl().equals(request.getRequestURI())) {
41+
filterChain.doFilter(request, response);
42+
return;
43+
}
44+
}
45+
46+
try {
47+
String userId = jwtTokenProvider.validateTokenAndGetUserId(request,
48+
ACCESS_TOKEN_COOKIE_NAME);
49+
if (userId != null) {
50+
UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
51+
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
52+
userDetails, null, userDetails.getAuthorities());
53+
SecurityContextHolder.getContext().setAuthentication(auth);
54+
55+
log.info("SecurityContextHolder.getContext().getAuthentication() : {}",
56+
SecurityContextHolder.getContext().getAuthentication());
57+
}
58+
} catch (UsernameNotFoundException ex) {
59+
Cookie cookie = new Cookie(ACCESS_TOKEN_COOKIE_NAME, null);
60+
cookie.setPath("/");
61+
cookie.setMaxAge(0);
62+
response.addCookie(cookie);
63+
response.sendRedirect("/");
64+
return;
4565
}
4666

4767
filterChain.doFilter(request, response);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.benchmarker.security.constant;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
import org.benchmarker.security.util.MethodUrlPair;
6+
7+
public interface URLConsts {
8+
9+
List<MethodUrlPair> WHITE_LIST_URLS = List.of(
10+
new MethodUrlPair(Arrays.asList("POST","GET"), "/login"),
11+
new MethodUrlPair(Arrays.asList("POST"), "/user")
12+
);
13+
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.benchmarker.security.util;
2+
3+
import java.util.List;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
import lombok.ToString;
7+
import org.springframework.http.HttpMethod;
8+
9+
@AllArgsConstructor
10+
@Getter
11+
@ToString
12+
public class MethodUrlPair {
13+
private final List<String> method;
14+
private final String url;
15+
}

bm-controller/src/test/java/org/benchmarker/security/JwtAuthFilterTest.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import org.mockito.InjectMocks;
99
import org.mockito.Mock;
1010
import org.springframework.boot.test.context.SpringBootTest;
11+
import org.springframework.mock.web.MockHttpServletRequest;
12+
import org.springframework.mock.web.MockHttpServletResponse;
1113
import org.springframework.security.authentication.TestingAuthenticationToken;
1214
import org.springframework.security.core.context.SecurityContextHolder;
1315

@@ -40,8 +42,12 @@ public void testDoFilterInternal_ValidToken() throws Exception {
4042
when(userDetails.getAuthorities())
4143
.thenReturn((Collection) authenticationToken.getAuthorities());
4244

45+
MockHttpServletRequest request = new MockHttpServletRequest();
46+
request.setRequestURI("/test");
47+
MockHttpServletResponse response = new MockHttpServletResponse();
48+
4349
// when
44-
jwtAuthFilter.doFilterInternal(null, null, (req, res) -> {
50+
jwtAuthFilter.doFilterInternal(request, response, (req, res) -> {
4551
});
4652

4753
// then
@@ -56,8 +62,12 @@ public void testDoFilterInternal_InvalidToken() throws Exception {
5662
// given
5763
when(jwtTokenProvider.validateTokenAndGetUserId(any(), any())).thenReturn(null);
5864

65+
MockHttpServletRequest request = new MockHttpServletRequest();
66+
request.setRequestURI("/test");
67+
MockHttpServletResponse response = new MockHttpServletResponse();
68+
5969
// when
60-
jwtAuthFilter.doFilterInternal(null, null, (req, res) -> {
70+
jwtAuthFilter.doFilterInternal(request, response, (req, res) -> {
6171
});
6272

6373
// then

0 commit comments

Comments
 (0)