Mat*_*ble 11 spring spring-security spring-java-config
我正在尝试删除Spring Security中的"ROLE_"前缀.我尝试的第一件事是:
http.servletApi().rolePrefix("");
Run Code Online (Sandbox Code Playgroud)
这没用,所以我尝试BeanPostProcessor按http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-中的建议创建一个jc.html#m3to4-role-prefixing-disable.那也行不通.
最后,我尝试创建自己的SecurityExpressionHandler:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.expressionHandler(webExpressionHandler())
.antMatchers("/restricted").fullyAuthenticated()
.antMatchers("/foo").hasRole("mycustomrolename")
.antMatchers("/**").permitAll();
}
private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");
return defaultWebSecurityExpressionHandler;
}
Run Code Online (Sandbox Code Playgroud)
但是,这也不起作用.如果我使用"hasAuthority(roleName)"而不是hasRole,它按预期工作.
是否可以从Spring Security的hasRole检查中删除ROLE_前缀?
小智 19
从Spring 4.2开始,您可以使用单个bean定义前缀,如下所述:https://github.com/spring-projects/spring-security/issues/4134
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
}
Run Code Online (Sandbox Code Playgroud)
XML版本:
<beans:bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
<beans:constructor-arg value="" />
</beans:bean>
Run Code Online (Sandbox Code Playgroud)
以下配置适用于我.
@Override
public void configure(WebSecurity web) throws Exception {
web.expressionHandler(new DefaultWebSecurityExpressionHandler() {
@Override
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
root.setDefaultRolePrefix(""); //remove the prefix ROLE_
return root;
}
});
}
Run Code Online (Sandbox Code Playgroud)
它出现的新GrantedAuthorityDefaults会更改前缀DefaultWebSecurityExpressionHandler和DefaultMethodSecurityExpressionHandler,但不会修改RoleVoter.rolePrefix这是从设置@EnableGlobalMethodSecurity。
RoleVoter.rolePrefix 是用于@Secured("ADMIN")方法安全性的样式。
因此,除此之外GrantedAuthorityDefaults,我还必须添加此类CustomGlobalMethodSecurity以覆盖RoleVoter.
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class CustomGlobalMethodSecurity extends GlobalMethodSecurityConfiguration {
protected AccessDecisionManager accessDecisionManager() {
AffirmativeBased accessDecisionManager = (AffirmativeBased) super.accessDecisionManager();
//Remove the ROLE_ prefix from RoleVoter for @Secured and hasRole checks on methods
accessDecisionManager.getDecisionVoters().stream()
.filter(RoleVoter.class::isInstance)
.map(RoleVoter.class::cast)
.forEach(it -> it.setRolePrefix(""));
return accessDecisionManager;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在 4.2 之前并且正在使用所谓的投票者(如果您使用 @hasRole 等注释),那么您需要在上下文中定义以下 bean:
@Bean
public DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
defaultMethodSecurityExpressionHandler.setDefaultRolePrefix("");
return defaultMethodSecurityExpressionHandler;
}
@Bean
public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");
return defaultWebSecurityExpressionHandler;
}
Run Code Online (Sandbox Code Playgroud)
这些 bean 用于为拼写表达式创建求值上下文,并且它们的 defaultRolePrefix 设置为“ROLE_”。尽管这取决于您的用例。这个对我有用,而上面的没有。
编辑:回答有关 xml 配置的问题 -> 当然可以在 xml 中完成。java配置中所做的一切都可以写在xml配置中。这是示例(尽管我没有测试它,因此可能存在拼写错误或其他问题):
<bean id="defaultWebSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
<property name="defaultRolePrefix" value=""></property>
</bean>
<bean id="defaultMethodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="defaultRolePrefix" value=""></property>
</bean>
Run Code Online (Sandbox Code Playgroud)
如果您使用 Spring Boot 2,您可以创建此 bean 来覆盖RoteVoter前缀
@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("<anything you want>");
}
Run Code Online (Sandbox Code Playgroud)
它之所以有效,是因为当GlobalMethodSecurityConfiguration在方法GlobalMethodSecurityConfiguration.accessDecisionManager()中创建AccessDecisionManager时。这是代码片段,请注意grantAuthorityDefaults上的 null 检查
protected AccessDecisionManager accessDecisionManager() {
....
RoleVoter roleVoter = new RoleVoter();
GrantedAuthorityDefaults grantedAuthorityDefaults =
getSingleBeanOrNull(GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaults != null) {
roleVoter.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
}
decisionVoters.add(roleVoter);
decisionVoters.add(new AuthenticatedVoter());
return new AffirmativeBased(decisionVoters);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13613 次 |
| 最近记录: |