refactor: 执行机下载资源时增加totp校验
This commit is contained in:
parent
b50d6652d1
commit
bfc70f58f9
|
@ -4,6 +4,7 @@ package io.metersphere.sdk.config;
|
||||||
import io.metersphere.sdk.security.ApiKeyFilter;
|
import io.metersphere.sdk.security.ApiKeyFilter;
|
||||||
import io.metersphere.sdk.security.CsrfFilter;
|
import io.metersphere.sdk.security.CsrfFilter;
|
||||||
import io.metersphere.sdk.security.MsPermissionAnnotationMethodInterceptor;
|
import io.metersphere.sdk.security.MsPermissionAnnotationMethodInterceptor;
|
||||||
|
import io.metersphere.sdk.security.TotpFilter;
|
||||||
import io.metersphere.sdk.security.realm.LocalRealm;
|
import io.metersphere.sdk.security.realm.LocalRealm;
|
||||||
import io.metersphere.sdk.util.FilterChainUtils;
|
import io.metersphere.sdk.util.FilterChainUtils;
|
||||||
import jakarta.servlet.DispatcherType;
|
import jakarta.servlet.DispatcherType;
|
||||||
|
@ -42,10 +43,13 @@ public class ShiroConfig {
|
||||||
|
|
||||||
shiroFilterFactoryBean.getFilters().put("apikey", new ApiKeyFilter());
|
shiroFilterFactoryBean.getFilters().put("apikey", new ApiKeyFilter());
|
||||||
shiroFilterFactoryBean.getFilters().put("csrf", new CsrfFilter());
|
shiroFilterFactoryBean.getFilters().put("csrf", new CsrfFilter());
|
||||||
|
shiroFilterFactoryBean.getFilters().put("totp", new TotpFilter());
|
||||||
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
||||||
|
|
||||||
filterChainDefinitionMap.putAll(FilterChainUtils.loadBaseFilterChain());
|
filterChainDefinitionMap.putAll(FilterChainUtils.loadBaseFilterChain());
|
||||||
|
|
||||||
|
filterChainDefinitionMap.putAll(FilterChainUtils.totpFilterChain());
|
||||||
|
|
||||||
filterChainDefinitionMap.putAll(FilterChainUtils.ignoreCsrfFilter());
|
filterChainDefinitionMap.putAll(FilterChainUtils.ignoreCsrfFilter());
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/**", "apikey, csrf, authc");
|
filterChainDefinitionMap.put("/**", "apikey, csrf, authc");
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package io.metersphere.sdk.security;
|
||||||
|
|
||||||
|
|
||||||
|
import com.bastiaanjansen.otp.TOTPGenerator;
|
||||||
|
import io.metersphere.sdk.constants.MsHttpHeaders;
|
||||||
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
|
import jakarta.servlet.ServletRequest;
|
||||||
|
import jakarta.servlet.ServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.shiro.web.filter.authc.AnonymousFilter;
|
||||||
|
import org.apache.shiro.web.util.WebUtils;
|
||||||
|
|
||||||
|
public class TotpFilter extends AnonymousFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
|
||||||
|
HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
|
||||||
|
|
||||||
|
// 请求头取出的token value
|
||||||
|
String token = httpServletRequest.getHeader(MsHttpHeaders.OTP_TOKEN);
|
||||||
|
// 校验 token
|
||||||
|
validateToken(token);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateToken(String token) {
|
||||||
|
if (StringUtils.isBlank(token)) {
|
||||||
|
throw new RuntimeException("token is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
TOTPGenerator totpGenerator = CommonBeanFactory.getBean(TOTPGenerator.class);
|
||||||
|
if (!totpGenerator.verify(token)) {
|
||||||
|
throw new RuntimeException("token is not valid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,9 +22,8 @@ public class FilterChainUtils {
|
||||||
filterChainDefinitionMap.put("/display/info", "anon");
|
filterChainDefinitionMap.put("/display/info", "anon");
|
||||||
filterChainDefinitionMap.put("/favicon.ico", "anon");
|
filterChainDefinitionMap.put("/favicon.ico", "anon");
|
||||||
filterChainDefinitionMap.put("/base-display/**", "anon");
|
filterChainDefinitionMap.put("/base-display/**", "anon");
|
||||||
filterChainDefinitionMap.put("/jmeter/download/**", "anon");
|
|
||||||
filterChainDefinitionMap.put("/jmeter/ping", "anon");
|
filterChainDefinitionMap.put("/jmeter/ping", "anon");
|
||||||
filterChainDefinitionMap.put("/jmeter/ready/**", "anon");
|
filterChainDefinitionMap.put("/jmeter/ready/**", "totp");
|
||||||
filterChainDefinitionMap.put("/authsource/list/allenable", "anon");
|
filterChainDefinitionMap.put("/authsource/list/allenable", "anon");
|
||||||
filterChainDefinitionMap.put("/sso/callback/**", "anon");
|
filterChainDefinitionMap.put("/sso/callback/**", "anon");
|
||||||
filterChainDefinitionMap.put("/license/validate", "anon");
|
filterChainDefinitionMap.put("/license/validate", "anon");
|
||||||
|
@ -72,4 +71,11 @@ public class FilterChainUtils {
|
||||||
filterChainDefinitionMap.put("/mock", "apikey, authc"); // 跳转到 /mock接口 不用校验 csrf
|
filterChainDefinitionMap.put("/mock", "apikey, authc"); // 跳转到 /mock接口 不用校验 csrf
|
||||||
return filterChainDefinitionMap;
|
return filterChainDefinitionMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> totpFilterChain() {
|
||||||
|
Map<String, String> filterChainDefinitionMap = new HashMap<>();
|
||||||
|
// 执行机下载执行资源需要验证totp
|
||||||
|
filterChainDefinitionMap.put("/jmeter/download/**", "totp");
|
||||||
|
return filterChainDefinitionMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue