Spring Security: benutzerdefinierte Benutzerdetails

8

Ich bin ziemlich neu in Java und Spring 3 (verwendet in den letzten 8 Jahren hauptsächlich PHP). Ich habe Spring Security 3 bekommen, um mit allen Standard-Benutzer-Details und UserDetailsService zu arbeiten, und ich weiß, dass ich auf den Benutzernamen des angemeldeten Benutzers in einem Controller zugreifen kann, indem ich verwende:

%Vor%

Aber es gibt zwei Probleme, die ich nicht herausfinden kann:

  1. Es gibt viele andere Benutzerdetails, die ich gespeichert haben möchte, wenn sich ein Benutzer anmeldet (wie DOB, Geschlecht, etc.) und später über die Controller zugänglich sein soll. Was muss ich tun, damit das erstellte userDetails-Objekt meine benutzerdefinierten Felder enthält?

  2. Ich rufe bereits an "HttpSession session = request.getSession (true);" an der Spitze jeder meiner Methoden in meinem Controller. Ist es möglich, die userDetails des angemeldeten Benutzers bei der Anmeldung in einer Sitzung zu speichern, so dass ich auch nicht "Authentication auth = SecurityContextHolder.getContext (). GetAuthentication ();" aufrufen muss am Anfang jeder Methode?

Security-applicationContext.xml:

%Vor%

login.jsp:

%Vor%     
Felix 15.05.2012, 19:42
quelle

3 Antworten

19

In dieser Frage geht sehr viel los. Ich werde versuchen, es in Stücke zu gehen ...

Q # 1: Es gibt ein paar mögliche Ansätze hier.

Vorgehensweise # 1: Wenn Sie andere Attribute zu Ihrem UserDetails-Objekt hinzufügen möchten, sollten Sie eine eigene alternative Implementierung der UserDetails-Schnittstelle bereitstellen, die diese Attribute zusammen mit den entsprechenden Gettern und Settors enthält. Dazu müssten Sie auch Ihre eigene alternative Implementierung der UserDetailsService-Schnittstelle bereitstellen. Diese Komponente müsste verstehen, wie diese zusätzlichen Attribute für den zugrunde liegenden Datenspeicher beibehalten werden, oder ob beim Lesen aus diesem Datenspeicher das Vervollständigen dieser zusätzlichen Attribute zu verstehen ist. Du würdest das alles so verkabeln:

%Vor%

Approach # 2: Wie bei mir finden Sie (insbesondere im Verlauf mehrerer Iterationen), dass Sie besser domänenspezifische Benutzer- / Kontodetails separat von Spring Security-spezifischen Benutzern erhalten /Kontodetails. Dies kann für Sie der Fall sein oder nicht. Aber wenn Sie bei diesem Ansatz irgendeine Weisheit finden, dann bleiben Sie bei dem Setup, das Sie gerade haben, und fügen Sie ein zusätzliches Benutzer- / Account-Domain-Objekt, entsprechendes Repository / DAO usw. hinzu. Wenn Sie den domänenspezifischen Benutzer / Konto, können Sie dies folgendermaßen tun:

%Vor%

Q # 2: Spring Security speichert die UserDetails automatisch in der Sitzung (es sei denn, Sie haben explizit Schritte unternommen, um dieses Verhalten zu überschreiben). Sie müssen das also nicht bei jeder Ihrer Controller-Methoden selbst machen. Das SecurityContextHolder-Objekt, mit dem Sie es zu tun haben, wird tatsächlich (mit SS) mit SecurityContext aufgefüllt, einschließlich des Authentifizierungsobjekts, UserDetails usw. zu Beginn jeder Anfrage. Dieser Kontext wird am Ende jeder Anfrage gelöscht, aber die Daten bleiben immer in der Sitzung.

Es ist jedoch erwähnenswert, dass es nicht wirklich eine großartige Übung ist, mit HttpServletRequest-, HttpSession-Objekten usw. in einem Spring MVC-Controller umzugehen, wenn Sie es vermeiden können. Der Frühling bietet fast immer sauberere, idiomatischere Mittel, um Dinge zu erreichen, ohne dass man dies tun muss. Der Vorteil wäre, dass die Signaturen und Logik der Controller-Methoden nicht mehr von Dingen abhängig sind, die in einem Komponententest (zB der HttpSession) schwer nachzuahmen sind und nicht von Ihren eigenen Domain-Objekten (oder Stubs / Mocks dieser Domain-Objekte) abhängig sind ). Dies erhöht die Testfähigkeit Ihrer Controller drastisch und erhöht somit die Wahrscheinlichkeit, dass Sie Ihre Controller tatsächlich testen. :)

Hoffe, das hilft einigen.

    
Kent Rancourt 15.05.2012, 20:26
quelle
2

Die Implementierung von Custom UserDetails ist meiner Meinung nach großartig, sollte aber nur für unveränderliche Eigenschaften Ihres Benutzers verwendet werden.

Sobald Ihr benutzerdefiniertes Benutzerobjekt UserDetails überschreibt, kann es nicht einfach geändert werden. Sie müssen ein vollständig neues Authentifizierungsobjekt mit den geänderten Details erstellen und das geänderte Objekt UserDetails nicht einfach in den Sicherheitskontext kleben.

In der Anwendung, die ich erstelle, habe ich dies erkannt und musste es neuarchitektonieren, so dass nach erfolgreicher Authentifizierung Details über den Benutzer, die sich mit jeder Anfrage ändern (aber ich möchte nicht von der db auf jedem neu laden Seitenlade) müssen separat in der Sitzung gehalten werden, aber immer noch nur zugänglich / änderbar nach einer Authentifizierungsprüfung.

Ich versuche herauszufinden, ob dieser in Ссылка erwähnte WebArgumentResolver eine bessere Lösung für meine Situation ist.

    
Marc Johnson 23.05.2012 02:28
quelle
1

Der direkte Zugriff auf die Sitzung ist ein wenig unübersichtlich und kann fehleranfällig sein. Wenn der Benutzer z. B. mit remember-me oder einem anderen Mechanismus authentifiziert wird, der keine Umleitung enthält, wird die Sitzung erst nach Abschluss dieser Anforderung ausgefüllt.

Ich würde eine benutzerdefinierte Accessor-Schnittstelle verwenden, um die Aufrufe in SecurityContextHolder zu verpacken. Siehe meine Antwort auf diese Frage .

    
Shaun the Sheep 15.05.2012 20:10
quelle

Tags und Links