Spring Security 상용 필터 인 스 턴 스 분석
1 . org.springframework.security.web.context.SecurityContextPersistenceFilter
가장 중요 한 필 터 는 역할 이 중요 하 므 로 더 이상 말 할 필요 가 없다.
이 필 터 는 Security Context 를 Spring 비동기 실행 체제 의 WebAsyncManager 로 통합 하 는 데 사 용 됩 니 다.
3 . org.springframework.security.web.header.HeaderWriterFilter
요청 한 Header 에 해당 하 는 정 보 를 추가 하면 http 탭 내부 에서 security:headers 를 사용 하여 제어 할 수 있 습 니 다.
4 . org.springframework.security.web.csrf.CsrfFilter
csrf 는 크로스 도 메 인 위조 요청 이 라 고도 부 릅 니 다.SpringSecurity 는 모든 post 에 시스템 생 성 csrf 의 token 정 보 를 포함 하 는 지 검증 을 요청 합 니 다.
포함 되 지 않 으 면 잘못 을 보고 합 니 다.csrf 공격 을 방지 하 는 효과 가 있 습 니 다.
5. org.springframework.security.web.authentication.logout.LogoutFilter
URL 이/logout 인 요청 과 일치 하여 사용자 가 종료 하고 인증 정 보 를 삭제 합 니 다.
6 . org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
인증 작업 은 모두 이 필터 에 의 해 이 루어 집 니 다.기본 URL 은/login 이 고 POST 요청 이 어야 합 니 다.
7 . org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter
설정 파일 에 인증 페이지 를 지정 하지 않 으 면 이 필터 로 기본 인증 페이지 를 만 듭 니 다.
8 . org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter
이 필 터 는 로그 인 페이지 에서 기본 종료 페이지 를 만 들 수 있 습 니 다.
9 . org.springframework.security.web.authentication.www.BasicAuthenticationFilter
이 필 터 는 HTTP 요청 의 머리 이름 이 Authentication 이 고 Basic 으로 시작 하 는 머리 정 보 를 자동 으로 해석 합 니 다.
10 . org.springframework.security.web.savedrequest.RequestCacheAwareFilter
HttpSession RequestCache 내 부 를 통 해 HttpServletRequest 캐 시 에 사용 할 RequestCache 를 유 지 했 습 니 다.
11 . org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
ServletRequest 에 대한 포장 을 진행 하여 request 가 더욱 풍부 한 API 를 가지 도록 합 니 다.
12 . org.springframework.security.web.authentication.AnonymousAuthenticationFilter
Security ContextHolder 에서 인증 정보 가 비어 있 으 면 익명 의 사용 자 를 만들어 Security ContextHolder 에 저장 합 니 다.
spring security 는 로그 인 되 지 않 은 방문 을 호 환 하기 위해 인증 절 차 를 밟 았 습 니 다.익명 의 신분 에 불과 합 니 다.
13 . org.springframework.security.web.session.SessionManagementFilter
Security ContextRepository 는 같은 사용자 가 여러 세 션 을 여 는 수량 을 제한 합 니 다.
14 . org.springframework.security.web.access.ExceptionTranslationFilter
이상 변환 필 터 는 전체 spring Security FilterChain 의 후방 에 위치 하여 전체 링크 에 나타 난 이상 을 변환 합 니 다.
15 . org.springframework.security.web.access.intercept.FilterSecurityInterceptor
설정 한 자원 접근 권한 수여 정 보 를 가 져 오고 Security ContextHolder 에 저 장 된 사용자 정보 에 따라 권한 이 있 는 지 여 부 를 결정 합 니 다.
그렇다면 spring security 에 모두 이렇게 많은 필터 가 있 는 것 일 까?정 답 은 부정!spring-security.xml 설정 이 추가 되면 서
새로운 필터 가 나타 납 니 다.
그렇다면 spring security 는 매번 이 필 터 를 불 러 오지 않 습 니까?답 도 부정 적!spring-security.xml 설정 에 따라 수정 되 었 습 니 다.
일부 필 터 는 지 워 질 수 있 습 니 다.
spring security 필터 체인 로드 원리
public class DelegatingFilterProxy extends GenericFilterBean {
@Nullable
private String contextAttribute;
@Nullable
private WebApplicationContext webApplicationContext;
@Nullable
private String targetBeanName;
private boolean targetFilterLifecycle;
@Nullable
private volatile Filter delegate;// :
private final Object delegateMonitor;
// :doFilter , !
public void doFilter(ServletRequest request, ServletResponse response, FilterChain
filterChain) throws ServletException, IOException {
Filter delegateToUse = this.delegate;
if (delegateToUse == null) {
synchronized(this.delegateMonitor) {
delegateToUse = this.delegate;
if (delegateToUse == null) {
WebApplicationContext wac = this.findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no
ContextLoaderListener or DispatcherServlet registered?");
}
// :doFilter , delegate
delegateToUse = this.initDelegate(wac);
}
this.delegate = delegateToUse;
}
}
// : FilterChainProxy
this.invokeDelegate(delegateToUse, request, response, filterChain);
}
// :
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
//debug targetBeanName :springSecurityFilterChain
String targetBeanName = this.getTargetBeanName();
Assert.state(targetBeanName != null, "No target bean name set");
//debug delegate :FilterChainProxy
Filter delegate = (Filter)wac.getBean(targetBeanName, Filter.class);
if (this.isTargetFilterLifecycle()) {
delegate.init(this.getFilterConfig());
}
return delegate;
}
protected void invokeDelegate(Filter delegate, ServletRequest request, ServletResponse
response, FilterChain filterChain) throws ServletException, IOException {
delegate.doFilter(request, response, filterChain);
}
}
두 번 째 debug 결 과 는 다음 과 같 습 니 다.이 를 통 해 알 수 있 듯 이 Delegating FilterProxy 는 spring Security FilterChain 이라는 이름 을 통 해 FilterChain Proxy 필 터 를 얻 었 습 니 다.
결국 세 번 째 단계 에서 이 필 터 를 실행 했다.
FilterChainProxy
public class FilterChainProxy extends GenericFilterBean {
private static final Log logger = LogFactory.getLog(FilterChainProxy.class);
private static final String FILTER_APPLIED =
FilterChainProxy.class.getName().concat(".APPLIED");
private List<SecurityFilterChain> filterChains;
private FilterChainProxy.FilterChainValidator filterChainValidator;
private HttpFirewall firewall;
// !? SecurityFilterChain FilterChainProxy
// FilterChainProxy ? ? !
public FilterChainProxy(SecurityFilterChain chain) {
this(Arrays.asList(chain));
}
// SecurityFilterChain ! !
public FilterChainProxy(List<SecurityFilterChain> filterChains) {
this.filterChainValidator = new FilterChainProxy.NullFilterChainValidator();
this.firewall = new StrictHttpFirewall();
this.filterChains = filterChains;
}
// : doFilter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
if (clearContext) {
try {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
this.doFilterInternal(request, response, chain);
} finally {
SecurityContextHolder.clearContext();
request.removeAttribute(FILTER_APPLIED);
}
} else {
// : doFilterInternal
this.doFilterInternal(request, response, chain);
}
}
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain
chain) throws IOException, ServletException {
FirewalledRequest fwRequest =
this.firewall.getFirewalledRequest((HttpServletRequest)request);
HttpServletResponse fwResponse =
this.firewall.getFirewalledResponse((HttpServletResponse)response);
// : , !
List<Filter> filters = this.getFilters((HttpServletRequest)fwRequest);
if (filters != null && filters.size() != 0) {
FilterChainProxy.VirtualFilterChain vfc = new
FilterChainProxy.VirtualFilterChain(fwRequest, chain, filters);
// :
vfc.doFilter(fwRequest, fwResponse);
} else {
if (logger.isDebugEnabled()) {
logger.debug(UrlUtils.buildRequestUrl(fwRequest) + (filters == null ? " has no
matching filters" : " has an empty filter list"));
}
fwRequest.reset();
chain.doFilter(fwRequest, fwResponse);
}
}
private List<Filter> getFilters(HttpServletRequest request) {
Iterator var2 = this.filterChains.iterator();
// : SecurityFilterChain !
SecurityFilterChain chain;
do {
if (!var2.hasNext()) {
return null;
}
chain = (SecurityFilterChain)var2.next();
} while(!chain.matches(request));
return chain.getFilters();
}
}
SecurityFilterChain
마지막 으로 Security FilterChain 을 보십시오.이것 은 인터페이스 입 니 다.실현 클래스 도 하나 입 니 다.이것 이 야 말로 웹.xml 에 설 치 된 필터 체인 대상 입 니 다!
public interface SecurityFilterChain {
boolean matches(HttpServletRequest request);
List<Filter> getFilters();
}
public final class DefaultSecurityFilterChain implements SecurityFilterChain {
private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);
private final RequestMatcher requestMatcher;
private final List<Filter> filters;
public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {
this(requestMatcher, Arrays.asList(filters));
}
public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {
logger.info("Creating filter chain: " + requestMatcher + ", " + filters);
this.requestMatcher = requestMatcher;
this.filters = new ArrayList<>(filters);
}
public RequestMatcher getRequestMatcher() {
return requestMatcher;
}
public List<Filter> getFilters() {
return filters;
}
public boolean matches(HttpServletRequest request) {
return requestMatcher.matches(request);
}
@Override
public String toString() {
return "[ " + requestMatcher + ", " + filters + "]";
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.