Spring Security Authorization Filter
Spring Security supports to easily configure role or authority for a specified resource by using Spring security expression.
For example,
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
...
.antMatchers("/auth/admin/*").hasRole("ADMIN")
.antMatchers("/auth/*").hasAnyRole("ADMIN","USER")
...
}
But I am still intertersted how the authorization is checked for a specified resource of a user, that what the AuthorizationFilter
, RequestMatcherDelegatingAuthorizationManager
and AuthorityAuthorizationManager
do the work.
-
In
AuthorizationFilter
, it callsRequestMatcherDelegatingAuthorizationManager.check
to check the authority of the requestJava@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; if (this.observeOncePerRequest && isApplied(request)) { chain.doFilter(request, response); return; } if (skipDispatch(request)) { chain.doFilter(request, response); return; } String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName(); request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE); try { AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request); this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, decision); if (decision != null && !decision.isGranted()) { throw new AccessDeniedException("Access Denied"); } chain.doFilter(request, response); } finally { request.removeAttribute(alreadyFilteredAttributeName); } }
-
In
RequestMatcherDelegatingAuthorizationManager.check
method, it find theAuthorizationManager<RequestAuthorizationContext>
by the request urlJava@Override public AuthorizationDecision check(Supplier<Authentication> authentication, HttpServletRequest request) { if (this.logger.isTraceEnabled()) { this.logger.trace(LogMessage.format("Authorizing %s", request)); } for (RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>> mapping : this.mappings) { RequestMatcher matcher = mapping.getRequestMatcher(); MatchResult matchResult = matcher.matcher(request); if (matchResult.isMatch()) { AuthorizationManager<RequestAuthorizationContext> manager = mapping.getEntry(); if (this.logger.isTraceEnabled()) { this.logger.trace(LogMessage.format("Checking authorization on %s using %s", request, manager)); } return manager.check(authentication, new RequestAuthorizationContext(request, matchResult.getVariables())); } } if (this.logger.isTraceEnabled()) { this.logger.trace(LogMessage.of(() -> "Denying request since did not find matching RequestMatcher")); } return DENY; }
-
In
AuthorizationManager.check
method, it check if user has the required authority.