Add content filter

pull/146/head
johnniang 2019-05-06 19:46:11 +08:00
parent 22a7311fef
commit 5271be57c1
10 changed files with 92 additions and 73 deletions

View File

@ -16,11 +16,11 @@ import run.halo.app.cache.InMemoryCacheStore;
import run.halo.app.cache.StringCacheStore;
import run.halo.app.config.properties.HaloProperties;
import run.halo.app.filter.CorsFilter;
import run.halo.app.filter.GuardFilter;
import run.halo.app.filter.LogFilter;
import run.halo.app.security.filter.AdminAuthenticationFilter;
import run.halo.app.security.filter.ApiAuthenticationFilter;
import run.halo.app.security.handler.AdminAuthenticationFailureHandler;
import run.halo.app.security.filter.ContentFilter;
import run.halo.app.security.handler.ContentAuthenticationFailureHandler;
import run.halo.app.security.handler.DefaultAuthenticationFailureHandler;
import run.halo.app.service.OptionService;
import run.halo.app.service.UserService;
@ -76,15 +76,6 @@ public class HaloConfiguration {
return corsFilter;
}
@Bean
public FilterRegistrationBean<GuardFilter> guardFilter() {
FilterRegistrationBean<GuardFilter> guardFilter = new FilterRegistrationBean<>();
guardFilter.setOrder(Ordered.HIGHEST_PRECEDENCE);
guardFilter.setFilter(new GuardFilter());
guardFilter.addUrlPatterns("/api/*");
return guardFilter;
}
/**
* Creates a LogFilter.
*
@ -101,6 +92,21 @@ public class HaloConfiguration {
return logFilter;
}
@Bean
public FilterRegistrationBean<ContentFilter> contentFilter(HaloProperties haloProperties,
OptionService optionService) {
ContentFilter contentFilter = new ContentFilter(haloProperties, optionService);
contentFilter.setFailureHandler(new ContentAuthenticationFailureHandler());
contentFilter.addExcludeUrlPatterns("/api/*", "/install", "/admin/*", "/js/*", "/css/*");
FilterRegistrationBean<ContentFilter> contentFrb = new FilterRegistrationBean<>();
contentFrb.addUrlPatterns("/*");
contentFrb.setFilter(contentFilter);
contentFrb.setOrder(-1);
return contentFrb;
}
@Bean
public FilterRegistrationBean<ApiAuthenticationFilter> apiAuthenticationFilter(HaloProperties haloProperties,
ObjectMapper objectMapper,
@ -118,6 +124,7 @@ public class HaloConfiguration {
authenticationFilter.setFilter(apiFilter);
authenticationFilter.addUrlPatterns("/api/content/*");
authenticationFilter.setOrder(0);
return authenticationFilter;
}
@ -129,7 +136,7 @@ public class HaloConfiguration {
OptionService optionService) {
AdminAuthenticationFilter adminAuthenticationFilter = new AdminAuthenticationFilter(cacheStore, userService, haloProperties, optionService);
AdminAuthenticationFailureHandler failureHandler = new AdminAuthenticationFailureHandler();
DefaultAuthenticationFailureHandler failureHandler = new DefaultAuthenticationFailureHandler();
failureHandler.setProductionEnv(haloProperties.isProductionEnv());
failureHandler.setObjectMapper(objectMapper);
@ -149,6 +156,7 @@ public class HaloConfiguration {
authenticationFilter.setFilter(adminAuthenticationFilter);
authenticationFilter.addUrlPatterns("/api/admin/*", "/api/content/comments");
authenticationFilter.setOrder(1);
return authenticationFilter;
}
}

View File

@ -1,6 +1,5 @@
package run.halo.app.controller.admin.api;
import freemarker.template.Configuration;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
@ -57,8 +56,6 @@ public class InstallController {
private final MenuService menuService;
private final Configuration configuration;
private final ApplicationEventPublisher eventPublisher;
public InstallController(UserService userService,
@ -67,7 +64,6 @@ public class InstallController {
PostCommentService postCommentService,
OptionService optionService,
MenuService menuService,
Configuration configuration,
ApplicationEventPublisher eventPublisher) {
this.userService = userService;
this.categoryService = categoryService;
@ -75,7 +71,6 @@ public class InstallController {
this.postCommentService = postCommentService;
this.optionService = optionService;
this.menuService = menuService;
this.configuration = configuration;
this.eventPublisher = eventPublisher;
}

View File

@ -1,4 +1,4 @@
package run.halo.app.controller.admin.api;
package run.halo.app.controller.content.api;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@ -17,4 +17,9 @@ public class MainController {
public String admin() {
return "redirect:/admin/index.html";
}
@GetMapping("/install")
public String installation() {
return "redirect:/admin/index.html#install";
}
}

View File

@ -60,7 +60,7 @@ public class CommonController implements ErrorController {
log.error("Captured an exception", throwable);
if (StringUtils.startsWithIgnoreCase(throwable.getMessage(), "Could not resolve view with name '")) {
// TODO May cause unreasoned problem
// TODO May cause unknown-reason problem
// if Ftl was not found then redirect to /404
if (requestURI.contains(ADMIN_URL) && null != user) {
return "redirect:/admin/404";

View File

@ -1,27 +0,0 @@
package run.halo.app.filter;
import org.springframework.web.filter.GenericFilterBean;
import run.halo.app.security.context.SecurityContextHolder;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* @author johnniang
* @date 19-4-30
*/
public class GuardFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// Do filter
chain.doFilter(request, response);
// Clear security context
SecurityContextHolder.clearContext();
}
}

