mirror of https://github.com/halo-dev/halo
Refactor authentication filters
parent
cfc8207919
commit
1e15f21e88
|
@ -6,10 +6,17 @@ import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
import run.halo.app.config.properties.HaloProperties;
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
|
import run.halo.app.exception.NotInstallException;
|
||||||
|
import run.halo.app.model.properties.PrimaryProperties;
|
||||||
import run.halo.app.security.handler.AuthenticationFailureHandler;
|
import run.halo.app.security.handler.AuthenticationFailureHandler;
|
||||||
import run.halo.app.security.handler.DefaultAuthenticationFailureHandler;
|
import run.halo.app.security.handler.DefaultAuthenticationFailureHandler;
|
||||||
|
import run.halo.app.service.OptionService;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,8 +43,12 @@ public abstract class AbstractAuthenticationFilter extends OncePerRequestFilter
|
||||||
|
|
||||||
private final HaloProperties haloProperties;
|
private final HaloProperties haloProperties;
|
||||||
|
|
||||||
protected AbstractAuthenticationFilter(HaloProperties haloProperties) {
|
private final OptionService optionService;
|
||||||
|
|
||||||
|
protected AbstractAuthenticationFilter(HaloProperties haloProperties,
|
||||||
|
OptionService optionService) {
|
||||||
this.haloProperties = haloProperties;
|
this.haloProperties = haloProperties;
|
||||||
|
this.optionService = optionService;
|
||||||
|
|
||||||
antPathMatcher = new AntPathMatcher();
|
antPathMatcher = new AntPathMatcher();
|
||||||
}
|
}
|
||||||
|
@ -154,4 +165,16 @@ public abstract class AbstractAuthenticationFilter extends OncePerRequestFilter
|
||||||
|
|
||||||
this.failureHandler = failureHandler;
|
this.failureHandler = failureHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
// Check whether the blog is installed or not
|
||||||
|
Boolean isInstalled = optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false);
|
||||||
|
|
||||||
|
if (!isInstalled) {
|
||||||
|
// If not installed
|
||||||
|
getFailureHandler().onFailure(request, response, new NotInstallException("The blog has not been initialized yet!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import run.halo.app.cache.StringCacheStore;
|
import run.halo.app.cache.StringCacheStore;
|
||||||
import run.halo.app.config.properties.HaloProperties;
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
import run.halo.app.exception.AuthenticationException;
|
import run.halo.app.exception.AuthenticationException;
|
||||||
import run.halo.app.exception.NotInstallException;
|
|
||||||
import run.halo.app.model.entity.User;
|
import run.halo.app.model.entity.User;
|
||||||
import run.halo.app.model.properties.PrimaryProperties;
|
|
||||||
import run.halo.app.security.authentication.AuthenticationImpl;
|
import run.halo.app.security.authentication.AuthenticationImpl;
|
||||||
import run.halo.app.security.context.SecurityContextHolder;
|
import run.halo.app.security.context.SecurityContextHolder;
|
||||||
import run.halo.app.security.context.SecurityContextImpl;
|
import run.halo.app.security.context.SecurityContextImpl;
|
||||||
|
@ -58,7 +55,7 @@ public class AdminAuthenticationFilter extends AbstractAuthenticationFilter {
|
||||||
/**
|
/**
|
||||||
* Admin token param name.
|
* Admin token param name.
|
||||||
*/
|
*/
|
||||||
public final static String ADMIN_TOKEN_QUERY_NAME = "adminToken";
|
public final static String ADMIN_TOKEN_QUERY_NAME = "admin_token";
|
||||||
|
|
||||||
private final HaloProperties haloProperties;
|
private final HaloProperties haloProperties;
|
||||||
|
|
||||||
|
@ -72,7 +69,7 @@ public class AdminAuthenticationFilter extends AbstractAuthenticationFilter {
|
||||||
UserService userService,
|
UserService userService,
|
||||||
HaloProperties haloProperties,
|
HaloProperties haloProperties,
|
||||||
OptionService optionService) {
|
OptionService optionService) {
|
||||||
super(haloProperties);
|
super(haloProperties, optionService);
|
||||||
this.cacheStore = cacheStore;
|
this.cacheStore = cacheStore;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.haloProperties = haloProperties;
|
this.haloProperties = haloProperties;
|
||||||
|
@ -82,59 +79,45 @@ public class AdminAuthenticationFilter extends AbstractAuthenticationFilter {
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
|
||||||
// Check whether the blog is installed or not
|
super.doFilterInternal(request, response, filterChain);
|
||||||
Boolean isInstalled = optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false);
|
|
||||||
|
|
||||||
if (!isInstalled) {
|
if (haloProperties.isAuthEnabled()) {
|
||||||
// If not installed
|
// Get token from request
|
||||||
getFailureHandler().onFailure(request, response, new NotInstallException("The blog has not been initialized yet!"));
|
String token = getTokenFromRequest(request);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!haloProperties.isAuthEnabled()) {
|
if (StringUtils.isBlank(token)) {
|
||||||
|
if (!shouldSkipAuthenticateFailure(request)) {
|
||||||
|
getFailureHandler().onFailure(request, response, new AuthenticationException("You have to login before accessing admin api"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Get user id from cache
|
||||||
|
Optional<Integer> optionalUserId = cacheStore.getAny(SecurityUtils.buildTokenAccessKey(token), Integer.class);
|
||||||
|
|
||||||
|
if (!optionalUserId.isPresent()) {
|
||||||
|
getFailureHandler().onFailure(request, response, new AuthenticationException("The token has been expired or not exist").setErrorData(token));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the user
|
||||||
|
User user = userService.getById(optionalUserId.get());
|
||||||
|
|
||||||
|
// Build user detail
|
||||||
|
UserDetail userDetail = new UserDetail(user);
|
||||||
|
|
||||||
|
// Set security
|
||||||
|
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(userDetail)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Set security
|
||||||
userService.getCurrentUser().ifPresent(user ->
|
userService.getCurrentUser().ifPresent(user ->
|
||||||
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(new UserDetail(user)))));
|
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(new UserDetail(user)))));
|
||||||
|
|
||||||
// If authentication disabled
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get token from request
|
filterChain.doFilter(request, response);
|
||||||
String token = getTokenFromRequest(request);
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(token)) {
|
// Clear context
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
// Get user id from cache
|
|
||||||
Optional<Integer> optionalUserId = cacheStore.getAny(SecurityUtils.buildTokenAccessKey(token), Integer.class);
|
|
||||||
|
|
||||||
if (!optionalUserId.isPresent()) {
|
|
||||||
getFailureHandler().onFailure(request, response, new AuthenticationException("The token has been expired or not exist").setErrorData(token));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the user
|
|
||||||
User user = userService.getById(optionalUserId.get());
|
|
||||||
|
|
||||||
// Build user detail
|
|
||||||
UserDetail userDetail = new UserDetail(user);
|
|
||||||
|
|
||||||
// Set security
|
|
||||||
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(userDetail)));
|
|
||||||
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldSkipAuthenticateFailure(request)) {
|
|
||||||
// If should skip this authentication failure
|
|
||||||
log.debug("Skipping authentication failure, url: [{}], method: [{}]", request.getServletPath(), request.getMethod());
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFailureHandler().onFailure(request, response, new AuthenticationException("You have to login before accessing admin api"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,9 +8,7 @@ import org.springframework.util.Assert;
|
||||||
import run.halo.app.config.properties.HaloProperties;
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
import run.halo.app.exception.AuthenticationException;
|
import run.halo.app.exception.AuthenticationException;
|
||||||
import run.halo.app.exception.ForbiddenException;
|
import run.halo.app.exception.ForbiddenException;
|
||||||
import run.halo.app.exception.NotInstallException;
|
|
||||||
import run.halo.app.model.properties.OtherProperties;
|
import run.halo.app.model.properties.OtherProperties;
|
||||||
import run.halo.app.model.properties.PrimaryProperties;
|
|
||||||
import run.halo.app.service.OptionService;
|
import run.halo.app.service.OptionService;
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
|
@ -30,26 +28,20 @@ public class ApiAuthenticationFilter extends AbstractAuthenticationFilter {
|
||||||
|
|
||||||
public final static String API_TOKEN_HEADER_NAME = "API-" + HttpHeaders.AUTHORIZATION;
|
public final static String API_TOKEN_HEADER_NAME = "API-" + HttpHeaders.AUTHORIZATION;
|
||||||
|
|
||||||
public final static String API_TOKEN_QUERY_NAME = "apiToken";
|
public final static String API_TOKEN_QUERY_NAME = "api_token";
|
||||||
|
|
||||||
private final OptionService optionService;
|
private final OptionService optionService;
|
||||||
|
|
||||||
public ApiAuthenticationFilter(HaloProperties haloProperties,
|
public ApiAuthenticationFilter(HaloProperties haloProperties,
|
||||||
OptionService optionService) {
|
OptionService optionService) {
|
||||||
super(haloProperties);
|
super(haloProperties, optionService);
|
||||||
this.optionService = optionService;
|
this.optionService = optionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
// Check whether the blog is installed or not
|
|
||||||
Boolean isInstalled = optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false);
|
|
||||||
|
|
||||||
if (!isInstalled) {
|
super.doFilterInternal(request, response, filterChain);
|
||||||
// If not installed
|
|
||||||
getFailureHandler().onFailure(request, response, new NotInstallException("The blog has not been initialized yet!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get token
|
// Get token
|
||||||
String token = getTokenFromRequest(request);
|
String token = getTokenFromRequest(request);
|
||||||
|
|
Loading…
Reference in New Issue