J'essaie de configurer une annotation de sécurité de méthode à l'aide de @Secured ("ADMIN") (sans XML, uniquement la configuration Java, Spring Boot). Mais l'accès via les rôles ne fonctionne pas.
Configuration de sécurité:
@Configuration
@EnableWebSecurity
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
.....
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated().and()
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
.....
}
Je veux restreindre l'accès à la méthode du contrôleur:
@RestController
@RequestMapping("/api/groups")
public class GroupController {
@Autowired
private GroupService groupService;
@Secured("ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}
}
Restreindre l'accès par l'URL fonctionne, avec:
.antMatchers("/api/**").hasAuthority("ADMIN")
Peut-être que j'ai oublié de spécifier que je veux restreindre par les rôles?
UPD: Selon les règles, sur quelle couche doit être @PreAuthorize("hasRole('ADMIN')")
dans la couche contrôleur ou dans la couche service?
Ce problème a été résolu.
J'ajoute @EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
}
Et dans le contrôleur, j'ai changé @Secured("ADMIN")
en @PreAuthorize("hasRole('ADMIN')")
Veuillez ajouter ceci
@EnableGlobalMethodSecurity(securedEnabled = true)
Cet élément est utilisé pour activer la sécurité basée sur les annotations dans votre application (en définissant les attributs appropriés), ainsi que pour regrouper les déclarations de coupure de sécurité qui seront appliquées à l'ensemble du contexte de votre application, spécifiquement pour @Secured
. le code devrait ressembler à ceci
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..
Il peut y avoir de nombreuses raisons pour lesquelles la sécurité de méthode sur un contrôleur ne fonctionne pas.
D'abord parce que ce n'est jamais cité en exemple dans le manuel Spring Security ... plaisanter mais il peut être difficile de prendre des outils Spring où ils ne veulent pas aller.
Plus sérieusement, vous devriez activer la sécurité des méthodes, comme l'a déjà dit @Mudassar. Le manuel dit:
Nous pouvons activer la sécurité basée sur les annotations à l'aide de l'annotation @EnableGlobalMethodSecurity
sur n'importe quelle instance @Configuration
. Par exemple, les éléments suivants activeraient l’annotation @Secured
de Spring Security.
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
// ...
}
Notez que la réponse de Mudassar est correcte jusque là.
Mais la sécurité des méthodes est basée sur AOP, qui utilise par défaut le proxy JDK sur interfaces . C'est la raison pour laquelle tous les exemples appliquent la sécurité de méthode sur la couche service, car les classes de service sont normalement injectées dans les contrôleurs en tant qu'interfaces.
Vous pouvez bien sûr l’utiliser sur la couche contrôleur, mais:
@Secured
La règle que j'essaie de suivre est la suivante:
Je sais que ce fil est assez ancien et ma réponse fait allusion à des parties des réponses de différentes personnes dans ce fil; mais voici une liste combinée de pièges et de réponses:
Voici une partie d'un exemple de travail Kotlin:
@RestController
@RequestMapping("api/v1")
open class DiagnosticsController {
@Autowired
lateinit var systemDao : SystemDao
@RequestMapping("ping", method = arrayOf(RequestMethod.GET))
@Secured("ROLE_ADMIN")
open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ...
}
et
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
Cordialement
Vous devez utiliser @secured (ROLE_ADMIN) au lieu de @secured (ADMIN). Vous devez écrire "ROLE_" avant de votre nom de rôle. Veuillez trouver l'exemple mentionné ci-dessous, qui s'assure que seul un utilisateur avec un rôle Admin peut accéder à la méthode list ().
@RestController
@RequestMapping("/api/groups")
public class GroupController {
@Autowired
private GroupService groupService;
@Secured("ROLE_ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}
}
Je veux partager ma décision, peut-être que cela sera utile.
Used spring mvc + spring security , version 4.2.9.RELEASE
Par exemple, j'ai un service avec la méthode annotée @Secured
@Secured("ACTION_USER_LIST_VIEW")
List<User> getUsersList();
Mais cela n'a pas fonctionné, car GlobalMethodSecurityConfiguration possède une méthode interne.
protected AccessDecisionManager accessDecisionManager()
dans lequel initialisé new RoleVoter()
avec rolePrefix = "ROLE_";
par défaut (il est impossible d'utiliser des beans pour définir votre rolePrefix)} qui nous donne des annotations inopérantes, car RoleVoter attend une valeur d'annotation commençant par ROLE_ '
Pour résoudre ce problème, je remplace GlobalMethodSecurityConfiguration like this
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
expressionAdvice.setExpressionHandler(getExpressionHandler());
decisionVoters.add(getRoleVoter());
decisionVoters.add(new AuthenticatedVoter());
return new AffirmativeBased(decisionVoters);
}
private RoleVoter getRoleVoter() {
RoleVoter e = new RoleVoter();
e.setRolePrefix("");
return e;
}
}
Vous devriez peut-être enregistrer votre AppSecurityConfiguration dans le même contexte que WebMvcConfig (qui étend WebMvcConfigurerAdapter).
AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
mvcContext.register(WebMvcConfig.class, SecurityConfig.class);