View File

@ -63,6 +63,8 @@ public abstract class AbstractAuthenticationFilter extends OncePerRequestFilter
@Nullable
protected abstract String getTokenFromRequest(@NonNull HttpServletRequest request);
protected abstract void doAuthenticate(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException;
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
Assert.notNull(request, "Http servlet request must not be null");
@ -193,5 +195,4 @@ public abstract class AbstractAuthenticationFilter extends OncePerRequestFilter
}
}
protected abstract void doAuthenticate(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException;
}

View File

@ -63,8 +63,6 @@ public class AdminAuthenticationFilter extends AbstractAuthenticationFilter {
private final UserService userService;
private final OptionService optionService;
public AdminAuthenticationFilter(StringCacheStore cacheStore,
UserService userService,
HaloProperties haloProperties,
@ -73,7 +71,6 @@ public class AdminAuthenticationFilter extends AbstractAuthenticationFilter {
this.cacheStore = cacheStore;
this.userService = userService;
this.haloProperties = haloProperties;
this.optionService = optionService;
}
@Override

View File

@ -0,0 +1,34 @@
package run.halo.app.security.filter;
import run.halo.app.config.properties.HaloProperties;
import run.halo.app.service.OptionService;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Content filter
*
* @author johnniang
* @date 19-5-6
*/
public class ContentFilter extends AbstractAuthenticationFilter {
public ContentFilter(HaloProperties haloProperties, OptionService optionService) {
super(haloProperties, optionService);
}
@Override
protected String getTokenFromRequest(HttpServletRequest request) {
return null;
}
@Override
protected void doAuthenticate(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// Do nothing
return;
}
}

View File

@ -1,23 +0,0 @@
package run.halo.app.security.handler;
import run.halo.app.exception.HaloException;
import run.halo.app.exception.HaloException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Authentication failure handler.
*
* @author johnniang
*/
public class AdminAuthenticationFailureHandler extends DefaultAuthenticationFailureHandler {
@Override
public void onFailure(HttpServletRequest request, HttpServletResponse response, HaloException exception) throws IOException, ServletException {
// TODO handler the admin authentication failure.
super.onFailure(request, response, exception);
}
}

View File

@ -0,0 +1,29 @@
package run.halo.app.security.handler;
import run.halo.app.exception.HaloException;
import run.halo.app.exception.NotInstallException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Content authentication failure handler.
*
* @author johnniang
* @date 19-5-6
*/
public class ContentAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onFailure(HttpServletRequest request, HttpServletResponse response, HaloException exception) throws IOException, ServletException {
if (exception instanceof NotInstallException) {
response.sendRedirect(request.getContextPath() + "/install");
return;
}
// Forward to error
request.getRequestDispatcher(request.getContextPath() + "/error").forward(request, response);
}
}