refactor: 执行机下载资源时增加totp校验

This commit is contained in:
CaptainB 2023-09-14 13:56:21 +08:00 committed by 刘瑞斌
parent b50d6652d1
commit bfc70f58f9
3 changed files with 50 additions and 2 deletions

View File

@ -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");

View File

@ -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");
}
}
}

View File

@ -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;
}
} }