2017-08-16 5 views
0

Ich möchte nur einem bestimmten Benutzer Zugriff auf ihre Änderungsseite erlauben.Benutzerdefinierte Methode in Spring Web Security

Zum Beispiel möchte ich Benutzer 3 die einzige in der Lage den Zugriff auf die URL:/user/3/bearbeiten

Dazu habe ich in meinem SecurityConfiguration.java gesetzt haben:

.authorizeRequests() 
.antMatchers("/user/{id}/edit").access("@MyClass.checkId(#id)"); 

MyClass.java ist die folgende:

@Component 
public class MyClass{ 


    public boolean checkId(Long id) { 
     if(id == SecurityUtils.getCurrentUserId()){ //I have this configured and working 
      return true; 
     } 
     return false; 
    } 
} 

Doch wenn gehen sie auf die folgende uRL: user/4/bearbeiten angemeldet als Benutzer 3 (diese Beispiele sind), kann ich nicht scheinen, um die CheckId Methode, und nichts eingeben passiert, und mein Seite lädt mit allem drin.

Haben Sie eine Idee? Ist antMatchers.access() der Weg zu gehen?

Vielen Dank für Ihre Zeit!

Antwort

1

Sie müssen zwei Klassen ableiten.

Zuerst stellen eine neue Methode Expression handler

<global-method-security> 
    <expression-handler ref="myMethodSecurityExpressionHandler"/> 
</global-method-security> 

myMethodSecurityExpressionHandler wird eine Unterklasse von DefaultMethodSecurityExpressionHandler sein, die createEvaluationContext überschreibt(), eine Unterklasse von MethodSecurityExpressionRoot auf der MethodSecurityEvaluationContext Einstellung.

Zum Beispiel:

@Override 
public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) { 
    MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(auth, mi, parameterNameDiscoverer); 
    MethodSecurityExpressionRoot root = new MyMethodSecurityExpressionRoot(auth); 
    root.setTrustResolver(trustResolver); 
    root.setPermissionEvaluator(permissionEvaluator); 
    root.setRoleHierarchy(roleHierarchy); 
    ctx.setRootObject(root); 

    return ctx; 
} 
+2

Danke für die Antwort, obwohl dies eine Kopie zu sein scheint -Paste dieser Antwort: https://Stackoverflow.com/a/6634438/5749754, Wort für Wort, das ist nicht cool für nicht erwähnen es! Aber ich danke dir wenigstens, dass ich gefunden habe, wonach ich gesucht habe ... –

0

Es gibt eine andere Lösung ist, und es kann auf eine sehr elegante Weise erreichen werden Expression-Based Access Control verwenden, für diesen Fall, dass Sie die @PreAuthorize Annotation verwenden können und in ihm den Hauptbenutzer-ID überprüfen. Zum Beispiel:

@PreAuthorize("#id == principal.userNumber") 
    @RequestMapping(method = RequestMethod.POST, value = "/user/{id}/edit") 
    public void userUpdate(Long id){ .. } 

Bitte nur sicherstellen, dass die Umsetzung der UserDetails Schnittstelle die userNumber Eigenschaft hat.

Sie mehr Informationen sehen über Expression-Based Access Control

Ein weiterer Ansatz ist es, die Principal Objekt in den Request-Handler Methode wie folgt zu injizieren:

@RequestMapping(method = RequestMethod.POST, value = "/user/{id}/edit") 
public void userUpdate(Long id, Principal myPrincipal){ 

    MyUserDetails user = (MyUserDetails) myPrincipal; 
    if (user.getUserNumber == id) { ... } 
    .... 
} 
Verwandte Themen