mirror of https://github.com/halo-dev/halo
Complete AdminAuthenticationFilter
parent
9a9295d6c1
commit
42032e3b78
|
@ -78,8 +78,10 @@ public class HaloConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<AdminAuthenticationFilter> adminAuthenticationFilter(HaloProperties haloProperties, ObjectMapper objectMapper) {
|
||||
AdminAuthenticationFilter adminFilter = new AdminAuthenticationFilter();
|
||||
public FilterRegistrationBean<AdminAuthenticationFilter> adminAuthenticationFilter(HaloProperties haloProperties,
|
||||
ObjectMapper objectMapper,
|
||||
StringCacheStore cacheStore) {
|
||||
AdminAuthenticationFilter adminFilter = new AdminAuthenticationFilter(cacheStore);
|
||||
// Set failure handler
|
||||
adminFilter.setFailureHandler(new AdminAuthenticationFailureHandler(haloProperties.getProductionEnv(), objectMapper));
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ public class CorsFilter extends OncePerRequestFilter {
|
|||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTION");
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "false");
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600");
|
||||
|
||||
if (CorsUtils.isPreFlightRequest(httpServletRequest)) {
|
||||
|
|
|
@ -96,8 +96,10 @@ public class LocalFileHandler implements FileHandler {
|
|||
// Build directory
|
||||
String subDir = UPLOAD_SUB_DIR + year + File.separator + month + File.separator;
|
||||
|
||||
String originalBasename = FilenameUtils.getBasename(file.getOriginalFilename());
|
||||
|
||||
// Get basename
|
||||
String basename = FilenameUtils.getBasename(file.getOriginalFilename()) + '-' + HaloUtils.randomUUIDWithoutDash();
|
||||
String basename = originalBasename + '-' + HaloUtils.randomUUIDWithoutDash();
|
||||
|
||||
// Get extension
|
||||
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
|
||||
|
@ -123,7 +125,7 @@ public class LocalFileHandler implements FileHandler {
|
|||
|
||||
// Build upload result
|
||||
UploadResult uploadResult = new UploadResult();
|
||||
uploadResult.setFilename(basename);
|
||||
uploadResult.setFilename(originalBasename);
|
||||
uploadResult.setFilePath(subFilePath);
|
||||
uploadResult.setKey(subFilePath);
|
||||
uploadResult.setSuffix(extension);
|
||||
|
|
|
@ -109,6 +109,7 @@ public interface PropertyEnum extends ValueEnum<String> {
|
|||
|| type.isAssignableFrom(Double.class)
|
||||
|| type.isAssignableFrom(Float.class)
|
||||
|| type.isAssignableFrom(Enum.class)
|
||||
|| type.isAssignableFrom(ValueEnum.class)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
package cc.ryanc.halo.security.filter;
|
||||
|
||||
import cc.ryanc.halo.cache.StringCacheStore;
|
||||
import cc.ryanc.halo.exception.AuthenticationException;
|
||||
import cc.ryanc.halo.security.authentication.AuthenticationImpl;
|
||||
import cc.ryanc.halo.security.context.SecurityContextHolder;
|
||||
import cc.ryanc.halo.security.context.SecurityContextImpl;
|
||||
import cc.ryanc.halo.security.handler.AuthenticationFailureHandler;
|
||||
import cc.ryanc.halo.security.support.UserDetail;
|
||||
import cc.ryanc.halo.utils.JsonUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
|
@ -8,6 +20,7 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Admin authentication filter.
|
||||
|
@ -16,15 +29,92 @@ import java.io.IOException;
|
|||
*/
|
||||
public class AdminAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
/**
|
||||
* Admin session key.
|
||||
*/
|
||||
public final static String ADMIN_SESSION_KEY = "halo.admin.session";
|
||||
|
||||
/**
|
||||
* Admin token header name.
|
||||
*/
|
||||
public final static String ADMIN_TOKEN_HEADER_NAME = "ADMIN-" + HttpHeaders.AUTHORIZATION;
|
||||
|
||||
/**
|
||||
* Admin token param name.
|
||||
*/
|
||||
public final static String ADMIN_TOKEN_PARAM_NAME = "adminToken";
|
||||
|
||||
private AuthenticationFailureHandler failureHandler;
|
||||
|
||||
private final StringCacheStore cacheStore;
|
||||
|
||||
public AdminAuthenticationFilter(StringCacheStore cacheStore) {
|
||||
this.cacheStore = cacheStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||
// TODO Handle admin authentication
|
||||
// Get token from request
|
||||
String token = getTokenFromRequest(request);
|
||||
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
|
||||
// Valid the token
|
||||
Optional<String> userDetailOptional = cacheStore.get(token);
|
||||
|
||||
if (!userDetailOptional.isPresent()) {
|
||||
failureHandler.onFailure(request, response, new AuthenticationException("The token has been expired or not exist").setErrorData(token));
|
||||
return;
|
||||
}
|
||||
|
||||
UserDetail userDetail = JsonUtils.jsonToObject(userDetailOptional.get(), UserDetail.class);
|
||||
|
||||
// Set security
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(userDetail)));
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get info from session
|
||||
Object adminSessionValue = request.getSession().getAttribute(ADMIN_SESSION_KEY);
|
||||
|
||||
if (adminSessionValue instanceof UserDetail) {
|
||||
// Convert to user detail
|
||||
UserDetail userDetail = (UserDetail) adminSessionValue;
|
||||
|
||||
// Set security context
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(userDetail)));
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
failureHandler.onFailure(request, response, new AuthenticationException("You have to login before accessing admin api"));
|
||||
}
|
||||
|
||||
public void setFailureHandler(AuthenticationFailureHandler failureHandler) {
|
||||
this.failureHandler = failureHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets token from request.
|
||||
*
|
||||
* @param request http servlet request must not be null
|
||||
* @return token or null
|
||||
*/
|
||||
@Nullable
|
||||
private String getTokenFromRequest(@NonNull HttpServletRequest request) {
|
||||
Assert.notNull(request, "Http servlet request must not be null");
|
||||
|
||||
// Get from header
|
||||
String token = request.getHeader(ADMIN_TOKEN_HEADER_NAME);
|
||||
|
||||
// Get from param
|
||||
if (StringUtils.isBlank(token)) {
|
||||
token = request.getParameter(ADMIN_TOKEN_PARAM_NAME);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
package cc.ryanc.halo.security.handler;
|
||||
|
||||
import cc.ryanc.halo.exception.HaloException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Authentication failure handler.
|
||||
*
|
||||
|
@ -19,8 +13,8 @@ public class AdminAuthenticationFailureHandler extends DefaultAuthenticationFail
|
|||
super(productionEnv, objectMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpServletRequest request, HttpServletResponse response, HaloException exception) throws IOException, ServletException {
|
||||
// TODO handler the admin authentication failure.
|
||||
}
|
||||
// @Override
|
||||
// public void onFailure(HttpServletRequest request, HttpServletResponse response, HaloException exception) throws IOException, ServletException {
|
||||
// // TODO handler the admin authentication failure.
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public class DefaultAuthenticationFailureHandler implements AuthenticationFailur
|
|||
|
||||
BaseResponse errorDetail = new BaseResponse();
|
||||
|
||||
errorDetail.setStatus(exception.getStatus().value());
|
||||
errorDetail.setMessage(exception.getMessage());
|
||||
|
||||
if (!productionEnv) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import cc.ryanc.halo.exception.MissingPropertyException;
|
|||
import cc.ryanc.halo.model.dto.OptionOutputDTO;
|
||||
import cc.ryanc.halo.model.entity.Option;
|
||||
import cc.ryanc.halo.model.enums.PropertyEnum;
|
||||
import cc.ryanc.halo.model.enums.ValueEnum;
|
||||
import cc.ryanc.halo.model.params.OptionParam;
|
||||
import cc.ryanc.halo.service.base.CrudService;
|
||||
import com.qiniu.common.Zone;
|
||||
|
@ -170,6 +171,7 @@ public interface OptionService extends CrudService<Option, Integer> {
|
|||
* @param <T> value type
|
||||
* @return value
|
||||
*/
|
||||
@NonNull
|
||||
<T> Optional<T> getByKey(@NonNull String key, @NonNull Class<T> valueType);
|
||||
|
||||
/**
|
||||
|
@ -180,6 +182,7 @@ public interface OptionService extends CrudService<Option, Integer> {
|
|||
* @param <T> enum value type
|
||||
* @return an optional enum value
|
||||
*/
|
||||
@NonNull
|
||||
<T extends Enum<T>> Optional<T> getEnumByProperty(@NonNull PropertyEnum property, @NonNull Class<T> valueType);
|
||||
|
||||
/**
|
||||
|
@ -191,7 +194,36 @@ public interface OptionService extends CrudService<Option, Integer> {
|
|||
* @param <T> enum value type
|
||||
* @return enum value
|
||||
*/
|
||||
<T extends Enum<T>> T getEnumByPropertyOrDefault(@NonNull PropertyEnum property, @NonNull Class<T> valueType, T defaultValue);
|
||||
@Nullable
|
||||
<T extends Enum<T>> T getEnumByPropertyOrDefault(@NonNull PropertyEnum property, @NonNull Class<T> valueType, @Nullable T defaultValue);
|
||||
|
||||
/**
|
||||
* Gets value enum by property.
|
||||
*
|
||||
* @param property property must not be blank
|
||||
* @param valueType enum value type must not be null
|
||||
* @param enumType enum type must not be null
|
||||
* @param <V> enum value type
|
||||
* @param <E> value enum type
|
||||
* @return an optional value enum value
|
||||
*/
|
||||
@NonNull
|
||||
<V, E extends ValueEnum<V>> Optional<E> getValueEnumByProperty(@NonNull PropertyEnum property, @NonNull Class<V> valueType, @NonNull Class<E> enumType);
|
||||
|
||||
/**
|
||||
* Gets value enum by property.
|
||||
*
|
||||
* @param property property must not be blank
|
||||
* @param valueType enum value type must not be null
|
||||
* @param enumType enum type must not be null
|
||||
* @param defaultValue default value enum value
|
||||
* @param <V> enum value type
|
||||
* @param <E> value enum type
|
||||
* @return value enum value or null if the default value is null
|
||||
*/
|
||||
@Nullable
|
||||
<V, E extends ValueEnum<V>> E getValueEnumByPropertyOrDefault(@NonNull PropertyEnum property, @NonNull Class<V> valueType, @NonNull Class<E> enumType, @Nullable E defaultValue);
|
||||
|
||||
|
||||
/**
|
||||
* Gets post page size.
|
||||
|
|
|
@ -6,6 +6,7 @@ import cc.ryanc.halo.model.entity.Option;
|
|||
import cc.ryanc.halo.model.enums.BlogProperties;
|
||||
import cc.ryanc.halo.model.enums.PropertyEnum;
|
||||
import cc.ryanc.halo.model.enums.QnYunProperties;
|
||||
import cc.ryanc.halo.model.enums.ValueEnum;
|
||||
import cc.ryanc.halo.model.params.OptionParam;
|
||||
import cc.ryanc.halo.repository.OptionRepository;
|
||||
import cc.ryanc.halo.service.OptionService;
|
||||
|
@ -198,6 +199,16 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
|||
return getEnumByProperty(property, valueType).orElse(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V, E extends ValueEnum<V>> Optional<E> getValueEnumByProperty(PropertyEnum property, Class<V> valueType, Class<E> enumType) {
|
||||
return getByProperty(property).map(value -> ValueEnum.valueToEnum(enumType, PropertyEnum.convertTo(value, valueType)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V, E extends ValueEnum<V>> E getValueEnumByPropertyOrDefault(PropertyEnum property, Class<V> valueType, Class<E> enumType, E defaultValue) {
|
||||
return getValueEnumByProperty(property, valueType, enumType).orElse(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPostPageSize() {
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue