token이 만료되어 Access denied exception이 떳을때
org/springframework/security/access/intercept/AbstractSecurityInterceptor.java:178
attemptAuthorization(object, attributes, authenticated) 를 부를기 전에
SecurityContextHolder.getContext().getAuthentication()를 가져온다.
=> 따라서 filter에서 SecurityContextHolder.getContext().setAuthentication 를 안해주면 access denied 에러가 발생하게 된다.
org/springframework/security/access/intercept/AbstractSecurityInterceptor.java
protected InterceptorStatusToken beforeInvocation(Object object) {
Assert.notNull(object, "Object was null");
if (!getSecureObjectClass().isAssignableFrom(object.getClass())) {
throw new IllegalArgumentException("Security invocation attempted for object " + object.getClass().getName()
+ " but AbstractSecurityInterceptor only configured to support secure objects of type: "
+ getSecureObjectClass());
}
Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource().getAttributes(object);
if (CollectionUtils.isEmpty(attributes)) {
Assert.isTrue(!this.rejectPublicInvocations,
() -> "Secure object invocation " + object
+ " was denied as public invocations are not allowed via this interceptor. "
+ "This indicates a configuration error because the "
+ "rejectPublicInvocations property is set to 'true'");
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Authorized public object %s", object));
}
publishEvent(new PublicInvocationEvent(object));
return null; // no further work post-invocation
}
if (SecurityContextHolder.getContext().getAuthentication() == null) {
credentialsNotFound(this.messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",
"An Authentication object was not found in the SecurityContext"), object, attributes);
}
// Attemp authrization 전에 Authentication 정보를 가져온다.
Authentication authenticated = authenticateIfRequired();
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.format("Authorizing %s with attributes %s", object, attributes));
}
// Attempt authorization
attemptAuthorization(object, attributes, authenticated);
org/springframework/security/access/intercept/AbstractSecurityInterceptor.java => authenticateIfRequired 메소드
/**
* Checks the current authentication token and passes it to the AuthenticationManager
* if {@link org.springframework.security.core.Authentication#isAuthenticated()}
* returns false or the property <tt>alwaysReauthenticate</tt> has been set to true.
* @return an authenticated <tt>Authentication</tt> object.
*/
private Authentication authenticateIfRequired() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.isAuthenticated() && !this.alwaysReauthenticate) {
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.format("Did not re-authenticate %s before authorizing", authentication));
}
return authentication;
}
authentication = this.authenticationManager.authenticate(authentication);
// Don't authenticated.setAuthentication(true) because each provider does that
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Re-authenticated %s before authorizing", authentication));
}
SecurityContextHolder.getContext().setAuthentication(authentication);
return authentication;
}
Authentication Exception 발생시 Security Config에 설정한 Exception Handling에 의해 처리가 된다.
.exceptionHandling().authenticationEntryPoint(new BasicAuthenticationPoint());
commence:31, BasicAuthenticationPoint (com.sdp.common.security)
sendStartAuthentication:213, ExceptionTranslationFilter (org.springframework.security.web.access)
handleAccessDeniedException:192, ExceptionTranslationFilter (org.springframework.security.web.access)
handleSpringSecurityException:173, ExceptionTranslationFilter (org.springframework.security.web.access)
doFilter:142, ExceptionTranslationFilter (org.springframework.security.web.access)
doFilter:115, ExceptionTranslationFilter (org.springframework.security.web.access)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:126, SessionManagementFilter (org.springframework.security.web.session)
doFilter:81, SessionManagementFilter (org.springframework.security.web.session)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:105, AnonymousAuthenticationFilter (org.springframework.security.web.authentication)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:149, SecurityContextHolderAwareRequestFilter (org.springframework.security.web.servletapi)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:63, RequestCacheAwareFilter (org.springframework.security.web.savedrequest)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilterInternal:47, TokenAuthenticationFilter (com.sdp.common.security)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:103, LogoutFilter (org.springframework.security.web.authentication.logout)
doFilter:89, LogoutFilter (org.springframework.security.web.authentication.logout)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doHeadersAfter:90, HeaderWriterFilter (org.springframework.security.web.header)
doFilterInternal:75, HeaderWriterFilter (org.springframework.security.web.header)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilter:110, SecurityContextPersistenceFilter (org.springframework.security.web.context)
doFilter:80, SecurityContextPersistenceFilter (org.springframework.security.web.context)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilterInternal:55, WebAsyncManagerIntegrationFilter (org.springframework.security.web.context.request.async)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
doFilter:336, FilterChainProxy$VirtualFilterChain (org.springframework.security.web)
doFilterInternal:211, FilterChainProxy (org.springframework.security.web)
doFilter:183, FilterChainProxy (org.springframework.security.web)
invokeDelegate:358, DelegatingFilterProxy (org.springframework.web.filter)
doFilter:271, DelegatingFilterProxy (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:100, RequestContextFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:93, FormContentFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:201, CharacterEncodingFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
invoke:197, StandardWrapperValve (org.apache.catalina.core)
invoke:97, StandardContextValve (org.apache.catalina.core)
invoke:540, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:135, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:78, StandardEngineValve (org.apache.catalina.core)
service:357, CoyoteAdapter (org.apache.catalina.connector)
service:382, Http11Processor (org.apache.coyote.http11)
process:65, AbstractProcessorLight (org.apache.coyote)
process:895, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1722, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1191, ThreadPoolExecutor (org.apache.tomcat.util.threads)
run:659, ThreadPoolExecutor$Worker (org.apache.tomcat.util.threads)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:834, Thread (java.lang)
Authentication 에러도 Authorization 에러 부터 시작해서 처리가 됨을 알 수 있다.
Exception의 원천은 AccessDeniedException
cause = {AccessDeniedException@12857} "org.springframework.security.access.AccessDeniedException: Access is denied"
stackTrace = {StackTraceElement[68]@12862}
0 = {StackTraceElement@12864} "org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:73)"
1 = {StackTraceElement@12865} "org.springframework.security.access.intercept.AbstractSecurityInterceptor.attemptAuthorization(AbstractSecurityInterceptor.java:238)"
2 = {StackTraceElement@12866} "org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:208)"
3 = {StackTraceElement@12867} "org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:113)"
4 = {StackTraceElement@12868} "org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)"
5 = {StackTraceElement@12869} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
6 = {StackTraceElement@12870} "org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)"
7 = {StackTraceElement@12871} "org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)"
8 = {StackTraceElement@12872} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
9 = {StackTraceElement@12873} "org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)"
10 = {StackTraceElement@12874} "org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)"
11 = {StackTraceElement@12875} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
12 = {StackTraceElement@12876} "org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)"
13 = {StackTraceElement@12877} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
14 = {StackTraceElement@12878} "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)"
15 = {StackTraceElement@12879} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
16 = {StackTraceElement@12880} "org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)"
17 = {StackTraceElement@12881} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
18 = {StackTraceElement@12882} "com.sdp.common.security.TokenAuthenticationFilter.doFilterInternal(TokenAuthenticationFilter.java:47)"
19 = {StackTraceElement@12883} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
20 = {StackTraceElement@12884} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
21 = {StackTraceElement@12885} "org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)"
22 = {StackTraceElement@12886} "org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)"
23 = {StackTraceElement@12887} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
24 = {StackTraceElement@12888} "org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)"
25 = {StackTraceElement@12889} "org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)"
26 = {StackTraceElement@12890} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
27 = {StackTraceElement@12891} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
28 = {StackTraceElement@12892} "org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)"
29 = {StackTraceElement@12893} "org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)"
30 = {StackTraceElement@12894} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
31 = {StackTraceElement@12895} "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)"
32 = {StackTraceElement@12896} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
33 = {StackTraceElement@12897} "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)"
34 = {StackTraceElement@12898} "org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)"
35 = {StackTraceElement@12899} "org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)"
36 = {StackTraceElement@12900} "org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)"
37 = {StackTraceElement@12901} "org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)"
38 = {StackTraceElement@12902} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
39 = {StackTraceElement@12903} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
40 = {StackTraceElement@12904} "org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)"
41 = {StackTraceElement@12905} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
42 = {StackTraceElement@12906} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
43 = {StackTraceElement@12907} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
44 = {StackTraceElement@12908} "org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)"
45 = {StackTraceElement@12909} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
46 = {StackTraceElement@12910} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
47 = {StackTraceElement@12911} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
48 = {StackTraceElement@12912} "org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)"
49 = {StackTraceElement@12913} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
50 = {StackTraceElement@12914} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
51 = {StackTraceElement@12915} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
52 = {StackTraceElement@12916} "org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)"
53 = {StackTraceElement@12917} "org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)"
54 = {StackTraceElement@12918} "org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)"
55 = {StackTraceElement@12919} "org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)"
56 = {StackTraceElement@12920} "org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)"
57 = {StackTraceElement@12921} "org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)"
58 = {StackTraceElement@12922} "org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)"
59 = {StackTraceElement@12923} "org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)"
60 = {StackTraceElement@12924} "org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)"
61 = {StackTraceElement@12925} "org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)"
62 = {StackTraceElement@12926} "org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)"
63 = {StackTraceElement@12927} "org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)"
64 = {StackTraceElement@12928} "org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)"
65 = {StackTraceElement@12929} "org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)"
66 = {StackTraceElement@12930} "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)"
67 = {StackTraceElement@12931} "java.base/java.lang.Thread.run(Thread.java:834)"
depth = 68
suppressedExceptions = {Collections$EmptyList@8861} size = 0
'Backend Development > Spring boot' 카테고리의 다른 글
[Spring boot] Spring Security 분석 - WebSecurityConfigurerAdapter (0) | 2022.03.14 |
---|---|
[Spring boot] Spring Security 분석 - FilterSecurityInterceptor (Token 인증 기반) (0) | 2022.03.14 |
[Spring boot] Spring Security 분석 - Start 시퀀스 (0) | 2022.03.13 |
[Spring boot] Spring Security 분석 - 메소드 Security (0) | 2022.03.11 |
[Spring boot] refresh token 갱신 시 DB 저장값과 Cookie 값 안맞을 경우 (0) | 2022.03.11 |