keycloak-uncached

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/AccessCode.java b/core/src/main/java/org/keycloak/representations/AccessCode.java
index 9fe860e..ef61202 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<String> requiredActions;
+    protected Action action;
     protected Set<String> 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<String> getRequiredActions() {
-        return requiredActions;
+    public Action getAction() {
+        return action;
     }
 
-    public void setRequiredActions(Set<String> 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<String> getRequestedRoles() {
@@ -125,4 +89,13 @@ public class AccessCode {
     public void setRequestedRoles(Set<String> 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 a0aa6a5..e7ce35c 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<ClientModel> 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 fb33ca1..d91061d 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<UserSessionModel> getUserSessions(RealmModel realm, UserModel user);
     List<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client);
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 3d03df1..9094a90 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-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 41c2705..640af99 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 490134f..01bda8e 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
@@ -54,6 +54,16 @@ public class UserSessionAdapter implements UserSessionModel {
     }
 
     @Override
+    public String getLoginUsername() {
+        return entity.getLoginUsername();
+    }
+
+    @Override
+    public void setLoginUsername(String loginUsername) {
+        entity.setLoginUsername(loginUsername);
+    }
+
+    @Override
     public String getIpAddress() {
         return entity.getIpAddress();
     }
@@ -64,6 +74,26 @@ public class UserSessionAdapter implements UserSessionModel {
     }
 
     @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-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 9c71cbe..2596137 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<String> clients = new LinkedList<String>();
@@ -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-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 0ebdefd..7021046 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 6a62ba7..a9008cf 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-mongo/src/main/java/org/keycloak/models/sessions/mongo/entities/MongoUserSessionEntity.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/entities/MongoUserSessionEntity.java
index 21e565b..8d0e946 100755
--- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/entities/MongoUserSessionEntity.java
+++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/entities/MongoUserSessionEntity.java
@@ -18,8 +18,14 @@ public class MongoUserSessionEntity extends AbstractIdentifiableEntity implement
 
     private String user;
 
+    private String loginUsername;
+
     private String ipAddress;
 
+    private String authMethod;
+
+    private boolean rememberMe;
+
     private int started;
 
     private int lastSessionRefresh;
@@ -42,6 +48,14 @@ public class MongoUserSessionEntity extends AbstractIdentifiableEntity implement
         this.user = user;
     }
 
+    public String getLoginUsername() {
+        return loginUsername;
+    }
+
+    public void setLoginUsername(String loginUsername) {
+        this.loginUsername = loginUsername;
+    }
+
     public String getIpAddress() {
         return ipAddress;
     }
@@ -50,6 +64,22 @@ public class MongoUserSessionEntity extends AbstractIdentifiableEntity implement
         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 b49036a..b555407 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 901dd24..d7a3223 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
@@ -59,6 +59,17 @@ public class UserSessionAdapter extends AbstractMongoAdapter<MongoUserSessionEnt
     }
 
     @Override
+    public String getLoginUsername() {
+        return entity.getLoginUsername();
+    }
+
+    @Override
+    public void setLoginUsername(String loginUsername) {
+        entity.setLoginUsername(loginUsername);
+        updateMongoEntity();
+    }
+
+    @Override
     public String getIpAddress() {
         return entity.getIpAddress();
     }
@@ -70,6 +81,28 @@ public class UserSessionAdapter extends AbstractMongoAdapter<MongoUserSessionEnt
     }
 
     @Override
+    public String getAuthMethod() {
+        return entity.getAuthMethod();
+    }
+
+    @Override
+    public void setAuthMethod(String authMethod) {
+        entity.setAuthMethod(authMethod);
+        updateMongoEntity();
+    }
+
+    @Override
+    public boolean isRememberMe() {
+        return entity.isRememberMe();
+    }
+
+    @Override
+    public void setRememberMe(boolean rememberMe) {
+        entity.setRememberMe(rememberMe);
+        updateMongoEntity();
+    }
+
+    @Override
     public int getStarted() {
         return entity.getStarted();
     }
diff --git a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
index f5afe34..68e1cf8 100755
--- a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
+++ b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
@@ -9,7 +9,6 @@ import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.representations.AccessCode;
-import org.keycloak.representations.AccessToken;
 import org.keycloak.util.Time;
 
 import java.util.HashSet;
@@ -42,12 +41,9 @@ public class AccessCodeEntry {
         return accessCode.getSessionState();
     }
 
-    public void setSessionState(String state) {
-        accessCode.setSessionState(state);
-    }
-
     public boolean isExpired() {
-        return accessCode.getExpiration() != 0 && Time.currentTime() > accessCode.getExpiration();
+        int lifespan = accessCode.getAction() == null ? realm.getAccessCodeLifespan() : realm.getAccessCodeLifespanUserAction();
+        return accessCode.getTimestamp() + lifespan < Time.currentTime();
     }
 
     public Set<RoleModel> getRequestedRoles() {
@@ -78,61 +74,52 @@ public class AccessCodeEntry {
         return accessCode.getRedirectUri();
     }
 
-    public boolean isRememberMe() {
-        return accessCode.isRememberMe();
-    }
-
-    public void setRememberMe(boolean remember) {
-        accessCode.setRememberMe(remember);
-    }
-
-    public String getAuthMethod() {
-        return accessCode.getAuthMethod();
+    public AccessCode.Action getAction() {
+        return accessCode.getAction();
     }
 
-    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 setAction(AccessCode.Action action) {
+        accessCode.setAction(action);
+        accessCode.setTimestamp(Time.currentTime());
     }
 
-    public void setAuthMethod(String authMethod) {
-        accessCode.setAuthMethod(authMethod);
-    }
-
-    public Set<RequiredAction> getRequiredActions() {
-        Set<RequiredAction> set = new HashSet<RequiredAction>();
-        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;
-    }
-
-    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<RequiredAction> set) {
-        Set<String> newSet = new HashSet<String>();
-        for (RequiredAction action : set) {
-            newSet.add(action.toString());
+        return null;
+    }
+
+    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 69dc76f..451131d 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 b2e3cc2..4d71501 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 e5ba119..727679e 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/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index a3fe4a2..184299f 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<UserModel.RequiredAction> requiredActions = new HashSet<UserModel.RequiredAction>(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 06a0e1a..b73c0fc 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<RequiredAction> requiredActions = user.getRequiredActions();
         if (!requiredActions.isEmpty()) {
-            accessCode.setRequiredActions(new HashSet<UserModel.RequiredAction>(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<RoleModel> realmRoles = new LinkedList<RoleModel>();
             MultivaluedMap<String, RoleModel> resourceRoles = new MultivaluedMapImpl<String, RoleModel>();
@@ -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/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
index 1a03dc5..60988ca 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<RequiredAction> requiredActions = new HashSet<RequiredAction>(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<RequiredAction> 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 2411706..d1691c1 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 ef32859..917dd2d 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<String, String> res = new HashMap<String, String>();
+            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());
+                .detail(Details.REDIRECT_URI, redirect);
 
-        if (accessCodeEntry.isRememberMe()) {
-            audit.detail(Details.REMEMBER_ME, "true");
+        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");
+            }
         }
 
-        UserSessionModel userSession = session.sessions().getUserSession(realm, accessCodeEntry.getSessionState());
         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/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
index 59bb24b..3b57ca3 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 7c155fb..a9114eb 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 54f85e2..6b39c49 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 2bf8217..9972c48 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 b032c41..6bec2d8 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);