diff --git a/core/src/main/java/org/keycloak/representations/AccessCode.java b/core/src/main/java/org/keycloak/representations/AccessCode.java index 9fe860e8c2..ef6120262a 100755 --- a/core/src/main/java/org/keycloak/representations/AccessCode.java +++ b/core/src/main/java/org/keycloak/representations/AccessCode.java @@ -11,15 +11,11 @@ public class AccessCode { protected String id; protected String clientId; protected String userId; - protected String usernameUsed; protected String state; protected String sessionState; protected String redirectUri; - protected boolean rememberMe; - protected String authMethod; protected int timestamp; - protected int expiration; - protected Set requiredActions; + protected Action action; protected Set requestedRoles; public String getId() { @@ -70,30 +66,6 @@ public class AccessCode { this.redirectUri = redirectUri; } - public boolean isRememberMe() { - return rememberMe; - } - - public void setRememberMe(boolean rememberMe) { - this.rememberMe = rememberMe; - } - - public String getAuthMethod() { - return authMethod; - } - - public void setAuthMethod(String authMethod) { - this.authMethod = authMethod; - } - - public int getExpiration() { - return expiration; - } - - public void setExpiration(int expiration) { - this.expiration = expiration; - } - public int getTimestamp() { return timestamp; } @@ -102,20 +74,12 @@ public class AccessCode { this.timestamp = timestamp; } - public Set getRequiredActions() { - return requiredActions; + public Action getAction() { + return action; } - public void setRequiredActions(Set requiredActions) { - this.requiredActions = requiredActions; - } - - public String getUsernameUsed() { - return usernameUsed; - } - - public void setUsernameUsed(String usernameUsed) { - this.usernameUsed = usernameUsed; + public void setAction(Action action) { + this.action = action; } public Set getRequestedRoles() { @@ -125,4 +89,13 @@ public class AccessCode { public void setRequestedRoles(Set requestedRoles) { this.requestedRoles = requestedRoles; } + + public static enum Action { + OAUTH_GRANT, + VERIFY_EMAIL, + UPDATE_PROFILE, + CONFIGURE_TOTP, + UPDATE_PASSWORD + } + } diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionModel.java b/model/api/src/main/java/org/keycloak/models/UserSessionModel.java index a0aa6a5d6f..e7ce35c394 100755 --- a/model/api/src/main/java/org/keycloak/models/UserSessionModel.java +++ b/model/api/src/main/java/org/keycloak/models/UserSessionModel.java @@ -15,10 +15,22 @@ public interface UserSessionModel { void setUser(UserModel user); + String getLoginUsername(); + + void setLoginUsername(String loginUsername); + String getIpAddress(); void setIpAddress(String ipAddress); + String getAuthMethod(); + + void setAuthMethod(String authMethod); + + boolean isRememberMe(); + + void setRememberMe(boolean rememberMe); + int getStarted(); void setStarted(int started); @@ -32,4 +44,5 @@ public interface UserSessionModel { List getClientAssociations(); void removeAssociatedClient(ClientModel client); + } diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java index fb33ca1093..d91061d65b 100755 --- a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java +++ b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java @@ -10,7 +10,7 @@ import java.util.List; */ public interface UserSessionProvider extends Provider { - UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress); + UserSessionModel createUserSession(RealmModel realm, UserModel user, String loginUsername, String ipAddress, String authMethod, boolean rememberMe); UserSessionModel getUserSession(RealmModel realm, String id); List getUserSessions(RealmModel realm, UserModel user); List getUserSessions(RealmModel realm, ClientModel client); diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java index 41c2705507..640af9938b 100644 --- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java +++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java @@ -63,12 +63,15 @@ public class JpaUserSessionProvider implements UserSessionProvider { } @Override - public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) { + public UserSessionModel createUserSession(RealmModel realm, UserModel user, String loginUsername, String ipAddress, String authMethod, boolean rememberMe) { UserSessionEntity entity = new UserSessionEntity(); entity.setId(KeycloakModelUtils.generateId()); entity.setRealmId(realm.getId()); entity.setUserId(user.getId()); + entity.setLoginUsername(loginUsername); entity.setIpAddress(ipAddress); + entity.setAuthMethod(authMethod); + entity.setRememberMe(rememberMe); int currentTime = Time.currentTime(); diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java index 490134f05d..01bda8ee90 100755 --- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java +++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java @@ -53,6 +53,16 @@ public class UserSessionAdapter implements UserSessionModel { entity.setUserId(user.getId()); } + @Override + public String getLoginUsername() { + return entity.getLoginUsername(); + } + + @Override + public void setLoginUsername(String loginUsername) { + entity.setLoginUsername(loginUsername); + } + @Override public String getIpAddress() { return entity.getIpAddress(); @@ -63,6 +73,26 @@ public class UserSessionAdapter implements UserSessionModel { entity.setIpAddress(ipAddress); } + @Override + public String getAuthMethod() { + return entity.getAuthMethod(); + } + + @Override + public void setAuthMethod(String authMethod) { + entity.setAuthMethod(authMethod); + } + + @Override + public boolean isRememberMe() { + return entity.isRememberMe(); + } + + @Override + public void setRememberMe(boolean rememberMe) { + entity.setRememberMe(rememberMe); + } + @Override public int getStarted() { return entity.getStarted(); diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UserSessionEntity.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UserSessionEntity.java index 3d03df12e5..9094a908f1 100755 --- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UserSessionEntity.java +++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UserSessionEntity.java @@ -35,12 +35,21 @@ public class UserSessionEntity { @Column(name="USER_ID") protected String userId; + @Column(name="LOGIN_USERNAME") + protected String loginUsername; + @Column(name="REALM_ID") protected String realmId; @Column(name="IP_ADDRESS") protected String ipAddress; + @Column(name="AUTH_METHOD") + protected String authMethod; + + @Column(name="REMEMBER_ME") + protected boolean rememberMe; + @Column(name="STARTED") protected int started; @@ -66,6 +75,14 @@ public class UserSessionEntity { this.userId = userId; } + public String getLoginUsername() { + return loginUsername; + } + + public void setLoginUsername(String loginUsername) { + this.loginUsername = loginUsername; + } + public String getRealmId() { return realmId; } @@ -82,6 +99,22 @@ public class UserSessionEntity { this.ipAddress = ipAddress; } + public String getAuthMethod() { + return authMethod; + } + + public void setAuthMethod(String authMethod) { + this.authMethod = authMethod; + } + + public boolean isRememberMe() { + return rememberMe; + } + + public void setRememberMe(boolean rememberMe) { + this.rememberMe = rememberMe; + } + public int getStarted() { return started; } diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java index 0ebdefdb4f..7021046b7d 100755 --- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java +++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java @@ -37,14 +37,17 @@ public class MemUserSessionProvider implements UserSessionProvider { } @Override - public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) { + public UserSessionModel createUserSession(RealmModel realm, UserModel user, String loginUsername, String ipAddress, String authMethod, boolean rememberMe) { String id = KeycloakModelUtils.generateId(); UserSessionEntity entity = new UserSessionEntity(); entity.setId(id); entity.setRealm(realm.getId()); entity.setUser(user.getId()); + entity.setLoginUsername(loginUsername); entity.setIpAddress(ipAddress); + entity.setAuthMethod(authMethod); + entity.setRememberMe(rememberMe); int currentTime = Time.currentTime(); diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java index 6a62ba7096..a9008cfc42 100755 --- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java +++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java @@ -43,6 +43,16 @@ public class UserSessionAdapter implements UserSessionModel { entity.setUser(user.getId()); } + @Override + public String getLoginUsername() { + return entity.getLoginUsername(); + } + + @Override + public void setLoginUsername(String loginUsername) { + entity.setLoginUsername(loginUsername); + } + public String getIpAddress() { return entity.getIpAddress(); } @@ -51,6 +61,26 @@ public class UserSessionAdapter implements UserSessionModel { entity.setIpAddress(ipAddress); } + @Override + public String getAuthMethod() { + return entity.getAuthMethod(); + } + + @Override + public void setAuthMethod(String authMethod) { + entity.setAuthMethod(authMethod); + } + + @Override + public boolean isRememberMe() { + return entity.isRememberMe(); + } + + @Override + public void setRememberMe(boolean rememberMe) { + entity.setRememberMe(rememberMe); + } + public int getStarted() { return entity.getStarted(); } diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UserSessionEntity.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UserSessionEntity.java index 9c71cbe9c7..25961371ba 100644 --- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UserSessionEntity.java +++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UserSessionEntity.java @@ -11,7 +11,10 @@ public class UserSessionEntity { private String id; private String realm; private String user; + private String loginUsername; private String ipAddress; + private String authMethod; + private boolean rememberMe; private int started; private int lastSessionRefresh; private List clients = new LinkedList(); @@ -40,6 +43,14 @@ public class UserSessionEntity { this.user = user; } + public String getLoginUsername() { + return loginUsername; + } + + public void setLoginUsername(String loginUsername) { + this.loginUsername = loginUsername; + } + public String getIpAddress() { return ipAddress; } @@ -48,6 +59,22 @@ public class UserSessionEntity { this.ipAddress = ipAddress; } + public String getAuthMethod() { + return authMethod; + } + + public void setAuthMethod(String authMethod) { + this.authMethod = authMethod; + } + + public boolean isRememberMe() { + return rememberMe; + } + + public void setRememberMe(boolean rememberMe) { + this.rememberMe = rememberMe; + } + public int getStarted() { return started; } diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java index b49036ade3..b555407ad1 100755 --- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java +++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java @@ -35,11 +35,14 @@ public class MongoUserSessionProvider implements UserSessionProvider { } @Override - public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) { + public UserSessionModel createUserSession(RealmModel realm, UserModel user, String loginUsername, String ipAddress, String authMethod, boolean rememberMe) { MongoUserSessionEntity entity = new MongoUserSessionEntity(); entity.setRealmId(realm.getId()); entity.setUser(user.getId()); + entity.setLoginUsername(loginUsername); entity.setIpAddress(ipAddress); + entity.setAuthMethod(authMethod); + entity.setRememberMe(rememberMe); int currentTime = Time.currentTime(); diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java index 901dd24632..d7a3223709 100755 --- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java +++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java @@ -58,6 +58,17 @@ public class UserSessionAdapter extends AbstractMongoAdapter accessCode.getExpiration(); + int lifespan = accessCode.getAction() == null ? realm.getAccessCodeLifespan() : realm.getAccessCodeLifespanUserAction(); + return accessCode.getTimestamp() + lifespan < Time.currentTime(); } public Set getRequestedRoles() { @@ -78,61 +74,52 @@ public class AccessCodeEntry { return accessCode.getRedirectUri(); } - public boolean isRememberMe() { - return accessCode.isRememberMe(); + public AccessCode.Action getAction() { + return accessCode.getAction(); } - public void setRememberMe(boolean remember) { - accessCode.setRememberMe(remember); + public void setAction(AccessCode.Action action) { + accessCode.setAction(action); + accessCode.setTimestamp(Time.currentTime()); } - public String getAuthMethod() { - return accessCode.getAuthMethod(); - } - - public String getUsernameUsed() { - return accessCode.getUsernameUsed(); - } - - public void setUsernameUsed(String username) { - accessCode.setUsernameUsed(username); - } - - public void resetExpiration() { - accessCode.setExpiration(Time.currentTime() + realm.getAccessCodeLifespan()); - - } - - public void setAuthMethod(String authMethod) { - accessCode.setAuthMethod(authMethod); - } - - public Set getRequiredActions() { - Set set = new HashSet(); - for (String action : accessCode.getRequiredActions()) { - set.add(RequiredAction.valueOf(action)); - + public RequiredAction getRequiredAction() { + AccessCode.Action action = accessCode.getAction(); + if (action != null) { + switch (action) { + case CONFIGURE_TOTP: + return RequiredAction.CONFIGURE_TOTP; + case UPDATE_PASSWORD: + return RequiredAction.UPDATE_PASSWORD; + case UPDATE_PROFILE: + return RequiredAction.UPDATE_PROFILE; + case VERIFY_EMAIL: + return RequiredAction.VERIFY_EMAIL; + } } - return set; + return null; } - public boolean hasRequiredAction(RequiredAction action) { - return accessCode.getRequiredActions().contains(action.toString()); - } - - public void removeRequiredAction(RequiredAction action) { - accessCode.getRequiredActions().remove(action.toString()); - } - - public void setRequiredActions(Set set) { - Set newSet = new HashSet(); - for (RequiredAction action : set) { - newSet.add(action.toString()); + public void setRequiredAction(RequiredAction requiredAction) { + switch (requiredAction) { + case CONFIGURE_TOTP: + setAction(AccessCode.Action.CONFIGURE_TOTP); + break; + case UPDATE_PASSWORD: + setAction(AccessCode.Action.UPDATE_PASSWORD); + break; + case UPDATE_PROFILE: + setAction(AccessCode.Action.UPDATE_PROFILE); + break; + case VERIFY_EMAIL: + setAction(AccessCode.Action.VERIFY_EMAIL); + break; + default: + throw new IllegalArgumentException("Unknown required action " + requiredAction); } - accessCode.setRequiredActions(newSet); } public String getCode() { - return new JWSBuilder().jsonContent(accessCode).rsa256(realm.getPrivateKey()); + return new JWSBuilder().jsonContent(accessCode).rsa256(realm.getPrivateKey()); } } diff --git a/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java index 69dc76f455..451131da6c 100755 --- a/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java +++ b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java @@ -21,11 +21,9 @@ public class AppAuthManager extends AuthenticationManager { public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) { AuthResult authResult = super.authenticateIdentityCookie(session, realm, uriInfo, headers); if (authResult == null) return null; - Cookie remember = headers.getCookies().get(AuthenticationManager.KEYCLOAK_REMEMBER_ME); - boolean rememberMe = remember != null; // refresh the cookies! - createLoginCookie(realm, authResult.getUser(), authResult.getSession(), uriInfo, rememberMe); - if (rememberMe) createRememberMeCookie(realm, uriInfo); + createLoginCookie(realm, authResult.getUser(), authResult.getSession(), uriInfo); + if (authResult.getSession().isRememberMe()) createRememberMeCookie(realm, uriInfo); return authResult; } diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java index b2e3cc2515..4d71501bcc 100755 --- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java +++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java @@ -94,7 +94,7 @@ public class AuthenticationManager { return token; } - public void createLoginCookie(RealmModel realm, UserModel user, UserSessionModel session, UriInfo uriInfo, boolean rememberMe) { + public void createLoginCookie(RealmModel realm, UserModel user, UserSessionModel session, UriInfo uriInfo) { logger.info("createLoginCookie"); String cookiePath = getIdentityCookiePath(realm, uriInfo); AccessToken identityToken = createIdentityToken(realm, user, session); @@ -102,7 +102,7 @@ public class AuthenticationManager { boolean secureOnly = !realm.isSslNotRequired(); logger.debugv("creatingLoginCookie - name: {0} path: {1}", KEYCLOAK_IDENTITY_COOKIE, cookiePath); int maxAge = NewCookie.DEFAULT_MAX_AGE; - if (rememberMe) { + if (session.isRememberMe()) { maxAge = realm.getSsoSessionIdleTimeout(); logger.info("createLoginCookie maxAge: " + maxAge); } diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java index e5ba119ac5..727679ecf3 100755 --- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java +++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java @@ -81,7 +81,6 @@ public class TokenManager { code.setClientId(client.getClientId()); code.setUserId(user.getId()); code.setTimestamp(Time.currentTime()); - code.setExpiration(Time.currentTime() + realm.getAccessCodeLifespan()); code.setSessionState(session != null ? session.getId() : null); code.setRedirectUri(redirect); code.setState(state); diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java index 1a03dc557e..60988ca438 100755 --- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java +++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java @@ -63,7 +63,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Providers; -import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -131,7 +130,6 @@ public class RequiredActionsService { user.setEmail(email); user.removeRequiredAction(RequiredAction.UPDATE_PROFILE); - accessCode.removeRequiredAction(RequiredAction.UPDATE_PROFILE); audit.clone().event(EventType.UPDATE_PROFILE).success(); if (emailChanged) { @@ -173,7 +171,6 @@ public class RequiredActionsService { user.setTotp(true); user.removeRequiredAction(RequiredAction.CONFIGURE_TOTP); - accessCode.removeRequiredAction(RequiredAction.CONFIGURE_TOTP); audit.clone().event(EventType.UPDATE_TOTP).success(); @@ -218,20 +215,15 @@ public class RequiredActionsService { logger.debug("updatePassword updated credential"); user.removeRequiredAction(RequiredAction.UPDATE_PASSWORD); - if (accessCode != null) { - accessCode.removeRequiredAction(RequiredAction.UPDATE_PASSWORD); - } audit.clone().event(EventType.UPDATE_PASSWORD).success(); - // Password reset through email won't have an associated session + // Redirect to account management to login if password reset was initiated by admin if (accessCode.getSessionState() == null) { - UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserById(accessCode.getUser().getId(), realm), clientConnection.getRemoteAddr()); - accessCode.setSessionState(userSession.getId()); - audit.session(userSession); + return Response.seeOther(Urls.accountPage(uriInfo.getBaseUri(), realm.getId())).build(); + } else { + return redirectOauth(user, accessCode); } - - return redirectOauth(user, accessCode); } @@ -240,8 +232,7 @@ public class RequiredActionsService { public Response emailVerification() { if (uriInfo.getQueryParameters().containsKey("key")) { AccessCodeEntry accessCode = tokenManager.parseCode(uriInfo.getQueryParameters().getFirst("key"), session, realm); - if (accessCode == null || accessCode.isExpired() - || !accessCode.hasRequiredAction(RequiredAction.VERIFY_EMAIL)) { + if (accessCode == null || accessCode.isExpired() || !RequiredAction.VERIFY_EMAIL.equals(accessCode.getRequiredAction())) { return unauthorized(); } @@ -252,7 +243,6 @@ public class RequiredActionsService { user.setEmailVerified(true); user.removeRequiredAction(RequiredAction.VERIFY_EMAIL); - accessCode.removeRequiredAction(RequiredAction.VERIFY_EMAIL); audit.clone().event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, accessCode.getUser().getEmail()).success(); @@ -276,9 +266,7 @@ public class RequiredActionsService { public Response passwordReset() { if (uriInfo.getQueryParameters().containsKey("key")) { AccessCodeEntry accessCode = tokenManager.parseCode(uriInfo.getQueryParameters().getFirst("key"), session, realm); - accessCode.setAuthMethod("form"); - if (accessCode == null || accessCode.isExpired() - || !accessCode.hasRequiredAction(RequiredAction.UPDATE_PASSWORD)) { + if (accessCode == null || accessCode.isExpired() || !RequiredAction.UPDATE_PASSWORD.equals(accessCode.getRequiredAction())) { return unauthorized(); } @@ -326,13 +314,11 @@ public class RequiredActionsService { logger.warn("Failed to send password reset email: user not found"); audit.error(Errors.USER_NOT_FOUND); } else { - Set requiredActions = new HashSet(user.getRequiredActions()); - requiredActions.add(RequiredAction.UPDATE_PASSWORD); + UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "form", false); + audit.session(userSession); - AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, session, realm, client, user, null); - accessCode.setRequiredActions(requiredActions); - accessCode.setAuthMethod("form"); - accessCode.setUsernameUsed(username); + AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, session, realm, client, user, userSession); + accessCode.setRequiredAction(RequiredAction.UPDATE_PASSWORD); try { UriBuilder builder = Urls.loginPasswordResetBuilder(uriInfo.getBaseUri()); @@ -372,8 +358,8 @@ public class RequiredActionsService { return null; } - if (accessCodeEntry.getRequiredActions() == null || !accessCodeEntry.getRequiredActions().contains(requiredAction)) { - logger.debugv("getAccessCodeEntry required actions null || entry does not contain required action: {0}|{1}", (accessCodeEntry.getRequiredActions() == null),!accessCodeEntry.getRequiredActions().contains(requiredAction) ); + if (!requiredAction.equals(accessCodeEntry.getRequiredAction())) { + logger.debugv("Invalid access code action: {0}", requiredAction); return null; } @@ -391,11 +377,12 @@ public class RequiredActionsService { Set requiredActions = user.getRequiredActions(); if (!requiredActions.isEmpty()) { + accessCode.setRequiredAction(requiredActions.iterator().next()); return Flows.forms(session, realm, uriInfo).setAccessCode(accessCode.getCode()).setUser(user) .createResponse(requiredActions.iterator().next()); } else { logger.debugv("redirectOauth: redirecting to: {0}", accessCode.getRedirectUri()); - accessCode.resetExpiration(); + accessCode.setAction(null); AuthenticationManager authManager = new AuthenticationManager(); @@ -419,12 +406,16 @@ public class RequiredActionsService { .session(accessCode.getSessionState()) .detail(Details.CODE_ID, accessCode.getCodeId()) .detail(Details.REDIRECT_URI, accessCode.getRedirectUri()) - .detail(Details.RESPONSE_TYPE, "code") - .detail(Details.AUTH_METHOD, accessCode.getAuthMethod()) - .detail(Details.USERNAME, accessCode.getUsernameUsed()); + .detail(Details.RESPONSE_TYPE, "code"); - if (accessCode.isRememberMe()) { - audit.detail(Details.REMEMBER_ME, "true"); + UserSessionModel userSession = accessCode.getSessionState() != null ? session.sessions().getUserSession(realm, accessCode.getSessionState()) : null; + + if (userSession != null) { + audit.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); + audit.detail(Details.USERNAME, userSession.getLoginUsername()); + if (userSession.isRememberMe()) { + audit.detail(Details.REMEMBER_ME, "true"); + } } } diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java index 2411706883..d1691c1b31 100755 --- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java +++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java @@ -116,6 +116,7 @@ public class SocialResource { SocialProvider provider = SocialLoader.load(initialRequest.getProvider()); String realmName = initialRequest.getRealm(); + String authMethod = "social@" + provider.getId(); RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(realmName); @@ -123,7 +124,7 @@ public class SocialResource { Audit audit = new AuditManager(realm, session, clientConnection).createAudit() .event(EventType.LOGIN) .detail(Details.RESPONSE_TYPE, initialRequest.get(OAuth2Constants.RESPONSE_TYPE)) - .detail(Details.AUTH_METHOD, "social@" + provider.getId()); + .detail(Details.AUTH_METHOD, authMethod); AuthenticationManager authManager = new AuthenticationManager(); OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager); @@ -251,10 +252,12 @@ public class SocialResource { return oauth.forwardToSecurityFailure("Your account is not enabled."); } - UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr()); + String username = socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(); + + UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), authMethod, false); audit.session(userSession); - return oauth.processAccessCode(scope, state, redirectUri, client, user, userSession, socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(), false, "social@" + provider.getId(), audit); + return oauth.processAccessCode(scope, state, redirectUri, client, user, userSession, audit); } @GET diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java index ef32859277..917dd2d9aa 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -28,6 +28,7 @@ import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.models.utils.KeycloakModelUtils; +import org.keycloak.representations.AccessCode; import org.keycloak.representations.AccessToken; import org.keycloak.representations.AccessTokenResponse; import org.keycloak.representations.idm.CredentialRepresentation; @@ -279,7 +280,7 @@ public class TokenService { String scope = form.getFirst(OAuth2Constants.SCOPE); - UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr()); + UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "oauth_credentials", false); userSession.associateClient(client); audit.session(userSession); @@ -426,10 +427,10 @@ public class TokenService { switch (status) { case SUCCESS: case ACTIONS_REQUIRED: - UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr()); + UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "form", remember); audit.session(userSession); - return oauth.processAccessCode(scopeParam, state, redirect, client, user, userSession, username, remember, "form", audit); + return oauth.processAccessCode(scopeParam, state, redirect, client, user, userSession, audit); case ACCOUNT_TEMPORARILY_DISABLED: audit.error(Errors.USER_TEMPORARILY_DISABLED); return Flows.forms(this.session, realm, uriInfo).setError(Messages.ACCOUNT_TEMPORARILY_DISABLED).setFormData(formData).createLogin(); @@ -642,6 +643,14 @@ public class TokenService { return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) .build(); } + if (accessCode.getAction() != null) { + Map res = new HashMap(); + res.put(OAuth2Constants.ERROR, "invalid_grant"); + res.put(OAuth2Constants.ERROR_DESCRIPTION, "Code is not active"); + audit.error(Errors.INVALID_CODE); + return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) + .build(); + } audit.user(accessCode.getUser()); audit.session(accessCode.getSessionState()); @@ -834,7 +843,7 @@ public class TokenService { logger.debug(user.getUsername() + " already logged in."); audit.user(user).session(session).detail(Details.AUTH_METHOD, "sso"); - return oauth.processAccessCode(scopeParam, state, redirect, client, user, session, null, false, "sso", audit); + return oauth.processAccessCode(scopeParam, state, redirect, client, user, session, audit); } if (prompt != null && prompt.equals("none")) { @@ -974,7 +983,7 @@ public class TokenService { String code = formData.getFirst(OAuth2Constants.CODE); AccessCodeEntry accessCodeEntry = tokenManager.parseCode(code, session, realm); - if (accessCodeEntry == null) { + if (accessCodeEntry == null || !AccessCode.Action.OAUTH_GRANT.equals(accessCodeEntry.getAction())) { audit.error(Errors.INVALID_CODE); return oauth.forwardToSecurityFailure("Unknown access code."); } @@ -986,15 +995,17 @@ public class TokenService { audit.client(accessCodeEntry.getClient()) .user(accessCodeEntry.getUser()) .detail(Details.RESPONSE_TYPE, "code") - .detail(Details.AUTH_METHOD, accessCodeEntry.getAuthMethod()) - .detail(Details.REDIRECT_URI, redirect) - .detail(Details.USERNAME, accessCodeEntry.getUsernameUsed()); - - if (accessCodeEntry.isRememberMe()) { - audit.detail(Details.REMEMBER_ME, "true"); - } + .detail(Details.REDIRECT_URI, redirect); UserSessionModel userSession = session.sessions().getUserSession(realm, accessCodeEntry.getSessionState()); + if (userSession != null) { + audit.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); + audit.detail(Details.USERNAME, userSession.getLoginUsername()); + if (userSession.isRememberMe()) { + audit.detail(Details.REMEMBER_ME, "true"); + } + } + if (!AuthenticationManager.isSessionValid(realm, userSession)) { AuthenticationManager.logout(session, realm, userSession, uriInfo); audit.error(Errors.INVALID_CODE); @@ -1009,7 +1020,7 @@ public class TokenService { audit.success(); - accessCodeEntry.resetExpiration(); + accessCodeEntry.setAction(null); return oauth.redirectAccessCode(accessCodeEntry, userSession, state, redirect); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index a3fe4a2698..184299f279 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -820,13 +820,8 @@ public class UsersResource { return Flows.errors().error("AccountProvider management not enabled", Response.Status.INTERNAL_SERVER_ERROR); } - Set requiredActions = new HashSet(user.getRequiredActions()); - requiredActions.add(UserModel.RequiredAction.UPDATE_PASSWORD); - AccessCodeEntry accessCode = tokenManager.createAccessCode(scope, state, redirect, session, realm, client, user, null); - accessCode.setRequiredActions(requiredActions); - accessCode.setUsernameUsed(username); - accessCode.resetExpiration(); + accessCode.setRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD); try { UriBuilder builder = Urls.loginPasswordResetBuilder(uriInfo.getBaseUri()); diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java index 06a0e1a36a..b73c0fcb79 100755 --- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java @@ -37,7 +37,7 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserModel.RequiredAction; import org.keycloak.models.UserSessionModel; -import org.keycloak.representations.AccessToken; +import org.keycloak.representations.AccessCode; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.managers.AccessCodeEntry; import org.keycloak.services.managers.AuthenticationManager; @@ -48,10 +48,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; /** @@ -84,12 +82,7 @@ public class OAuthFlows { this.tokenManager = tokenManager; } - public Response redirectAccessCode(AccessCodeEntry accessCode, UserSessionModel session, String state, String redirect) { - return redirectAccessCode(accessCode, session, state, redirect, false); - } - - - public Response redirectAccessCode(AccessCodeEntry accessCode, UserSessionModel userSession, String state, String redirect, boolean rememberMe) { + public Response redirectAccessCode(AccessCodeEntry accessCode, UserSessionModel userSession, String state, String redirect) { String code = accessCode.getCode(); UriBuilder redirectUri = UriBuilder.fromUri(redirect).queryParam(OAuth2Constants.CODE, code); log.debugv("redirectAccessCode: state: {0}", state); @@ -97,7 +90,6 @@ public class OAuthFlows { redirectUri.queryParam(OAuth2Constants.STATE, state); Response.ResponseBuilder location = Response.status(302).location(redirectUri.build()); Cookie remember = request.getHttpHeaders().getCookies().get(AuthenticationManager.KEYCLOAK_REMEMBER_ME); - rememberMe = rememberMe || remember != null; Cookie sessionCookie = request.getHttpHeaders().getCookies().get(AuthenticationManager.KEYCLOAK_SESSION_COOKIE); if (sessionCookie != null) { @@ -112,8 +104,8 @@ public class OAuthFlows { } // refresh the cookies! - authManager.createLoginCookie(realm, accessCode.getUser(), userSession, uriInfo, rememberMe); - if (rememberMe) authManager.createRememberMeCookie(realm, uriInfo); + authManager.createLoginCookie(realm, accessCode.getUser(), userSession, uriInfo); + if (userSession.isRememberMe()) authManager.createRememberMeCookie(realm, uriInfo); return location.build(); } @@ -125,15 +117,12 @@ public class OAuthFlows { return Response.status(302).location(redirectUri.build()).build(); } - public Response processAccessCode(String scopeParam, String state, String redirect, ClientModel client, UserModel user, UserSessionModel session, String username, boolean rememberMe, String authMethod, Audit audit) { + public Response processAccessCode(String scopeParam, String state, String redirect, ClientModel client, UserModel user, UserSessionModel session, Audit audit) { isTotpConfigurationRequired(user); isEmailVerificationRequired(user); boolean isResource = client instanceof ApplicationModel; AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, this.session, realm, client, user, session); - accessCode.setRememberMe(rememberMe); - accessCode.setAuthMethod(authMethod); - accessCode.setUsernameUsed(username); log.debugv("processAccessCode: isResource: {0}", isResource); log.debugv("processAccessCode: go to oauth page?: {0}", @@ -143,10 +132,9 @@ public class OAuthFlows { Set requiredActions = user.getRequiredActions(); if (!requiredActions.isEmpty()) { - accessCode.setRequiredActions(new HashSet(requiredActions)); - accessCode.resetExpiration(); - RequiredAction action = user.getRequiredActions().iterator().next(); + accessCode.setRequiredAction(action); + if (action.equals(RequiredAction.VERIFY_EMAIL)) { audit.clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, accessCode.getUser().getEmail()).success(); } @@ -156,7 +144,7 @@ public class OAuthFlows { } if (!isResource) { - accessCode.resetExpiration(); + accessCode.setAction(AccessCode.Action.OAUTH_GRANT); List realmRoles = new LinkedList(); MultivaluedMap resourceRoles = new MultivaluedMapImpl(); @@ -177,7 +165,7 @@ public class OAuthFlows { if (redirect != null) { audit.success(); - return redirectAccessCode(accessCode, session, state, redirect, rememberMe); + return redirectAccessCode(accessCode, session, state, redirect); } else { return null; } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java index 59bb24bd56..3b57ca3cfc 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java @@ -100,7 +100,7 @@ public class AdapterTest { ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION); TokenManager tm = new TokenManager(); UserModel admin = session.users().getUserByUsername("admin", adminRealm); - UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null); + UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false); AccessToken token = tm.createClientAccessToken(tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession); return tm.encodeToken(adminRealm, token); } finally { diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java index 7c155fb5d4..a9114ebf6d 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java @@ -87,7 +87,7 @@ public class RelativeUriAdapterTest { ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION); TokenManager tm = new TokenManager(); UserModel admin = session.users().getUserByUsername("admin", adminRealm); - UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null); + UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "user", null, "form", false); AccessToken token = tm.createClientAccessToken(tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession); adminToken = tm.encodeToken(adminRealm, token); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java index 54f85e2b91..6b39c49eda 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java @@ -79,7 +79,7 @@ public class AdminAPITest { ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION); TokenManager tm = new TokenManager(); UserModel admin = session.users().getUserByUsername("admin", adminRealm); - UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null); + UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false); AccessToken token = tm.createClientAccessToken(tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession); return tm.encodeToken(adminRealm, token); } finally { diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java index 2bf82173ce..9972c48ca1 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java @@ -126,7 +126,7 @@ public class ResetPasswordTest { resetPasswordPage.assertCurrent(); - events.expectRequiredAction(EventType.SEND_RESET_PASSWORD).user(userId).detail(Details.USERNAME, username).session((String) null).detail(Details.EMAIL, "login@test.com").assertEvent().getSessionId(); + String sessionId = events.expectRequiredAction(EventType.SEND_RESET_PASSWORD).user(userId).detail(Details.USERNAME, username).detail(Details.EMAIL, "login@test.com").assertEvent().getSessionId(); Assert.assertEquals("You should receive an email shortly with further instructions.", resetPasswordPage.getSuccessMessage()); @@ -143,16 +143,15 @@ public class ResetPasswordTest { updatePasswordPage.changePassword("resetPassword", "resetPassword"); - events.expectRequiredAction(EventType.UPDATE_PASSWORD).user(userId).session((String) null).detail(Details.USERNAME, username).assertEvent(); + events.expectRequiredAction(EventType.UPDATE_PASSWORD).user(userId).session(sessionId).detail(Details.USERNAME, username).assertEvent(); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - Event loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, username).assertEvent(); - String sessionId = loginEvent.getSessionId(); + events.expectLogin().user(userId).detail(Details.USERNAME, username).session(sessionId).assertEvent(); oauth.openLogout(); - events.expectLogout(loginEvent.getSessionId()).user(userId).session(sessionId).assertEvent(); + events.expectLogout(sessionId).user(userId).session(sessionId).assertEvent(); loginPage.open(); @@ -210,7 +209,7 @@ public class ResetPasswordTest { String body = (String) message.getContent(); String changePasswordUrl = MailUtil.getLink(body); - events.expectRequiredAction(EventType.SEND_RESET_PASSWORD).user(userId).detail(Details.USERNAME, "login-test").detail(Details.EMAIL, "login@test.com").session((String) null).assertEvent(); + String sessionId = events.expectRequiredAction(EventType.SEND_RESET_PASSWORD).user(userId).detail(Details.USERNAME, "login-test").detail(Details.EMAIL, "login@test.com").assertEvent().getSessionId(); driver.navigate().to(changePasswordUrl.trim()); @@ -222,16 +221,15 @@ public class ResetPasswordTest { updatePasswordPage.changePassword("resetPasswordWithPasswordPolicy", "resetPasswordWithPasswordPolicy"); - events.expectRequiredAction(EventType.UPDATE_PASSWORD).user(userId).session((String) null).detail(Details.USERNAME, "login-test").assertEvent(); + events.expectRequiredAction(EventType.UPDATE_PASSWORD).user(userId).session(sessionId).detail(Details.USERNAME, "login-test").assertEvent(); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - Event loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); - String sessionId = loginEvent.getSessionId(); + events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").session(sessionId).assertEvent(); oauth.openLogout(); - events.expectLogout(loginEvent.getSessionId()).user(userId).session(sessionId).assertEvent(); + events.expectLogout(sessionId).user(userId).session(sessionId).assertEvent(); loginPage.open(); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java index b032c41fd0..6bec2d8bf7 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java @@ -55,8 +55,8 @@ public class UserSessionProviderTest { int started = Time.currentTime(); UserSessionModel[] sessions = createSessions(); - assertSession(session.sessions().getUserSession(realm, sessions[0].getId()), session.users().getUserByUsername("user1", realm), "127.0.0.1", started, started, "test-app", "third-party"); - assertSession(session.sessions().getUserSession(realm, sessions[1].getId()), session.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app"); + assertSession(session.sessions().getUserSession(realm, sessions[0].getId()), session.users().getUserByUsername("user1", realm), "127.0.0.1", started, started, "test-app", "third-party"); + assertSession(session.sessions().getUserSession(realm, sessions[1].getId()), session.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app"); assertSession(session.sessions().getUserSession(realm, sessions[2].getId()), session.users().getUserByUsername("user2", realm), "127.0.0.3", started, started); } @@ -116,7 +116,7 @@ public class UserSessionProviderTest { @Test public void testGetByClientPaginated() { for (int i = 0; i < 25; i++) { - UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "127.0.0." + i); + UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0." + i, "form", false); userSession.setStarted(Time.currentTime() + i); userSession.associateClient(realm.findClient("test-app")); } @@ -157,14 +157,14 @@ public class UserSessionProviderTest { private UserSessionModel[] createSessions() { UserSessionModel[] sessions = new UserSessionModel[4]; - sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "127.0.0.1"); + sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true); sessions[0].associateClient(realm.findClient("test-app")); sessions[0].associateClient(realm.findClient("third-party")); - sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "127.0.0.2"); + sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.2", "form", true); sessions[1].associateClient(realm.findClient("test-app")); - sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "127.0.0.3"); + sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.3", "form", true); resetSession(); @@ -197,6 +197,9 @@ public class UserSessionProviderTest { public void assertSession(UserSessionModel session, UserModel user, String ipAddress, int started, int lastRefresh, String... clients) { assertEquals(user.getId(), session.getUser().getId()); assertEquals(ipAddress, session.getIpAddress()); + assertEquals(user.getUsername(), session.getLoginUsername()); + assertEquals("form", session.getAuthMethod()); + assertEquals(true, session.isRememberMe()); assertTrue(session.getStarted() >= started - 1 && session.getStarted() <= started + 1); assertTrue(session.getLastSessionRefresh() >= lastRefresh - 1 && session.getLastSessionRefresh() <= lastRefresh + 1);