Togglz returns 功能切换时出现 403
Togglz returns a 403 on feature toggle
我已经在我的 spring 启动应用程序中实现了 togglz。我什至可以访问 Togglz 控制台,并且我已经使用 FeatureManager 测试了限制。但是,如果我转到 togglz 控制台并尝试更改激活策略或 enable/disable 功能,我会收到 403 Forbidden 错误页面。
换句话说,我可以访问 /togglz/index 但我不能 access/call /togglz/edit
在我的 WebMvcConfigurer class:
@Bean
public FilterRegistrationBean<TogglzFilter> togglzRegistration() {
FilterRegistrationBean<TogglzFilter> reg = new FilterRegistrationBean<>();
reg.setFilter(new TogglzFilter());
reg.addUrlPatterns("/*");
reg.setName("TogglzFilter");
return reg;
}
@Bean
public ServletRegistrationBean<TogglzConsoleServlet> togglzConsoleServlet() {
ServletRegistrationBean<TogglzConsoleServlet> reg = new ServletRegistrationBean<>();
reg.setServlet(new TogglzConsoleServlet());
reg.setName("TogglzConsoleServlet");
reg.addUrlMappings("/togglz/*");
return reg;
}
在我的 TogglzConfiguration 中:
@Component
public class TogglzConfiguration implements TogglzConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(TogglzConfiguration.class);
@Autowired
private ResourceLoader resourceLoader;
@Override
public Class<? extends Feature> getFeatureClass() {
return Features.class;
}
@Override
public StateRepository getStateRepository() {
try {
return new FileBasedStateRepository(
resourceLoader.getResource("classpath:/togglz.properties").getFile()
);
} catch (IOException ex) {
LOGGER.error(ex.getMessage(),ex);
throw new RuntimeException(ex);
}
}
@Override
public UserProvider getUserProvider() {
return new UserProvider() {
@Override
public FeatureUser getCurrentUser() {
return new SimpleFeatureUser("admin", true);
}
};
}
}
我的特点class:
public enum Features implements Feature {
@Label("Inventory Initiation")
@TestingUI
TESTING_UI_INITIATE_INVENTORY,
@Label("Random Warehouse Creation")
@TestingUI
TESTING_UI_CREATE_WAREHOUSE
;
public boolean isActive() {
return FeatureContext.getFeatureManager().isActive(this);
}
}
togglz application.yml
你有什么配置?您很可能在此处遗漏了 secure: false
:
togglz:
enabled: true
console:
enabled: true
secured: false
您似乎在应用程序中使用了某种 CSRF 保护。至少这可以解释为什么只有 POST 个请求被破坏。
Togglz 控制台提供了一个 SPI,用于获取需要嵌入表单的 CSRF 令牌:
Togglz 支持 Spring 安全 CSRF 保护:
Togglz 正在使用 JDK 的 ServiceLoader 工具来查找提供程序。因此,在 Spring 安全性的情况下,只有一个引用实现的文件 class:
所以如果你想将一些第 3 方 CSRF 保护框架与 Togglz 集成,你必须:
- 实施
CSRFTokenProvider
- 将文件
META-INF/services/org.togglz.servlet.spi.CSRFTokenProvider
添加到您的 class 路径并向其添加实现 class 的完全限定 class 名称。
这里也一样。由于我是 Java 和 Spring 的新手,所以我在尝试从 @chkal 解决方案实施 CSRFTokenProvider 时卡住了。
所以我点击了 Togglz API 到 enable/disable 一个功能。 return 200 OK,内容 HTML(与 togglz 控制台的索引页类似)。
启用
curl --location --request POST '{host}/{context_path}/togglz-console/edit?f=FEATURE_ONE&enabled=enabled'
禁用
curl --location --request POST '{host}/{context_path}/togglz-console/edit?f=FEATURE_ONE'
application.yml
...
togglz:
console:
enabled: true
path: /togglz-console
secured: false
use-management-port: false
features:
FEATURE_ONE:
enabled: true
build.gradle
...
implementation "org.togglz:togglz-spring-boot-starter:2.6.1.Final"
implementation "org.togglz:togglz-console:2.6.1.Final"
implementation "org.togglz:togglz-spring-security:2.6.1.Final"
注意:这不是回答上述问题,但可以作为替代方案
更新:我遇到这个是因为我的 InputStream 已被读取(由过滤器 bean)并且只读取一次
我已经通过属性文件禁用了 togglz 中的 csrf 保护:
togglz.console.validate-c-s-r-f-token=false
如果您使用 yaml 而不是属性文件,该文件应如下所示:
...
togglz:
console:
validate-c-s-r-f-token: false
您应该注意,不建议禁用 csrf 令牌验证,因为它会降低应用程序的安全性。
我已经在我的 spring 启动应用程序中实现了 togglz。我什至可以访问 Togglz 控制台,并且我已经使用 FeatureManager 测试了限制。但是,如果我转到 togglz 控制台并尝试更改激活策略或 enable/disable 功能,我会收到 403 Forbidden 错误页面。
换句话说,我可以访问 /togglz/index 但我不能 access/call /togglz/edit
在我的 WebMvcConfigurer class:
@Bean
public FilterRegistrationBean<TogglzFilter> togglzRegistration() {
FilterRegistrationBean<TogglzFilter> reg = new FilterRegistrationBean<>();
reg.setFilter(new TogglzFilter());
reg.addUrlPatterns("/*");
reg.setName("TogglzFilter");
return reg;
}
@Bean
public ServletRegistrationBean<TogglzConsoleServlet> togglzConsoleServlet() {
ServletRegistrationBean<TogglzConsoleServlet> reg = new ServletRegistrationBean<>();
reg.setServlet(new TogglzConsoleServlet());
reg.setName("TogglzConsoleServlet");
reg.addUrlMappings("/togglz/*");
return reg;
}
在我的 TogglzConfiguration 中:
@Component
public class TogglzConfiguration implements TogglzConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(TogglzConfiguration.class);
@Autowired
private ResourceLoader resourceLoader;
@Override
public Class<? extends Feature> getFeatureClass() {
return Features.class;
}
@Override
public StateRepository getStateRepository() {
try {
return new FileBasedStateRepository(
resourceLoader.getResource("classpath:/togglz.properties").getFile()
);
} catch (IOException ex) {
LOGGER.error(ex.getMessage(),ex);
throw new RuntimeException(ex);
}
}
@Override
public UserProvider getUserProvider() {
return new UserProvider() {
@Override
public FeatureUser getCurrentUser() {
return new SimpleFeatureUser("admin", true);
}
};
}
}
我的特点class:
public enum Features implements Feature {
@Label("Inventory Initiation")
@TestingUI
TESTING_UI_INITIATE_INVENTORY,
@Label("Random Warehouse Creation")
@TestingUI
TESTING_UI_CREATE_WAREHOUSE
;
public boolean isActive() {
return FeatureContext.getFeatureManager().isActive(this);
}
}
togglz application.yml
你有什么配置?您很可能在此处遗漏了 secure: false
:
togglz:
enabled: true
console:
enabled: true
secured: false
您似乎在应用程序中使用了某种 CSRF 保护。至少这可以解释为什么只有 POST 个请求被破坏。
Togglz 控制台提供了一个 SPI,用于获取需要嵌入表单的 CSRF 令牌:
Togglz 支持 Spring 安全 CSRF 保护:
Togglz 正在使用 JDK 的 ServiceLoader 工具来查找提供程序。因此,在 Spring 安全性的情况下,只有一个引用实现的文件 class:
所以如果你想将一些第 3 方 CSRF 保护框架与 Togglz 集成,你必须:
- 实施
CSRFTokenProvider
- 将文件
META-INF/services/org.togglz.servlet.spi.CSRFTokenProvider
添加到您的 class 路径并向其添加实现 class 的完全限定 class 名称。
这里也一样。由于我是 Java 和 Spring 的新手,所以我在尝试从 @chkal 解决方案实施 CSRFTokenProvider 时卡住了。
所以我点击了 Togglz API 到 enable/disable 一个功能。 return 200 OK,内容 HTML(与 togglz 控制台的索引页类似)。
启用
curl --location --request POST '{host}/{context_path}/togglz-console/edit?f=FEATURE_ONE&enabled=enabled'
禁用
curl --location --request POST '{host}/{context_path}/togglz-console/edit?f=FEATURE_ONE'
application.yml
...
togglz:
console:
enabled: true
path: /togglz-console
secured: false
use-management-port: false
features:
FEATURE_ONE:
enabled: true
build.gradle
...
implementation "org.togglz:togglz-spring-boot-starter:2.6.1.Final"
implementation "org.togglz:togglz-console:2.6.1.Final"
implementation "org.togglz:togglz-spring-security:2.6.1.Final"
注意:这不是回答上述问题,但可以作为替代方案
更新:我遇到这个是因为我的 InputStream 已被读取(由过滤器 bean)并且只读取一次
我已经通过属性文件禁用了 togglz 中的 csrf 保护:
togglz.console.validate-c-s-r-f-token=false
如果您使用 yaml 而不是属性文件,该文件应如下所示:
...
togglz:
console:
validate-c-s-r-f-token: false
您应该注意,不建议禁用 csrf 令牌验证,因为它会降低应用程序的安全性。