Sono abbastanza nuovo in Java e Spring 3 (usato principalmente PHP negli ultimi 8 anni). Ho ottenuto la sicurezza molla 3 a lavorare con tutti i UserDetails default e userDetailsService e so di poter accedere alla registrato nel nome utente dell'utente in un controller utilizzando:Spring Security: custom userdetails
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName(); //get logged in username
Ma ci sono due problemi non riesco a capire out:
ci sono un sacco di altri dettagli utente Vorrei memorizzato quando un utente accede (come data di nascita, sesso, ecc) e di essere accessibile tramite i controller più tardi. Cosa devo fare in modo che l'oggetto userDetails creato contenga i miei campi personalizzati?
Sto già chiamando "HttpSession session = request.getSession (true);" nella parte superiore di ciascuno dei miei metodi nel mio controller. È possibile memorizzare i dati utente dell'utente registrati in una sessione al momento dell'accesso, in modo che non sia necessario chiamare anche "Autenticazione auth = SecurityContextHolder.getContext(). GetAuthentication();" all'inizio di ogni metodo?
Security-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" />
Grazie Kent, è stato molto utile! Ci scusiamo per il casino, la prima volta che abbiamo programmato Spring. Mi piace l'approccio n. 2, dove inserirò quella riga di codice, all'inizio di ogni metodo? E suppongo che sulla base di tale domanda, se vado con quel secondo approccio è possibile memorizzare l'oggetto utente in modo che io non t necessario creare un nuovo oggetto utente e andare al db per gli stessi dati ogni volta? – Felix
La risposta è "dipende". Trovo che con l'approccio # 2, ho molto raramente bisogno di accedere all'account di un utente (dal punto di vista del dominio). Forse accedo solo a scopo di visualizzazione o modifica del loro "profilo". Se questo è il caso, vorrei solo leggere fino al datastore per queste informazioni quando è necessario. Se, tuttavia, è necessario accedere frequentemente agli attributi dell'utente (dal punto di vista del dominio, forse un attributo dell'oggetto utente deve apparire nell'intestazione ed è quindi necessario in ogni richiesta), allora probabilmente dovresti riconsiderare approccio # 1. –
Grazie Kent. Ho finito per fare una soluzione di tipo ibrido. Quando ho bisogno di un utente connesso, eseguo un metodo in un controller wrapper per ottenere i dati. Il metodo controlla se la sessione contiene un oggetto utente e se lo fa controlla se il nome utente dell'oggetto è uguale a quello del nome utente securityContext. In caso contrario (o se l'oggetto utente sessione è nullo) ottiene i dati utente dal database e archivia l'oggetto in sessione. Due istruzioni extra if, ma una chiamata al database in meno. – Felix