1

Ich war auf der Suche nach einem konkreten, ernsthaften und vollständigen Beispiel zur Verwendung der Spring-Sicherheit in einer Spring Boot-Anwendung, die Spring data repositories für den Zugriff auf die Datenbank verwendet Abfrage über registrierte Benutzer.Spring Security in Verbindung mit Spring Repositories zum Sichern und Authentifizieren verschiedener Teile einer Website

Ich habe gesehen, dass es leicht durch Überschreiben der configure Methode eine Reihe von Web-Seiten mit Spring Security geschützt, zum Beispiel mit den folgenden Optionen:

http.authorizeRequests() 
    .antMatchers("/", "/css/**", "/js/**", "/vendor/**", "/templates/**") 
    .permitAll() 
    .anyRequest() 
    .authenticated() 
    .and() 
    .formLogin() 
    .loginPage("/login") 
    .permitAll() 
    .and() 
    .logout() 
    .permitAll(); 

Dieser Code schützt Anwender zum Beispiel von http://localhost:3000/home/users/ Zugriff, aber ermöglicht dann Zugriff auf http://localhost:3000/login oder einfach http://localhost:3000.

Ich habe gelesen über Frühjahr Sicherheit, aber ich kann nicht erhalten, wie kann ich die verschiedenen Teile einer Anwendung schützen, zum Beispiel, wenn ein Benutzer auf der Website angemeldet ist, und verbieten ihm den Zugriff von Beispiel http://localhost:3000/home/users/another_user, und im Allgemeinen den Zugriff eines angemeldeten Benutzers auf alle Teile der Website zu steuern.

Ich verwende Spring data repositories, um Daten der Datenbank über die Entitäten zu manipulieren.

Kennen Sie ein Beispiel, das Spring-Sicherheit in Verbindung mit Spring-Repositories (und ggf. anderen Tools) verwendet, um verschiedene Teile einer Website zu schützen (und zu authentifizieren)? Ein (Video-) Tutorial kann ebenfalls nützlich sein.

Danke für jede Hilfe.

Hinweis: Ich habe auf der sagan Website Repository gesucht, aber es ist ziemlich komplex, zu verstehen, was los ist ...

Antwort

1

Diese Access Control genannt wird, oder „Domain-Objektsicherheit“ in Spring Security.

http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#domain-acls

Sie haben eine Menge zu lesen bekam zu tun!

Wahrscheinlich möchten Sie es mit Spring Data JPA kombinieren, so dass SDJ nur die Datensätze zurückgibt, die es sollte. Ein Beispiel hier:

https://github.com/spring-projects/spring-data-examples/tree/master/jpa/security

Grundsätzlich Sie gehen einige „Reihe Besitzer“ weitere Infos auf die Tabellen zu Hinzufügen, und immer SDJ und SS zusammenarbeiten, Zugang zu kontrollieren, wie:

@Query("select o from BusinessObject o where o.owner.emailAddress like ?#{hasRole('ROLE_ADMIN') ? '%' : principal.emailAddress}") 
List<BusinessObject> findBusinessObjectsForCurrentUser(); 

Eine Alternative, um einen Datenbankserver, der Row Security unterstützt, wie PostgreSQL, zu verwenden und Ihre Zugriffskontrolle direkt in der Datenbank zu verwalten.

1

Wie oben erwähnt, sind ACLs eine Option, aber eine alternative und möglicherweise einfachere Lösung könnte darin bestehen, Sicherheit auf Methodenebene anzuwenden.

Siehe Abschnitt 15.3.

https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html

Also angenommen, Sie haben eine URL/users/123, wo 123 der aktuelle Benutzer und die Delegierten zu einer Service-Layer-Methode der Benutzer laden dann, wie verhindere ich den Benutzer von der URL Manipulation und Sehen von Daten, die z/Benutzer/456.

Ein Ansatz ist Methode Level-Sicherheit über die @PostAuthorize Anmerkung gelten:

