2016-06-30 59 views
4

我試圖刪除Spring安全中的「ROLE_」前綴。我想的第一件事是:如何使用JavaConfig從Spring Security中刪除ROLE_前綴?

http.servletApi().rolePrefix(""); 

那沒有工作,所以我試圖創建一個BeanPostProcessorhttp://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; 
    } 

不過,這並不能工作。如果我使用「hasAuthority(roleName)」而不是hasRole,它按預期工作。

是否可以從Spring Security的hasRole檢查中刪除ROLE_前綴?

+0

奇怪了'BeanPostProcessor'對我的作品(你沒有聲明它作爲一個'static' bean方法,其中包括了'PriorityOrdered',使其運行速度非常早?)和相同的表達處理器。我們還有一個'DefaultMethodSecurityExpressionHandler'DefaultMethodSecurityExpressionHandler'配置了前綴'null'。 –

+0

是的,我直接從文檔中複製了'BeanPostProcessor'的代碼。我試着將'@ Bean'放入Spring Security的'@ Configuration'類和'@ SpringBootApplication'類中。我添加了一個'System.out.println'來確保它在Spring Security之前被配置。 'hasAuthority'按預期工作,所以我想我會用它來代替。 –

+0

我們有一個非彈簧啓動應用程序。難道這是干擾,或者啓動的安全性在某種程度上還是配置較早? –

回答

4

以下配置適用於我。

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

如果你之前4.2和正在使用所謂的選民(你如果你使用像@hasRole等註釋),那麼你需要在上下文中定義如下豆:

@Bean 
public DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() { 
    DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler(); 
    defaultMethodSecurityExpressionHandler.setDefaultRolePrefix(""); 
    return defaultMethodSecurityExpressionHandler; 
} 

@Bean 
public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() { 
    DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler(); 
    defaultWebSecurityExpressionHandler.setDefaultRolePrefix(""); 
    return defaultWebSecurityExpressionHandler; 
} 

這些bean將用於創建法術表達式求值上下文和他們甲肝e 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> 
+0

在XML配置中是否有任何等價物? –

+0

我已經用xml config更新了我的答案......但正如我寫的,可能會有某種錯誤 - 我沒有對它進行測試。一般的規則是 - 在java配置中的所有東西都可以用xml來完成。 –

+0

xml配置不適合我。 –

0

它出現的新GrantedAuthorityDefaults將更改DefaultWebSecurityExpressionHandler和DefaultMethodSecurityExpressionHandler前綴,但它不修改從@EnableGlobalMethodSecurity設置的RoleVoter.rolePrefix

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; 
    } 
} 
相關問題