Spring Security _ Temp - taeyun-ham/andalos GitHub Wiki
- Spring Security : 6.2.3
// HeaderWriterFilter ๋ฅผ securityFilterChain์ ์ถ๊ฐํฉ๋๋ค.
http.headers((headers) -> headers. ~~);
// CorsFilter๋ฅผ ์ถ๊ฐํฉ๋๋ค.
http.cors(withDefaults());
// SessionManagementFilter, ConcurrentSessionFilter, DisableEncodeUrlFilter, ForceEagerSessionCreationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
http.sessionManagement((sessionManagement) -> sessionManagement.~~);
// portMapper ์ port ๋ฅผ ๋ฑ๋กํฉ๋๋ค. requiresChannel ์ค์ ์ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
// 9090 port ๋ฅผ 9443 ์ผ๋ก redirect
http.portMapper((portMapper) -> portMapper
.http(9090).mapsTo(9443)
.http(80).mapsTo(443));
// X509AuthenticationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// X509 ์ธ์ฆ์์์ ์ฌ์ฉ์ ์ด๋ฆ์ ์ถ์ถํ๋ ค๊ณ ์๋ํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ด ์๋ํ๋ ค๋ฉด ์๋ธ๋ฆฟ ์ปจํ
์ด๋๊ฐ ํด๋ผ์ด์ธํธ ์ธ์ฆ์๋ฅผ ์์ฒญํ๋๋ก ๊ตฌ์ฑ๋์ด์ผ ํฉ๋๋ค.
http.x509(withDefaults());
// RememberMeAuthenticationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// session ์ด ๋ง๋ฃ๋๊ฑฐ๋ ์ฟ ํค๊ฐ ์๋๋ผ๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ๊ธฐ์ตํ๋ ๊ธฐ๋ฅ์
๋๋ค. (์๋๋ก๊ทธ์ธ)
http.rememberMe(withDefaults());
// AuthorizationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ์ธ์ฆ๋ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ ์ ์๋ url ๊ณผ ๊ถํ์ ์ฒดํฌํฉ๋๋ค.
http.authorizeHttpRequests((authorizeHttpRequests) -> ~~);
// RequestCacheAwareFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ์ ์ฅ๋ ์์ฒญ์ด ์บ์๋์ด ์๊ณ ํ์ฌ ์์ฒญ๊ณผ ์ผ์นํ๋ ๊ฒฝ์ฐ ์ ์ฅ๋ ์์ฒญ์ ์ฌ๊ตฌ์ฑํ๋ ์ญํ ์ ๋ด๋นํฉ๋๋ค.
http.requestCache((requestCache) -> ~~);
// ExceptionTranslationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ํํฐ ์ฒด์ธ ๋ด์์ ๋ฐ์ํ๋ ๋ชจ๋ AccessDeniedException ๋ฐ AuthenticationException์ ์ฒ๋ฆฌํฉ๋๋ค.
http.exceptionHandling((exceptionHandling) ->~~)
// SecurityContextHolderFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// SecurityContextRepository๋ฅผ ์ฌ์ฉํ์ฌ SecurityContext๋ฅผ ์ป๊ณ ์ด๋ฅผ SecurityContextHolder์ ์ค์ ํ๋ jakarta.servlet.Filter์
๋๋ค
http.securityContext((securityContext) -> ~~)
// SecurityContextHolderAwareRequestFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// exceptionHandling, logout ์ค์ ์ ๋ณด๋ฅผ ์ฐธ์กฐํ์ฌ SecurityContextHolderAwareRequestFilter ์ ์
ํ
ํฉ๋๋ค.
http.servletApi((servletApi) -> ~~);
// CsrfFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ๋๊ธฐํ ํ ํฐ ํจํด์ ์ฌ์ฉํ์ฌ CSRF ๋ณดํธ๋ฅผ ์ ์ฉํฉ๋๋ค.
// logout, sessionManagement ์ค์ ์ ๋ณด๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
http.csrf((csrf) -> ~~);
// LogoutFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ๋ก๊ทธ์์ ํ ์ฌ์ฉ๋ ์์ฑ์์ ๋ฐ๋ผ ๊ตฌ์ฑ๋ LogoutSuccessHandler ๋๋ logoutSuccessUrl์ ์ํด ๊ฒฐ์ ๋ URL๋ก ๋ฆฌ๋ค์ด๋ ํธ๊ฐ ์ํ๋ฉ๋๋ค.
http.logout((logout) -> ~~);
// AnonymousAuthenticationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// SecurityContextHolder์ Authentication ๊ฐ์ฒด๊ฐ ์๋์ง ๊ฐ์งํ๊ณ ํ์ํ ๊ฒฝ์ฐ ํ๋๋ฅผ ์ฑ์๋๋ค.
http.anonymous((anonymous) -> ~~);
// UsernamePasswordAuthenticationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// login url ๋ฅผ ์ค์ ํ์ง ์์๊ฒฝ์ฐ DefaultLoginPageGeneratingFilter, DefaultLogoutPageGeneratingFilter ๊ฐ ์ถ๊ฐ๋ฉ๋๋ค.
http.formLogin((formLogin) -> ~~);
// Saml2WebSsoAuthenticationRequestFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
http.saml2Login(withDefaults());
// logout ์ค์ ์ ์ฐธ์กฐํ๊ณ CsrfFilter ์์ Saml2LogoutRequestFilter, Saml2LogoutResponseFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
http.saml2Logout(withDefaults());
// BasicAuthenticationFilter ์์ Saml2MetadataFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
http.saml2Metadata(Customizer. withDefaults());
// OAuth2AuthorizationRequestRedirectFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ์ด ํํฐ๋ ์ต์ข
์ฌ์ฉ์์ ์ฌ์ฉ์ ์์ด์ ํธ๋ฅผ ์ธ์ฆ ์๋ฒ์ ์ธ์ฆ ์๋ํฌ์ธํธ๋ก ๋ฆฌ๋ค์ด๋ ํธํจ์ผ๋ก์จ ๊ถํ ๋ถ์ฌ ์ฝ๋ ๋ถ์ฌ ํ๋ฆ์ ์์ํฉ๋๋ค.
http.oauth2Login(withDefaults());
// OAuth2AuthorizationRequestRedirectFilter, OAuth2AuthorizationCodeGrantFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// OAuth 2.0 ๊ถํ ๋ถ์ฌ ์ฝ๋ ๋ถ์ฌ๋ฅผ ์ํ ํํฐ๋ก, OAuth 2.0 ์ธ์ฆ ์๋ต ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํฉ๋๋ค.
http.oauth2Client(withDefaults());
// BearerTokenAuthenticationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// OAuth 2.0 ๋ฒ ์ด๋ฌ ํ ํฐ์ ํฌํจํ๋ ์์ฒญ์ ์ธ์ฆํฉ๋๋ค. ์ด ํํฐ๋ OAuth 2.0 ๋ฒ ์ด๋ฌ ํ ํฐ์ ์ธ์ฆํ ์ ์๋ AuthenticationManager์ ์ฐ๊ฒฐ๋์ด์ผ ํฉ๋๋ค.
http.oauth2ResourceServer((oauth2ResourceServer) -> ~~);
// ChannelProcessingFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ์์ฒญ์ด ํ์ํ ์ฑ๋์ ํตํด ์ ๋ฌ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ค์ ์ฑ๋ ๋ณด์ ๊ฒฐ์ ๊ณผ ํ์ํ ์กฐ์น๋ฅผ ๊ตฌ์ฑ๋ ChannelDecisionManager์ ์์ํฉ๋๋ค.
http.requiresChannel((requiresChannel) -> ~~)
// BasicAuthenticationFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// HTTP ์์ฒญ์ BASIC ์ธ์ฆ ํค๋๋ฅผ ์ฒ๋ฆฌํ์ฌ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ SecurityContextHolder์ ๋ฃ์ต๋๋ค.
http.httpBasic(withDefaults());
// RequestMatcherRedirectFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// RequestMatcher์ ์ผ์นํ๋ ์์ฒญ์ ์ง์ ๋ URL๋ก ๋ฆฌ๋ค์ด๋ ํธํ๋ ํํฐ์
๋๋ค.
http.passwordManagement(passwordManagement -> ~~);
// ์ง์ ๋ Url ์์๋ง security ๊ฐ ์ ์ฉ๋๋๋ก ํฉ๋๋ค.
http.securityMatchers((matchers) -> matchers.requestMatchers("/api/**"));
// J2eePreAuthenticatedProcessingFilter ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
http.jee((jee) -> ~~)- DisableEncodeUrlFilter
- WebAsyncManagerIntegrationFilter
- SecurityContextHolderFilter
- HeaderWriterFilter
- CsrfFilter
- LogoutFilter
- UsernamePasswordAuthenticationFilter
- DefaultLoginPageGeneratingFilter
- DefaultLogoutPageGeneratingFilter
- BasicAuthenticationFilter
- RequestCacheAwareFilter
- SecurityContextHolderAwareRequestFilter
- AnonymousAuthenticationFilter
- ExceptionTranslationFilter
- AuthorizationFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
BasicAuthenticationFilter
์ 4๊ฐ์ ํํฐ๋ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฐ์ http ์ธ์ฆ์ ์ฌ์ฉํ ๋ ํธ์ถ๋๋ค.
Form ๊ธฐ๋ฐ login ์ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ 4๊ฐ์ ํํฐ๋ ์ ์ธ๋๋ค.
- HttpServletResponse๋ฅผ ์ฌ์ฉํ์ฌ URL์ ์ธ์ฝ๋ฉํ๋ ๊ฒ์ ๋นํ์ฑํํ์ฌ, ์ธ์ ID๊ฐ HTTP ์ ๊ทผ ๋ก๊ทธ์ ๊ฐ์ ๊ฒ๋ค์์ ์ ์ถ๋ ์ ์๊ธฐ ๋๋ฌธ์, URL์ ์ธ์ ID๋ฅผ ํฌํจํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
/**
* Disables encoding URLs using the {@link HttpServletResponse} to prevent including the
* session id in URLs which is not considered URL because the session id can be leaked in
* things like HTTP access logs.
*
* @author Rob Winch
* @since 5.7
*/
public class DisableEncodeUrlFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(request, new DisableEncodeUrlResponseWrapper(response));
}
/**
* Disables URL rewriting for the {@link HttpServletResponse} to prevent including the
* session id in URLs which is not considered URL because the session id can be leaked
* in things like HTTP access logs.
*
* @author Rob Winch
* @since 5.7
*/
private static final class DisableEncodeUrlResponseWrapper extends HttpServletResponseWrapper {
/**
* Constructs a response adaptor wrapping the given response.
* @param response the {@link HttpServletResponse} to be wrapped.
* @throws IllegalArgumentException if the response is null
*/
private DisableEncodeUrlResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public String encodeRedirectURL(String url) {
return url;
}
@Override
public String encodeURL(String url) {
return url;
}
}
}filterChain.doFilter(request, new DisableEncodeUrlResponseWrapper(response));
- ๋ค์ ํํฐ์ response ๋ฅผ DisableEncodeUrlResponseWrapper ๋ก ๊ต์ฒดํด์ ์ ๋ฌํ๋ค.
- DisableEncodeUrlResponseWrapper ๋ HttpServletResponseWrapper ์ encodeURL, encodeRedirectURL ๋ฉ์๋๋ง ์ฌ์ ์ ํ์๋ค.
- ์ ๋ฌ ๋ฐ์ url ์ ๊ทธ๋๋ก ๋ฆฌํดํ๋ค.
- ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ org.apache.catalina.connector.Response.class ์ encodeURL ์ ์ํด session id ๊ฐ ๋ ธ์ถ๋๋ค.
/**
* Encode the session identifier associated with this response into the specified URL, if necessary.
*
* @param url URL to be encoded
*
* @return <code>true</code> if the URL was encoded
*/
@Override
public String encodeURL(String url) {
String absolute;
try {
absolute = toAbsolute(url);
} catch (IllegalArgumentException iae) {
// Relative URL
return url;
}
if (isEncodeable(absolute)) {
// W3c spec clearly said
if (url.equalsIgnoreCase("")) {
url = absolute;
} else if (url.equals(absolute) && !hasPath(url)) {
url += '/';
}
return toEncoded(url, request.getSessionInternal().getIdInternal()); // <=== ์ฌ๊ธฐ์ session id ๊ฐ url ์ query string ์ผ๋ก ์ถ๊ฐ๋๋ค.
} else {
return url;
}
}- ์ฆ
DisableEncodeUrlFilter๋ ์ธ์ ์ ์ฌ์ฉํ ๋๋ง ๊ด๋ จ์ด ์๋ค. - Security config ์ค์ ์์
sessionManagement๋ฅผ disable ์ฒ๋ฆฌํ๋ฉด ํด๋น ํํฐ๊ฐ ์๋๋์ง ์๋๋ค.
...
http.sessionManagement(AbstractHttpConfigurer::disable)
...- SecurityContextCallableProcessingInterceptor๋ฅผ ์ฌ์ฉํ์ฌ SecurityContext์ Spring Web์ WebAsyncManager ์ฌ์ด์ ํตํฉ์ ์ ๊ณตํฉ๋๋ค. beforeConcurrentHandling(org.springframework.web.context.request.NativeWebRequest, Callable)์ ์ฌ์ฉํ์ฌ Callable์์ SecurityContext๋ฅผ ์ฑ์๋๋ค.
- ์ฆ, ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ํ์๋๋ Thread ์์SecurityContext ์ ์ ๊ทผํ ์ ์๋๋ก ํตํฉํฉ๋๋ค.
public final class WebAsyncManagerIntegrationFilter extends OncePerRequestFilter {
private static final Object CALLABLE_INTERCEPTOR_KEY = new Object();
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
SecurityContextCallableProcessingInterceptor securityProcessingInterceptor = (SecurityContextCallableProcessingInterceptor) asyncManager
.getCallableInterceptor(CALLABLE_INTERCEPTOR_KEY);
if (securityProcessingInterceptor == null) {
SecurityContextCallableProcessingInterceptor interceptor = new SecurityContextCallableProcessingInterceptor();
interceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
asyncManager.registerCallableInterceptor(CALLABLE_INTERCEPTOR_KEY, interceptor);
}
filterChain.doFilter(request, response);
}
/**
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
*
* @since 5.8
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
this.securityContextHolderStrategy = securityContextHolderStrategy;
}
}WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
- WebAsyncManager ๋ฅผ ๋ฐ์์ SecurityContextHolderStrategy ๊ฐ ์์ ๊ฒฝ์ฐ ์ฃผ์ ์ํต๋๋ค.
- WebAsyncManager ๋ ๋น๋๊ธฐ ์์ฒญ ์ฒ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ์ค์ฌ ํด๋์ค ์ ๋๋ค.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.addFilterBefore(new CustomJwtAuthenticationFilter(customJwtProvider, SECRET_KEY),
UsernamePasswordAuthenticationFilter.class)
.authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers(
AntPathRequestMatcher.antMatcher("/api/**")
).authenticated() // api ๊ฐ ํฌํจ๋ url ์ ์ธ์ฆ๋ ์ฌ์ฉ์๋ง.
.requestMatchers(
AntPathRequestMatcher.antMatcher("/api/service/**")
).hasAuthority("ROLE_MEMBER") // /api/service/** ๋ ํ์๋ง.
.requestMatchers(
AntPathRequestMatcher.antMatcher("/api/admin/**")
).hasAuthority("ROLE_ADMIN") // /api/admin/** ๋ ์ด๋๋ฏผ๋ง.
.requestMatchers(
AntPathRequestMatcher.antMatcher("/**")
).permitAll()
);
return http.build();
}- ์ฌ๊ธฐ์๋ Rest ๊ธฐ๋ฐ์ token ์ธ์ฆ๋ฐฉ์์ผ๋ก ํ ๊ฒ์ด๊ธฐ์
.csrf(AbstractHttpConfigurer::disable)๋ disable ์ฒ๋ฆฌํ๋ค. - disable ์ ๋ช ์ํ์ง ์์ ๊ฒฝ์ฐ api ํธ์ถ์ csrf token ์ด ์๊ธฐ์ 403 ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
- token ์ธ์ฆ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ CustomJwtAuthenticationFilter ๋ฅผ ๋ณ๋๋ก ๋ง๋ค์ด UsernamePasswordAuthenticationFilter ์ด์ ์ ์ถ๊ฐํ๋ค. (
.addFilterBefore(new CustomJwtAuthenticationFilter(customJwtProvider, SECRET_KEY), UsernamePasswordAuthenticationFilter.class)) -
.formLogin์ ์ค์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ UsernamePasswordAuthenticationFilter ๋ ์๋๋์ง ์์ผ๋ CustomJwtAuthenticationFilter ๊ฐ ์์น ํด์ผ ํ ๊ณณ์ UsernamePasswordAuthenticationFilter ์ด์ ์ ์์ด์ผ ํ๋ค. - URL ์ ํฌ๊ฒ 3๊ฐ์ง๋ก ๋ถ๋ฆฌํ๋ค.
- ์ฒซ๋ฒ์งธ, /api/** ์ ํด๋นํ๋ url ์ ์ธ์ฆ์ฒ๋ฆฌ๊ฐ ๋์ด์ผ ํ๋ค.
- ๋๋ฒ์งธ, /api/service/** ์ ํด๋นํ๋ url ์ ํ์๊ถํ์ด ์์ด์ผ ํ๋ค.
- ์ธ๋ฒ์งธ, /api/admin/** ์ ํด๋นํ๋ url ์ ์ด๋๋ฏผ๊ถํ์ด ์์ด์ผ ํ๋ค.
- ์ฌ๊ธฐ์์ ๊ถํ์ ํํ๋ค ๋งํ๋ ๋ฉ๋ด๋ณ ๊ถํ, ์ ์ ๋ณ ๊ถํ, ๋ถ์๋ณ ๊ถํ ๋ณด๋ค๋ ์กฐ๊ธ ๋ ๋์ ๋ฒ์์ ์๋น์ค๋ณ ๊ถํ์ผ๋ก ํด์ํ๋ ๊ฒ์ด ์ณ๋ค.
- Actor ๊ฐ ์ด๋๋ฏผ ์ฌ์ฉ์์ธ์ง, BtoC ์ฌ์ฉ์์ธ์ง, BtoB ์ฌ์ฉ์์ธ์ง ๊ตฌ๋ณํ์ฌ ์๋น์ค๋ณ๋ก ๊ถํ ์ฒดํฌํ ๋ ์ฌ์ฉํด์ผ ํ์ฉ ๋ฒ์๊ฐ ๋์ด์ง๋ค.
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
try {
String token = CustomJwtProvider.resolveToken(request);
CustomJwtProvider.validateToken(token, secretKey);
Authentication auth = customJwtProvider.getAuthentication(token, secretKey);
SecurityContextHolder.getContext().setAuthentication(auth);
} catch (AuthorizationNotFoundException ae) {
// skip
} catch (ExpiredJwtException ee) {
log.warn(ee.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "The token has expired.");
return; // ๋ค์ ์งํ์ด ๋์ง ์์์ผ 401 ๋ก ์๋ต๋จ.
} catch (Exception e) {
log.warn(e.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "The token is invalid.");
return; // ๋ค์ ์งํ์ด ๋์ง ์์์ผ 401 ๋ก ์๋ต๋จ.
}
filterChain.doFilter(request, response);
}-
CustomJwtProvider.validateToken(token, secretKey);: CustomJwtAuthenticationFilter ์์ฑ์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ CustomJwtProvider ์ secretKey ๋ก token ์ ๊ฒ์ฆํ๋ค. -
Authentication auth = customJwtProvider.getAuthentication(token, secretKey);: CustomJwtProvider ์์ ์ธ์ฆ์ ๋ณด๋ฅผ ํ๋ํ๊ณ -
SecurityContextHolder.getContext().setAuthentication(auth);: SecurityContextHolder ์ ์ ์ฅํ๋ค.
...
// header.Authorization ์์ bearer token ์ทจ๋
public static String resolveToken(HttpServletRequest request) {
String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
if (authorization == null)
throw new AuthorizationNotFoundException("The request header does not contain Authorization.");
return authorization.split(" ")[1].trim();
}
public static boolean validateToken(String token, String secretKey) {
secretKey = getBase64EncodeSecretKey(secretKey);
Jws<Claims> claims = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
return claims.getBody().getExpiration().after(new Date());
}
public Authentication getAuthentication(String token, String secretKey) {
// todo ์ฐจํ redis ์์ ์กฐํํ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝ.
UserDetails userDetails = userServiceImpl.loadUserByUsername(getSubject(token, secretKey));
return new UsernamePasswordAuthenticationToken(userDetails, token, userDetails.getAuthorities());
}
...