@PostAuthorize("hasPermission(returnObject, null)") 
public User findById(Long id) { 
    return repository.findOne(id); 
} 

Die Sicherheitskontrollen übertragen auf eine Implementierung von org.springframework.security.access.PermissionEvaluator

Eine Implementierung könnten, sind wie folgt aussehen:

public class BasePermissionsEvaluator implements PermissionEvaluator { 

    public boolean hasPermission(Authentication authentication, Object domainObject) { 
     return hasPermission(authentication, domainObject, null); 
    } 

    @Override 
    public boolean hasPermission(Authentication authentication, Object domainObject, Object permission) { 
     boolean hasPermission = true; 

     //User is my custom class representing a logged in user 
     //UserEntity is my custom interface implemented by entities associated with specific user 
     //If user is an Admin allow access 
     //Otherwise allow access if logged in user 'owns' the DomainObject instance 
     User user = (User) authentication.getPrincipal(); 

     if(! user.isAdmin()){ 
      if (domainObject instanceof UserEntity) { 
       User owner = ((UserEntity) domainObject).getOwner(); 
       hasPermission = user.equals(owner); 
      } 
     } 

     return hasPermission; 
    } 

    @Override 
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, 
      Object permission) { 
     return false; 
    } 
} 

Konfiguration des PermissionEvaluator sieht in XML wie folgt aus, so Sie würden d müssen Java Config konvertieren:

<security:global-method-security 
    pre-post-annotations="enabled"> 
     <security:expression-handler ref="expressionHandler"/> 
</security:global-method-security> 

<bean id="expressionHandler" 
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> 
    <property name="permissionEvaluator" ref="permissionEvaluator" /> 
</bean> 

<bean id="permissionEvaluator" class="com.mycompany.BasePermissionsEvaluator" /> 

In der folgenden Übersicht Umwandlung der XML-Konfigurations auf Java config:

https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/#custom-method-security

So in Ihre bestehende Sicherheitskonfiguration Klasse sieht es aus wie Sie hinzufügen würde:

+0

Entschuldigung dafür, dass Sie lange keine Rückmeldung zu Ihrer Antwort gegeben haben, aber ich fand alle diese Konzepte nicht trivial und seltsam aus meiner Sicht, wahrscheinlich, weil ich mit diesen Dingen im Allgemeinen neu bin, obwohl ich 'pass.js' bereits einmal mit Node und Express benutzt habe. Ich hätte eine erste Frage oder Zweifel. Warum sollten wir diese 'PostAuthorize'-Sache auf eine Repository-Methode anwenden? Liegt das daran, dass wir in den Spring-Controllern diese spezifische Repository-Methode (die die Annotation enthält) verwenden können, die einige Prüfungen durchführt? – nbro

+0

Es scheint, dass Spring Security alles nur für die einfachen Fälle sehr komplex macht ... Von dem, was ich mit pass.js erinnere, war es viel einfacher, die Sicherheit für die Anwendung einzurichten, aber ich kann mich auch irren oder, oder Zeit, ich hatte nicht die ganze Perspektive von dem, was ich tat ... – nbro

+0

Ich habe es auf das Repository gelegt, weil das Repository eine Instanz des Domainobjekts zurückgibt, das im Evaluator benötigt wird. Ich kann die Bewertung nicht sehr gut auf den Controller anwenden, weil das etwas ganz anderes zurückgeben wird. Sie können Sicherheit überall anwenden, aber dieser spezielle Fall überprüft das Domänenobjekt, das von einer Methode zurückgegeben wird, so dass Repository oder Service-Layer geeignet sind. Der angemeldete Benutzer hat eine Entität angefordert. Erlaube den Zugriff, wenn der angemeldete Benutzer das angeforderte Objekt "besitzt" oder eine Admin-Rolle hat, andernfalls den Zugriff verweigern. –