SpringSecurity权限过滤是由AuthorizationFilter负责的,核心代码如下
代码语言:javascript复制public class AuthorizationFilter extends OncePerRequestFilter {
private final AuthorizationManager<HttpServletRequest> authorizationManager;
private AuthorizationEventPublisher eventPublisher = AuthorizationFilter::noPublish;
private boolean shouldFilterAllDispatcherTypes = false;
/**
* Creates an instance.
* @param authorizationManager the {@link AuthorizationManager} to use
*/
public AuthorizationFilter(AuthorizationManager<HttpServletRequest> authorizationManager) {
Assert.notNull(authorizationManager, "authorizationManager cannot be null");
this.authorizationManager = authorizationManager;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//判断用户是否有权限
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");
}
filterChain.doFilter(request, response);
}
private Authentication getAuthentication() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new AuthenticationCredentialsNotFoundException(
"An Authentication object was not found in the SecurityContext");
}
return authentication;
}
@Override
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
doFilterInternal(request, response, filterChain);
}
@Override
protected boolean shouldNotFilterAsyncDispatch() {
return !this.shouldFilterAllDispatcherTypes;
}
@Override
protected boolean shouldNotFilterErrorDispatch() {
return !this.shouldFilterAllDispatcherTypes;
}
/**
* Use this {@link AuthorizationEventPublisher} to publish
* {@link AuthorizationDeniedEvent}s and {@link AuthorizationGrantedEvent}s.
* @param eventPublisher the {@link ApplicationEventPublisher} to use
* @since 5.7
*/
public void setAuthorizationEventPublisher(AuthorizationEventPublisher eventPublisher) {
Assert.notNull(eventPublisher, "eventPublisher cannot be null");
this.eventPublisher = eventPublisher;
}
/**
* Gets the {@link AuthorizationManager} used by this filter
* @return the {@link AuthorizationManager}
*/
public AuthorizationManager<HttpServletRequest> getAuthorizationManager() {
return this.authorizationManager;
}
/**
* Sets whether to filter all dispatcher types.
* @param shouldFilterAllDispatcherTypes should filter all dispatcher types. Default
* is {@code false}
* @since 5.7
*/
public void setShouldFilterAllDispatcherTypes(boolean shouldFilterAllDispatcherTypes) {
this.shouldFilterAllDispatcherTypes = shouldFilterAllDispatcherTypes;
}
private static <T> void noPublish(Supplier<Authentication> authentication, T object,
AuthorizationDecision decision) {
}
}