Ich bin ziemlich neu in Java und Spring 3 (in den letzten 8 Jahren in erster Linie PHP verwendet). Ich habe Frühjahr Sicherheit 3 bekommen mit allen Standard-Userdetails und userDetailsService zu arbeiten, und ich weiß, ich kann den Benutzernamen des angemeldeten Benutzers zuzugreifen in einer Steuerung durch den Einsatz:Spring Security: benutzerdefinierte Benutzerdetails
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName(); //get logged in username
Aber es gibt zwei Probleme, die ich verstehe nicht out:
Es gibt eine Menge anderer Benutzer Details würde ich gespeichert wie wenn sich ein Benutzer anmeldet (zB DOB, Geschlecht, etc.) und über die Regler später zugänglich zu sein. Was muss ich tun, damit das erstellte userDetails-Objekt meine benutzerdefinierten Felder enthält?
Ich rufe bereits "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?
Sicherheits applicationContext.xml:
<global-method-security secured-annotations="enabled"></global-method-security>
<http auto-config='true' access-denied-page="/access-denied.html">
<!-- NO RESTRICTIONS -->
<intercept-url pattern="/login.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/*.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- RESTRICTED PAGES -->
<intercept-url pattern="/admin/*.html" access="ROLE_ADMIN" />
<intercept-url pattern="/member/*.html" access="ROLE_ADMIN, ROLE_STAFF" />
<form-login login-page="/login.html"
login-processing-url="/loginProcess"
authentication-failure-url="/login.html?login_error=1"
default-target-url="/member/home.html" />
<logout logout-success-url="/login.html"/>
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource" authorities-by-username-query="SELECT U.username, UR.authority, U.userid FROM users U, userroles UR WHERE U.username=? AND U.roleid=UR.roleid LIMIT 1" />
<password-encoder hash="md5"/>
</authentication-provider>
</authentication-manager>
login.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<tiles:insertDefinition name="header" />
<tiles:insertDefinition name="menu" />
<tiles:insertDefinition name="prebody" />
<h1>Login</h1>
<c:if test="${not empty param.login_error}">
<font color="red"><c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.<br /><br /></font>
</c:if>
<form name="f" action="<c:url value='/loginProcess'/>" method="POST">
<table>
<tr><td>User:</td><td><input type='text' name='j_username' value='<c:if test="${not empty param.login_error}"><c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>' /></td></tr>
<tr><td>Password:</td><td><input type='password' name='j_password' /></td></tr>
<tr><td> </td><td><input type="checkbox" name="_spring_security_remember_me" /> Remember Me</td></tr>
<tr><td> </td><td><input name="submit" type="submit" value="Login" /></td></tr>
</table>
</form>
<tiles:insertDefinition name="postbody" />
<tiles:insertDefinition name="footer" />
Danke Kent, das war sehr hilfreich! Sorry für das Durcheinander, zum ersten Mal Codierung Frühling. Ich mag Approach # 2, wo würde ich diese Codezeile am Anfang jeder Methode platzieren? Und ich denke, basierend auf dieser Frage, wenn ich mit diesem zweiten Ansatz fortfahre, ist es möglich, das Benutzerobjekt so zu speichern, t müssen Sie ein neues Benutzerobjekt erstellen und jedes Mal zur Datenbank für die gleichen Daten wechseln? – Felix
Die Antwort lautet: "Es kommt darauf an." Ich finde, dass ich mit Ansatz Nr. 2 sehr selten auf ein Benutzerkonto zugreifen muss (aus einer Domänenperspektive). Vielleicht kann ich nur darauf zugreifen, um ihr "Profil" anzuzeigen oder zu bearbeiten. Wenn dies der Fall ist, würde ich diese Informationen nur dann im Datenspeicher durchlesen, wenn sie benötigt werden. Wenn Sie jedoch häufig auf Attribute des Benutzers zugreifen müssen (aus einer Domänenperspektive; möglicherweise muss ein Attribut des Benutzerobjekts in der Kopfzeile angezeigt werden und wird daher in jeder Anforderung benötigt), sollten Sie dies entweder erneut prüfen Annäherung # 1. –
Danke Kent. Am Ende habe ich eine hybride Lösung gemacht. Wenn ich den angemeldeten Benutzer brauche, führe ich eine Methode in einem Wrapper-Controller aus, um die Daten zu erhalten. Die Methode überprüft, ob die Sitzung ein Benutzerobjekt enthält. Wenn dies der Fall ist, wird überprüft, ob der Benutzername des Objekts dem des SecurityContext-Benutzernamens entspricht. Wenn nicht (oder wenn das Sitzungsbenutzerobjekt null ist), ruft es die Benutzerdaten aus der Datenbank ab und speichert das Objekt in der Sitzung. Zwei zusätzliche if-Anweisungen, aber 1 weniger Datenbankaufruf. – Felix