여기서 필터체인이 만들어져서 등록됩니다.
public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
implements SecurityBuilder<Filter>, ApplicationContextAware, ServletContextAware {
...
@Override
protected Filter performBuild() throws Exception {
Assert.state(!this.securityFilterChainBuilders.isEmpty(),
() -> "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. "
+ "Typically this is done by exposing a SecurityFilterChain bean "
+ "or by adding a @Configuration that extends WebSecurityConfigurerAdapter. "
+ "More advanced users can invoke " + WebSecurity.class.getSimpleName()
+ ".addSecurityFilterChainBuilder directly");
int chainSize = this.ignoredRequests.size() + this.securityFilterChainBuilders.size();
List<SecurityFilterChain> securityFilterChains = new ArrayList<>(chainSize);
List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> requestMatcherPrivilegeEvaluatorsEntries = new ArrayList<>();
// ✨ 1-1. 여기서 WebSecurity - ignoring이 등록된 것이 Start!
for (RequestMatcher ignoredRequest : this.ignoredRequests) {
WebSecurity.this.logger.warn("You are asking Spring Security to ignore " + ignoredRequest
+ ". This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.");
/** ✨ 1-2. DefaultSecurityFilterChain 등록하는데...?
생성자에서 2번째 인자값으로 필터를 넘겨주질 않으니 필터 없이 등록이 된다.
public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {...}
*/
SecurityFilterChain securityFilterChain = new DefaultSecurityFilterChain(ignoredRequest);
securityFilterChains.add(securityFilterChain);
requestMatcherPrivilegeEvaluatorsEntries
.add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
}
// ✨ 그 외의 경우에는 여기서 필터 체인을 만들어서 등록
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : this.securityFilterChainBuilders) {
SecurityFilterChain securityFilterChain = securityFilterChainBuilder.build();
securityFilterChains.add(securityFilterChain);
requestMatcherPrivilegeEvaluatorsEntries
.add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
}
if (this.privilegeEvaluator == null) {
this.privilegeEvaluator = new RequestMatcherDelegatingWebInvocationPrivilegeEvaluator(
requestMatcherPrivilegeEvaluatorsEntries);
}
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
if (this.httpFirewall != null) {
filterChainProxy.setFirewall(this.httpFirewall);
}
if (this.requestRejectedHandler != null) {
filterChainProxy.setRequestRejectedHandler(this.requestRejectedHandler);
}
filterChainProxy.afterPropertiesSet();
Filter result = filterChainProxy;
if (this.debugEnabled) {
this.logger.warn("\n\n" + "********************************************************************\n"
+ "********** Security debugging is enabled. *************\n"
+ "********** This may include sensitive information. *************\n"
+ "********** Do not use in a production system! *************\n"
+ "********************************************************************\n\n");
result = new DebugFilter(filterChainProxy);
}
this.postBuildAction.run();
return result;
}
}
📌 디버깅을 해보면 결과적으로 ignoring 용 NoFilter Chain과 나머지 가 생성되는걸 볼수 있습니다.
(/api/v1/users/join 을 WebSecurity-ignoring으로 등록했습니다.)
Login URL을 HttpSecurity - ignoring으로 설정 하고,
요청을 했을 때!
✨ 결과적으로 FilterChain의 갯수가 꽉찼음을 확인할 수 있었습니다.
URL 하나를 WebSecurity - ignoring으로 설정 하고,
요청을 했을 때!
✨ 결과적으로 FilterChain의 갯수가 0개임을 확인할 수 있었습니다.
HttpSecurity, WebSecurity 둘다 동일한 URL을 등록하는 경우, WebSecurity가 우선적으로 적용됩니다.
WebSecurity에서 필터체인을 등록할 때, ignoring을 먼저 등록을 했으니.. 순서가 첫번째!
그래서 먼저 매칭이 되어 우선 적용이 되는 것이외다!