J'essaie de définir des règles d'accès au niveau de la méthode, mais cela ne fonctionne pas vraiment.
SecurityConfiguration
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("user").password("user").roles("USER").and().
withUser("admin").password("admin").roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/v2/**").authenticated()
.and()
.httpBasic()
.realmName("Secure api")
.and()
.csrf()
.disable();
}
}
ExampleController
@EnableAutoConfiguration
@RestController
@RequestMapping({"/v2/"})
public class ExampleController {
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
@RequestMapping(value = "/home", method = RequestMethod.GET)
String home() {
return "Hello World";
}
}
Chaque fois que j'essaie d'accéder à/v2/home en utilisant user:user
, il s'exécute correctement. Ne devrait-il pas me donner une erreur d'accès refusé en raison du fait que "l'utilisateur" n'a pas ROLE_ADMIN
?
Je pense en fait à abandonner les règles d'accès au niveau de la méthode et à m'en tenir aux règles http (), mais je dois savoir pourquoi cela ne fonctionne pas pour moi.
Un problème courant lié à l'utilisation d'annotations PrePost sur des contrôleurs est que la sécurité de la méthode Spring est basée sur Spring AOP, implémentée par défaut avec des mandataires JDK.
Cela signifie que cela fonctionne bien sur la couche de service injectée dans la couche contrôleur en tant qu'interfaces, mais que cette dernière est ignorée sur la couche contrôleur car le contrôleur n'implémente généralement pas les interfaces.
Ce qui suit est juste mon avis:
Vous devez ajouter @EnableGlobalMethodSecurity(prePostEnabled = true)
dans votre WebSecurityConfig.
Vous pouvez le trouver ici: http://www.baeldung.com/spring-security-expressions-basic
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
J'ai eu un problème similaire et ce qui suit l'a résolu:
1) Je devais rendre ma méthode publique (c'est-à-dire rendre votre méthode home () public)
2) Je dois utiliser hasRole au lieu de hasAuthority
Pour que cela fonctionne sur la couche contrôleur ..__, j'ai dû mettre @EnableAspectJAutoProxy sur ma classe de configuration . Exemple:
@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "com.abc.fraud.ts.userservices.web.controller" })
public class WebConfig extends WebMvcConfigurerAdapter{
}
Il y a deux façons différentes d’utiliser ceci: l’une consiste à préfixer l’autre et l’autre n’est pas . Et vous pouvez peut-être remplacer @PreAuthorize("hasAuthority('ROLE_ADMIN')")
par @PreAuthorize("hasAuthority('ADMIN')")
, ce qui sera correct.
est le suivant: code source @PreAuthorize
.
private String defaultRolePrefix = "ROLE_";
public final boolean hasAuthority(String authority) {
return hasAnyAuthority(authority);
}
public final boolean hasAnyAuthority(String... authorities) {
return hasAnyAuthorityName(null, authorities);
}
public final boolean hasRole(String role) {
return hasAnyRole(role);
}
public final boolean hasAnyRole(String... roles) {
return hasAnyAuthorityName(defaultRolePrefix, roles);
}
Si vous avez un fichier de contexte xml pour vos beans de sécurité et un fichier distinct pour votre contexte web/servlet, vous devez également ajouter:
<security:global-method-security pre-post-annotations="enabled"/>
à votre contexte web-context.xml/servlet. Ce n'est pas suffisant pour simplement l'ajouter dans le contexte de sécurité xml.
Ce n'est pas hérité dans des contextes enfants.
HTH