2016-06-30 20 views
4

Ich versuche, das "ROLE_" Präfix in Spring Security zu entfernen. Das erste, was ich versuchte, war:Wie entferne ich das Präfix ROLE_ von Spring Security mit JavaConfig?

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

, die nicht funktioniert, so dass ich versuchte, einen BeanPostProcessor zu schaffen, wie in http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-jc.html#m3to4-role-prefixing-disable vorgeschlagen. Das hat auch nicht funktioniert.

Schließlich habe ich versucht, meine eigene Schaffung 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; 
    } 

Doch dies funktioniert auch nicht. Wenn ich "hasAuthority (roleName)" anstelle von hasRole verwende, funktioniert es wie erwartet.

Ist es möglich, das ROLE_-Präfix aus der hasRole-Prüfung von Spring Security zu entfernen?

+0

Seltsam das 'BeanPostProcessor' funktioniert für mich (Sie es als eine Methode' static' Bohne tat erklären und enthalten die 'PriorityOrdered' so, dass es sehr früh läuft?) Und das gleiche gilt für die Expression Handler. Wir haben auch einen 'DefaultMethodSecurityExpressionHandler'DefaultMethodSecurityExpressionHandler', der mit dem Präfix'NULL' konfiguriert ist. –

+0

Ja, ich habe den Code für den 'BeanPostProcessor' direkt aus der Dokumentation kopiert. Ich habe versucht, die @ Bean in meiner '@ Configuration' Klasse für Spring Security und in meiner' @ SpringBootApplication' Klasse zu platzieren. Ich habe ein 'System.out.println' hinzugefügt, um sicherzustellen, dass es auch vor Spring Security konfiguriert wird. 'hasAuthority' funktioniert wie erwartet, also schätze ich, dass ich das stattdessen benutze. –

+0

Wir haben es in einer Nicht-Spring-Boot-Anwendung.Könnte es sein, dass das stört oder dass die Sicherheit des Bootes irgendwie noch früher konfiguriert ist? –

Antwort

4

Die folgende Konfiguration funktioniert für mich.

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

Ab Frühling 4.2 können Sie das Präfix mit einer einzigen Bohne definieren, wie hier beschrieben: https://github.com/spring-projects/spring-security/issues/4134

@Bean 
GrantedAuthorityDefaults grantedAuthorityDefaults() { 
    return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix 
} 
+1

Hat für mich nicht funktioniert –

1

Wenn Sie vor 4.2 und werden mit so genannten Wähler (Sie sind, wenn Sie verwenden Anmerkungen wie @hasRole etc), dann müssen Sie unter Bohnen im Kontext definieren:

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

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

Diese Bohnen werden verwendet, Auswertung Kontext für die Rechtschreib Ausdrücke zu erstellen und sie hav e ein defaultRolePrefix auf 'ROLE_' gesetzt. Es hängt zwar von Ihrem Anwendungsfall ab. Dieser hat für mich und darüber nicht funktioniert.

EDIT: Beantworten der Frage über XML-Konfiguration -> natürlich kann es in XML getan werden. Alles, was in java config erledigt wird, kann in der xml-Konfiguration geschrieben werden. Hier ist Beispiel (obwohl ich es nicht testen, so könnte es ein Tippfehler oder etwas sein):

<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

Gibt es eine Entsprechung in der XML-Konfiguration? –

+0

Ich habe meine Antwort mit xml config aktualisiert ... aber wie ich geschrieben habe, könnte es einen Fehler geben - ich habe es nicht getestet. Die allgemeine Regel ist - alles in Java Config kann auch in XML gemacht werden. –

+0

Die XML-Konfiguration funktioniert nicht für mich. –

0

Es die neue GrantedAuthorityDefaults erscheint das Präfix für die DefaultWebSecurityExpressionHandler und den DefaultMethodSecurityExpressionHandler ändern, aber es nicht ändert die RoleVoter.rolePrefix das von @EnableGlobalMethodSecurity eingerichtet wird.

Der RoleVoter.RolePrefix ist, was für @Secured("ADMIN") Stil der Methoden-Sicherheit verwendet wird.

Also zusammen mit der GrantedAuthorityDefaults, musste ich auch diese CustomGlobalMethodSecurity-Klasse hinzufügen, um die Standardeinstellungen für RoleVoter zu überschreiben.

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