2014-10-30 16 views
9

Ich versuche, hierarchische Rollen in meiner Spring Boot-App ohne Erfolg einzurichten. Ich habe alles, was an verschiedenen Stellen im Internet gesagt wurde, getan. Aber mit keiner von ihnen konnte ich das Problem lösen.Spring Boot + Spring Security + Hierarchische Rollen

Hier ist der Code meiner SecurityConfig-Klasse. Wenn ich mich mit einem Benutzer mit ROLE_ADMIN in der App anmelde, sollte es in der Lage sein, Daten von '/ users' abzurufen, aber momentan erhalte ich eine Zugriff verweigert-Ausnahme. Wenn der Benutzer den ROLE_USER-Berechtigungsnachweis hat, funktioniert es einwandfrei. Kann mir jemand helfen, herauszufinden, was fehlschlägt? Vielen Dank im Voraus.

@Configuration 
@EnableWebMvcSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private SigpaUserDetailsService userDetailsService; 

    @Bean 
    public RoleHierarchyImpl roleHierarchy() { 
     RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl(); 
     roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER"); 
     return roleHierarchy; 
    } 

    @Bean 
    public RoleHierarchyVoter roleVoter() {  
     return new RoleHierarchyVoter(roleHierarchy()); 
    } 

    @Bean 
    public DefaultWebSecurityExpressionHandler expressionHandler(){ 
     DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler(); 
     expressionHandler.setRoleHierarchy(roleHierarchy()); 
     return expressionHandler; 
    } 

    @Bean 
    @SuppressWarnings(value = { "rawtypes" }) 
    public AffirmativeBased accessDecisionManager() {  
     List<AccessDecisionVoter> decisionVoters = new ArrayList<AccessDecisionVoter>(); 
     WebExpressionVoter webExpressionVoter = new WebExpressionVoter(); 
     webExpressionVoter.setExpressionHandler(expressionHandler()); 
     decisionVoters.add(webExpressionVoter); 
     decisionVoters.add(roleVoter()); 
     return new AffirmativeBased(decisionVoters); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
      .accessDecisionManager(accessDecisionManager()) 
      .expressionHandler(expressionHandler()) 
      .antMatchers("https://stackoverflow.com/users/**") 
       .access("hasRole('ROLE_USER')") 
      .anyRequest().authenticated(); 
     http 
      .formLogin() 
       .loginPage("/login").permitAll() 
       .and() 
      .logout() 
       .permitAll(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder registry) 
      throws Exception { 
     registry.userDetailsService(userDetailsService); 
    } 
} 

Update: Hier ist der Code mit Ihrem Vorschlag aktualisiert, aber immer noch nicht funktioniert.

Antwort

3

Sie müssen die Rollenhierarchie im Webausdruck-Voter festlegen. Etwas wie:

DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler(); 
expressionHandler.setRoleHierarchy(roleHierarchy); 
webExpressionVoter.setExpressionHandler(expressionHandler); 

Update: Sie könnten auch versuchen, die der obige Ausdruck Handler wie diese Einstellung:

http 
    .authorizeRequests() 
    .expressionHandler(expressionHandler) 
    ... 
+0

Es funktioniert nicht so. Ich bekomme immer noch die gleiche Ausnahme für Zugriff verweigert – Mario

+0

@Mario Versuchen Sie mein Update. – holmis83

+0

Das habe ich gestern schon gemacht ... Ich habe keine Ahnung, warum es nicht funktioniert, weil ich alles ohne Erfolg getan habe. – Mario

3

Sie haben die Rolle Hierarchie auf der MethodSecurityExpressionHandler einzustellen:

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public static class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration { 
    @Autowired 
    private RoleHierarchy roleHierarchy; 

    @Override 
    protected MethodSecurityExpressionHandler createExpressionHandler() { 
     final DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler(); 
     handler.setRoleHierarchy(this.roleHierarchy); 
     return handler; 
    } 
} 

Weitere Informationen finden Sie unter Javadoc for @EnableGlobalMethodSecurity. Besonders zu beachten: , dass EnableGlobalMethodSecurity noch in der Klasse enthalten sein muss, die GlobalMethodSecurityConfiguration erweitert, um die Einstellungen zu bestimmen.

7

Ich bin gerade durch diese Einrichtung gegangen, also werde ich euch auf jeden Fall zum Laufen bringen. Hier ist der Deal:

Sie brachten diese Annotation @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true), aber zeigte keinen Code zu verwenden Pre/Post Autorize/Filter, so dass ich nicht weiß, ob Sie es wirklich brauchen.

  1. Wenn Sie nicht diese Klasse benötigen/Methode Level-Sicherheit/Filterung dann alles, was Sie tun müssen, ist:

    @Bean 
    public RoleHierarchyImpl roleHierarchy() { 
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl(); 
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER"); 
        return roleHierarchy; 
    } 
    

und

 private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() { 
      DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler(); 
      defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy()); 
      return defaultWebSecurityExpressionHandler; 
     } 

http 
     .authorizeRequests() 
     .expressionHandler(webExpressionHandler()) 

Sie don‘ t müssen Sie mit Ihrem eigenen accessDecisionManager überschreiben, wenn Sie nur eine Rollenhierarchie einführen müssen.

  1. Wenn Sie auch Sicherheit auf Klassen-/Methodenebene benötigen, d.mit PreAuthorize, PostAuthorize, PreFilter, PostFilter auf Ihren Methoden/Klassen erstellen Sie dann auch eine @Configuration wie dies in Ihrem Classpath (und die @EnableGlobalMethodSecurity Anmerkung aus Ihrer GlobalMethodSecurityConfig Klasse entfernen):

    @Configuration 
    @EnableGlobalMethodSecurity(prePostEnabled=true) 
    public class AnyNameYouLike extends GlobalMethodSecurityConfiguration { 
    
    @Resource 
    private RoleHierarchy roleHierarchy; 
    
    @Override 
    protected MethodSecurityExpressionHandler createExpressionHandler() { 
        DefaultMethodSecurityExpressionHandler expressionHandler = (DefaultMethodSecurityExpressionHandler) super.createExpressionHandler(); 
        expressionHandler.setRoleHierarchy(roleHierarchy); 
        return expressionHandler; 
    } 
    

    }

Ich würde die Benennen Sie GlobalMethodSecurityConfig mit dieser neuen Klasse und ändern Sie Ihre aktuelle GlobalMethodSecurityConfig-Klasse in WebSecurityConfig oder etwas, das angibt, dass es sich um die Sicherheitseinstellung für die Webebene handelt.

Ich definiere die RoleHierarchy Bean in der webSecurityConfig und injizieren/verwenden Sie es in der globalMethodSecurityConfig, aber Sie können das tun, wie Sie möchten, solange Sie nicht 2 Bohnen unnötig erstellen.

Hoffe, das hilft.

+0

Hallo, vielen Dank für Ihre Antwort! Leider lässt Spring mich '@ EnableGlobalMethodSecurity' Annotation nicht aus meiner' WebSecurityConfig' Klasse entfernen - ich bekomme 'IllegalArgumentException: Ein ServletContext ist erforderlich, um die Standard-Servlet-Behandlung zu konfigurieren. Jede Hilfe geschätzt – kiedysktos

+0

OK, ich habe eine Lösung gefunden. Sieht so aus, als ob dein Rat in Punkt 2 nicht so gut war, da es für mich andersherum funktioniert. Siehe eine Antwort hier: http://StackOverflow.com/Questions/43468285/springboot-method-based-hierarchical-roles-security-servletcontext-is-require/43473615#43473615 – kiedysktos

0

Aktivieren der Sicherheit auf Methodenebene (z. B. @EnableGlobalMethodSecurity (prePostEnabled = true)) zusammen mit unterstützender Hierarchical-Rolle auf WebSecurityConfigurerAdapter.

1.Nur müssen Sie die RoleHierarchy für eine andere mit @Bean annotierte Klasse trennen. 2.Eingeben Sie sie mit @Autowired auf WebSecurityConfigurerAdapter. Es funktioniert einwandfrei bei meinen Projekten.

Bitte schauen Sie in meinen Code.

WeSecurityConfig.class

@Configuration 
    @EnableGlobalMethodSecurity(prePostEnabled = true) 
    @EnableWebSecurity 
    public class AppSecurityConfig extends WebSecurityConfigurerAdapter{ 
    @Autowired 
    private RoleHierarchy roleHierarchy; 

    private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() { 
    DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler  = new DefaultWebSecurityExpressionHandler(); 
    defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy); 
    return defaultWebSecurityExpressionHandler; 
} 


@Override 
public void configure(WebSecurity web) throws Exception{ 
    super.configure(web); 
    web.ignoring().antMatchers("/static/**"); 
} 

@Override 
public void configure(HttpSecurity http) throws Exception{ 
    http. 
      authorizeRequests() 
      .expressionHandler(webExpressionHandler()) 
      .antMatchers("/static/**","/bower_components/**","/").permitAll() 
      .antMatchers("/user/login","/user/login?error").anonymous() 
      .anyRequest().authenticated() 
      .and() 
      .formLogin().loginPage("/user/login").passwordParameter("password").usernameParameter("username") 
      .defaultSuccessUrl("/") 
      .permitAll() 
      .and() 
      .logout().logoutUrl("/user/logout") 
      .logoutSuccessUrl("/user/login?logout") 
      .and().csrf(); 

} 


@Override 
public void configure(AuthenticationManagerBuilder auth) throws Exception{ 
    auth.authenticationProvider(daoAuthenticationProvider()); 
} 

public DaoAuthenticationProvider daoAuthenticationProvider(){ 
    final DaoAuthenticationProvider auth = new DaoAuthenticationProvider(); 
    auth.setUserDetailsService(userDetailService); 
    auth.setPasswordEncoder(passwordEncoder); 
    return auth; 
} 

}

BeanConfiguration.class

@Configuration 
public class BeanConfiguration { 

@Bean 
public RoleHierarchy roleHierarchy(){ 
    RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl(); 
    /* tricks lies here */ 
    roleHierarchy.setHierarchy("ROLE_SUPREME > ROLE_ADMIN ROLE_ADMIN > ROLE_OPERATOR ROLE_OPERATOR > ROLE_GUEST"); 
    return roleHierarchy; 
} 

}

hoffen, dass es Ihnen hilft.

Verwandte Themen