keycloak-aplcache

Merge pull request #230 from stianst/master KEYCLOAK-284

2/21/2014 7:55:25 AM

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
index c762ec0..5fc55f0 100755
--- a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
@@ -12,6 +12,7 @@ import java.util.Map;
 public class UserRepresentation {
 
     protected String self; // link
+    protected String id;
     protected String username;
     protected boolean enabled;
     protected boolean totp;
@@ -31,6 +32,14 @@ public class UserRepresentation {
         this.self = self;
     }
 
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
     public String getFirstName() {
         return firstName;
     }
diff --git a/core/src/main/java/org/keycloak/representations/JsonWebToken.java b/core/src/main/java/org/keycloak/representations/JsonWebToken.java
index c5ca3f1..b60d0ab 100755
--- a/core/src/main/java/org/keycloak/representations/JsonWebToken.java
+++ b/core/src/main/java/org/keycloak/representations/JsonWebToken.java
@@ -120,8 +120,8 @@ public class JsonWebToken implements Serializable {
         return subject;
     }
 
-    public JsonWebToken principal(String principal) {
-        this.subject = principal;
+    public JsonWebToken subject(String subject) {
+        this.subject = subject;
         return this;
     }
 
diff --git a/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java b/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java
index a0c6968..7fe682a 100755
--- a/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java
+++ b/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java
@@ -136,8 +136,8 @@ public class SkeletonKeyToken extends JsonWebToken {
     }
 
     @Override
-    public SkeletonKeyToken principal(String principal) {
-        return (SkeletonKeyToken) super.principal(principal);
+    public SkeletonKeyToken subject(String subject) {
+        return (SkeletonKeyToken) super.subject(subject);
     }
 
     @Override
diff --git a/core/src/test/java/org/keycloak/RSAVerifierTest.java b/core/src/test/java/org/keycloak/RSAVerifierTest.java
index ca0f46f..546cf70 100755
--- a/core/src/test/java/org/keycloak/RSAVerifierTest.java
+++ b/core/src/test/java/org/keycloak/RSAVerifierTest.java
@@ -70,7 +70,7 @@ public class RSAVerifierTest {
     public void initTest() {
 
         token = new SkeletonKeyToken();
-        token.principal("CN=Client")
+        token.subject("CN=Client")
                 .audience("domain")
                 .addAccess("service").addRole("admin");
     }
@@ -212,7 +212,7 @@ public class RSAVerifierTest {
     @Test
     public void testTokenAuth() throws Exception {
         token = new SkeletonKeyToken();
-        token.principal("CN=Client")
+        token.subject("CN=Client")
                 .audience("domain")
                 .addAccess("service").addRole("admin").verifyCaller(true);
 
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 2e247d7..6f22121 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -84,6 +84,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
 
     UserModel getUserByEmail(String email);
 
+    UserModel getUserById(String name);
+
     UserModel addUser(String username);
 
     boolean removeUser(String name);
diff --git a/model/api/src/main/java/org/keycloak/models/UserModel.java b/model/api/src/main/java/org/keycloak/models/UserModel.java
index 7e33185..b86ee77 100755
--- a/model/api/src/main/java/org/keycloak/models/UserModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserModel.java
@@ -13,6 +13,8 @@ public interface UserModel {
     public static final String FIRST_NAME = "firstName";
     public static final String EMAIL = "email";
 
+    String getId();
+
     String getLoginName();
 
     boolean isEnabled();
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 7fbc340..a4a6cb7 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -419,6 +419,11 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
+    public UserModel getUserById(String id) {
+        return new UserAdapter(em.find(UserEntity.class, id));
+    }
+
+    @Override
     public UserModel addUser(String username) {
         UserEntity entity = new UserEntity();
         entity.setLoginName(username);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
index 9f822d8..6c2bf30 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -25,6 +25,11 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
+    public String getId() {
+        return user.getId();
+    }
+
+    @Override
     public String getLoginName() {
         return user.getLoginName();
     }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 2d23090..91aa0bf 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -304,6 +304,21 @@ public class RealmAdapter extends AbstractAdapter implements RealmModel {
     }
 
     @Override
+    public UserModel getUserById(String id) {
+        DBObject query = new QueryBuilder()
+                .and("id").is(id)
+                .and("realmId").is(getId())
+                .get();
+        UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
+
+        if (user == null) {
+            return null;
+        } else {
+            return new UserAdapter(user, invocationContext);
+        }
+    }
+
+    @Override
     public UserAdapter addUser(String username) {
         UserAdapter userModel = addUserEntity(username);
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
index 1a18387..2276313 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
@@ -28,6 +28,11 @@ public class UserAdapter extends AbstractAdapter implements UserModel {
     }
 
     @Override
+    public String getId() {
+        return user.getId();
+    }
+
+    @Override
     public String getLoginName() {
         return user.getLoginName();
     }
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 08abe26..4008fa1 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -40,11 +40,11 @@ public class AuthenticationManager {
     public static final String FORM_USERNAME = "username";
     public static final String KEYCLOAK_IDENTITY_COOKIE = "KEYCLOAK_IDENTITY";
 
-    public SkeletonKeyToken createIdentityToken(RealmModel realm, String username) {
+    public SkeletonKeyToken createIdentityToken(RealmModel realm, UserModel user) {
         SkeletonKeyToken token = new SkeletonKeyToken();
         token.id(KeycloakModelUtils.generateId());
         token.issuedNow();
-        token.principal(username);
+        token.subject(user.getId());
         token.audience(realm.getName());
         if (realm.getTokenLifespan() > 0) {
             token.expiration((System.currentTimeMillis() / 1000) + realm.getTokenLifespan());
@@ -73,7 +73,7 @@ public class AuthenticationManager {
     }
 
     protected NewCookie createLoginCookie(RealmModel realm, UserModel user, UserModel client, String cookieName, String cookiePath) {
-        SkeletonKeyToken identityToken = createIdentityToken(realm, user.getLoginName());
+        SkeletonKeyToken identityToken = createIdentityToken(realm, user);
         if (client != null) {
             identityToken.issuedFor(client.getLoginName());
         }
@@ -177,7 +177,7 @@ public class AuthenticationManager {
 
             Auth auth = new Auth(token);
 
-            UserModel user = realm.getUser(token.getSubject());
+            UserModel user = realm.getUserById(token.getSubject());
             if (user == null || !user.isEnabled()) {
                 logger.debug("Unknown user in identity cookie");
                 expireIdentityCookie(realm, uriInfo);
@@ -224,7 +224,7 @@ public class AuthenticationManager {
 
             Auth auth = new Auth(token);
 
-            UserModel user = realm.getUser(token.getSubject());
+            UserModel user = realm.getUserById(token.getSubject());
             if (user == null || !user.isEnabled()) {
                 throw new NotAuthorizedException("invalid_user");
             }
diff --git a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
index a8e3609..d2bacba 100755
--- a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
+++ b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
@@ -25,6 +25,7 @@ import java.util.Map;
 public class ModelToRepresentation {
     public static UserRepresentation toRepresentation(UserModel user) {
         UserRepresentation rep = new UserRepresentation();
+        rep.setId(user.getId());
         rep.setUsername(user.getLoginName());
         rep.setLastName(user.getLastName());
         rep.setFirstName(user.getFirstName());
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 a7eeb86..48644b0 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -3,7 +3,6 @@ package org.keycloak.services.managers;
 import org.jboss.resteasy.logging.Logger;
 import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.Constants;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
@@ -16,7 +15,6 @@ import org.keycloak.util.JsonSerialization;
 import javax.ws.rs.core.MultivaluedMap;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -136,7 +134,7 @@ public class TokenManager {
     protected SkeletonKeyToken initToken(RealmModel realm, UserModel client, UserModel user) {
         SkeletonKeyToken token = new SkeletonKeyToken();
         token.id(KeycloakModelUtils.generateId());
-        token.principal(user.getLoginName());
+        token.subject(user.getId());
         token.audience(realm.getName());
         token.issuedNow();
         token.issuedFor(client.getLoginName());
@@ -224,7 +222,7 @@ public class TokenManager {
         SkeletonKeyToken token = new SkeletonKeyToken();
         token.id(KeycloakModelUtils.generateId());
         token.issuedNow();
-        token.principal(user.getLoginName());
+        token.subject(user.getId());
         token.audience(realm.getName());
         if (realm.getTokenLifespan() > 0) {
             token.expiration((System.currentTimeMillis() / 1000) + realm.getTokenLifespan());
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 b7d3bd7..1d0f0b5 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -28,6 +28,7 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
@@ -139,7 +140,7 @@ public class SocialResource {
             return oauth.forwardToSecurityFailure("Failed to process social callback");
         }
 
-        SocialLinkModel socialLink = new SocialLinkModel(provider.getId(), socialUser.getUsername());
+        SocialLinkModel socialLink = new SocialLinkModel(provider.getId(), socialUser.getId());
         UserModel user = realm.getUserBySocialLink(socialLink);
 
         if (user == null) {
@@ -147,24 +148,14 @@ public class SocialResource {
                 return oauth.forwardToSecurityFailure("Registration not allowed");
             }
 
-            // Automatically register user into realm with his social username (don't redirect to registration screen)
-            if (realm.getUser(socialUser.getUsername()) != null) {
-                // TODO: Username is already in realm. Show message and let user to bind accounts after he re-authenticate
-                throw new IllegalStateException("Username " + socialUser.getUsername() +
-                        " already registered in the realm. TODO: bind accounts...");
-
-                // TODO: Maybe we should search also by email and bind accounts if user with this email is
-                // already registered. But actually Keycloak allows duplicate emails
-            } else {
-                user = realm.addUser(socialUser.getUsername());
-                user.setEnabled(true);
-                user.setFirstName(socialUser.getFirstName());
-                user.setLastName(socialUser.getLastName());
-                user.setEmail(socialUser.getEmail());
-
-                if (realm.isUpdateProfileOnInitialSocialLogin()) {
-                    user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
-                }
+            user = realm.addUser(KeycloakModelUtils.generateId());
+            user.setEnabled(true);
+            user.setFirstName(socialUser.getFirstName());
+            user.setLastName(socialUser.getLastName());
+            user.setEmail(socialUser.getEmail());
+
+            if (realm.isUpdateProfileOnInitialSocialLogin()) {
+                user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
             }
 
             realm.addSocialLink(user, socialLink);
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 7279f45..f543a13 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -154,7 +154,7 @@ public class TokenService {
         }
 
         tokenManager = new TokenManager();
-        SkeletonKeyToken token = authManager.createIdentityToken(realm, username);
+        SkeletonKeyToken token = authManager.createIdentityToken(realm, user);
         String encoded = tokenManager.encodeToken(realm, token);
         AccessTokenResponse res = accessTokenResponse(token, encoded);
         return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
diff --git a/social/core/src/main/java/org/keycloak/social/SocialUser.java b/social/core/src/main/java/org/keycloak/social/SocialUser.java
index f9485d6..2c69456 100644
--- a/social/core/src/main/java/org/keycloak/social/SocialUser.java
+++ b/social/core/src/main/java/org/keycloak/social/SocialUser.java
@@ -3,7 +3,6 @@ package org.keycloak.social;
 public class SocialUser {
     
     private String id;
-    private String username;
     private String firstName;
     private String lastName;
     private String email;
@@ -20,30 +19,29 @@ public class SocialUser {
         this.id = id;
     }
 
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
     public String getFirstName() {
         return firstName;
     }
 
-    public void setFirstName(String firstName) {
+    public void setName(String name) {
+        int i = name.lastIndexOf(' ');
+        if (i != -1) {
+            firstName  = name.substring(0, i);
+            lastName = name.substring(i + 1);
+        } else {
+            firstName = name;
+        }
+    }
+
+    public void setName(String firstName, String lastName) {
         this.firstName = firstName;
+        this.lastName = lastName;
     }
 
     public String getLastName() {
         return lastName;
     }
 
-    public void setLastName(String lastName) {
-        this.lastName = lastName;
-    }
-
     public String getEmail() {
         return email;
     }
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
index dd2d7e3..cc62c52 100755
--- a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
@@ -53,14 +53,7 @@ public class FacebookProvider extends AbstractOAuth2Provider {
             JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
 
             SocialUser user = new SocialUser(profile.getString("id"));
-
-            user.setUsername(profile.getString("username"));
-            if (user.getUsername() == null || user.getUsername().length() == 0) {
-                user.setUsername(profile.getString("id"));
-            }
-
-            user.setFirstName(profile.optString("first_name"));
-            user.setLastName(profile.optString("last_name"));
+            user.setName(profile.optString("first_name"), profile.optString("last_name"));
             user.setEmail(profile.optString("email"));
 
             return user;
diff --git a/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java b/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java
index 9ea0096..ad38dcd 100755
--- a/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java
+++ b/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java
@@ -53,9 +53,7 @@ public class GitHubProvider extends AbstractOAuth2Provider {
             JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
 
             SocialUser user = new SocialUser(profile.get("id").toString());
-
-            user.setUsername(profile.getString("login"));
-            user.setFirstName(profile.optString("name"));
+            user.setName(profile.optString("name"));
             user.setEmail(profile.optString("email"));
 
             return user;
diff --git a/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java b/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java
index 2db4a9c..08b1104 100755
--- a/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java
+++ b/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java
@@ -72,11 +72,7 @@ public class GoogleProvider extends AbstractOAuth2Provider {
             JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
 
             SocialUser user = new SocialUser(profile.getString("sub"));
-
-            user.setUsername(profile.getString("email"));
-
-            user.setFirstName(profile.optString("given_name"));
-            user.setLastName(profile.optString("family_name"));
+            user.setName(profile.optString("given_name"), profile.optString("family_name"));
             user.setEmail(profile.optString("email"));
 
             return user;
diff --git a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
index b3b07db..fda4c6a 100755
--- a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
+++ b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
@@ -78,18 +78,7 @@ public class TwitterProvider implements SocialProvider {
             twitter4j.User twitterUser = twitter.verifyCredentials();
 
             SocialUser user = new SocialUser(Long.toString(twitterUser.getId()));
-
-            // Use screenName as username for Twitter
-            user.setUsername(twitterUser.getScreenName());
-
-            String twitterName = twitterUser.getName();
-            int spaceIndex = twitterName.lastIndexOf(' ');
-            if (spaceIndex != -1) {
-                user.setFirstName(twitterName.substring(0, spaceIndex));
-                user.setLastName(twitterName.substring(spaceIndex + 1));
-            } else {
-                user.setFirstName(twitterName);
-            }
+            user.setName(twitterUser.getName());
 
             return user;
         } catch (Exception e) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
index dfb2fc9..ff91229 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
@@ -95,7 +95,7 @@ public class CompositeImportRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("APP_COMPOSITE_USER", token.getSubject());
+        Assert.assertEquals("APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
@@ -120,7 +120,7 @@ public class CompositeImportRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_APP_COMPOSITE_USER", token.getSubject());
+        Assert.assertEquals("REALM_APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
@@ -144,7 +144,7 @@ public class CompositeImportRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", token.getSubject());
+        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(2, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
@@ -167,7 +167,7 @@ public class CompositeImportRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", token.getSubject());
+        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
@@ -189,7 +189,7 @@ public class CompositeImportRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_ROLE_1_USER", token.getSubject());
+        Assert.assertEquals("REALM_ROLE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
index 852f840..45162be 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
@@ -166,7 +166,7 @@ public class CompositeRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("APP_COMPOSITE_USER", token.getSubject());
+        Assert.assertEquals("APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
@@ -191,7 +191,7 @@ public class CompositeRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_APP_COMPOSITE_USER", token.getSubject());
+        Assert.assertEquals("REALM_APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
@@ -215,7 +215,7 @@ public class CompositeRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", token.getSubject());
+        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(2, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
@@ -238,7 +238,7 @@ public class CompositeRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", token.getSubject());
+        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
@@ -260,13 +260,10 @@ public class CompositeRoleTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_ROLE_1_USER", token.getSubject());
+        Assert.assertEquals("REALM_ROLE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
     }
 
-
-
-
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
index 5e5bd1d..ee4607e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
@@ -44,8 +44,8 @@ public class DummySocial implements SocialProvider {
 
         String username = callback.getQueryParam("username");
         SocialUser user = new SocialUser(username);
-        user.setEmail(username + "@dummy-social");
-        user.setUsername(username);
+        user.setName(callback.getQueryParam("firstname"), callback.getQueryParam("lastname"));
+        user.setEmail(callback.getQueryParam("email"));
         return user;
     }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
index fe55e34..9278d36 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
@@ -23,6 +23,9 @@ public class DummySocialServlet extends HttpServlet {
         pw.print("<body>");
         pw.print("<form method=\"post\">");
         pw.print("<label for=\"username\">Username</label><input type=\"text\" id=\"username\" name=\"username\" />");
+        pw.print("<label for=\"firstname\">First Name</label><input type=\"text\" id=\"firstname\" name=\"firstname\" />");
+        pw.print("<label for=\"lastname\">Last Name</label><input type=\"text\" id=\"lastname\" name=\"lastname\" />");
+        pw.print("<label for=\"email\">Email</label><input type=\"text\" id=\"email\" name=\"email\" />");
         pw.print("<input type=\"submit\" id=\"submit\" value=\"login\" />");
         pw.print("</form>");
         pw.print("</body>");
@@ -51,6 +54,16 @@ public class DummySocialServlet extends HttpServlet {
         }
 
         String redirect = redirectUri + "?username=" + req.getParameter("username") + "&state=" + state + "&code=" + UUID.randomUUID().toString();
+        if (req.getParameter("firstname") != null) {
+            redirect += "&firstname=" + req.getParameter("firstname");
+        }
+        if (req.getParameter("lastname") != null) {
+            redirect += "&lastname=" + req.getParameter("lastname");
+        }
+        if (req.getParameter("email") != null) {
+            redirect += "&email=" + req.getParameter("email");
+        }
+
         resp.sendRedirect(redirect);
     }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 2dfdde3..99aad82 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -26,6 +26,7 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.representations.SkeletonKeyToken;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
 import org.keycloak.testsuite.pages.LoginPage;
@@ -69,7 +70,11 @@ public class AccessTokenTest {
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("test-user@localhost", token.getSubject());
+        UserRepresentation user = oauth.getProfile(response.getAccessToken());
+
+        Assert.assertEquals(user.getId(), token.getSubject());
+        Assert.assertNotEquals("test-user@localhost", token.getSubject());
+        Assert.assertEquals("test-user@localhost", user.getUsername());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("user"));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index e92b223..f9897e5 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -22,12 +22,15 @@
 package org.keycloak.testsuite;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpHeaders;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.entity.ContentType;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.message.BasicNameValuePair;
 import org.jboss.resteasy.security.PemUtils;
@@ -35,6 +38,7 @@ import org.json.JSONObject;
 import org.junit.Assert;
 import org.keycloak.RSATokenVerifier;
 import org.keycloak.VerificationException;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.util.BasicAuthHelper;
 import org.keycloak.util.JsonSerialization;
 import org.keycloak.representations.SkeletonKeyScope;
@@ -145,6 +149,20 @@ public class OAuthClient {
         }
     }
 
+    public UserRepresentation getProfile(String token) {
+        HttpClient client = new DefaultHttpClient();
+        HttpGet get = new HttpGet(baseUrl + "/realms/" + realm + "/account");
+        get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token);
+        get.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType());
+
+        try {
+            HttpResponse response = client.execute(get);
+            return JsonSerialization.readValue(response.getEntity().getContent(), UserRepresentation.class);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to retrieve profile", e);
+        }
+    }
+
     public SkeletonKeyToken verifyToken(String token) {
         try {
             return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
index dd5c033..8540683 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
@@ -21,22 +21,14 @@
  */
 package org.keycloak.testsuite.rule;
 
-import io.undertow.servlet.api.DeploymentInfo;
-import io.undertow.servlet.api.ServletInfo;
-import org.junit.rules.ExternalResource;
-import org.keycloak.util.JsonSerialization;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.ApplicationServlet;
-import org.keycloak.testutils.KeycloakServer;
-
-import javax.servlet.Servlet;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
index d1b3d51..95d59be 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
@@ -28,6 +28,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.models.RealmModel;
 import org.keycloak.representations.SkeletonKeyToken;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.DummySocialServlet;
 import org.keycloak.testsuite.OAuthClient;
@@ -94,7 +95,10 @@ public class SocialLoginTest {
 
         loginPage.clickSocial("dummy");
 
-        driver.findElement(By.id("username")).sendKeys("dummy-user");
+        driver.findElement(By.id("username")).sendKeys("dummy-user1");
+        driver.findElement(By.id("firstname")).sendKeys("Bob");
+        driver.findElement(By.id("lastname")).sendKeys("Builder");
+        driver.findElement(By.id("email")).sendKeys("bob@builder.com");
         driver.findElement(By.id("submit")).click();
 
         Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -102,8 +106,14 @@ public class SocialLoginTest {
         AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get("code"), "password");
 
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
+        Assert.assertEquals(36, token.getSubject().length());
 
-        Assert.assertEquals("dummy-user", token.getSubject());
+        UserRepresentation profile = oauth.getProfile(response.getAccessToken());
+        Assert.assertEquals(36, profile.getUsername().length());
+
+        Assert.assertEquals("Bob", profile.getFirstName());
+        Assert.assertEquals("Builder", profile.getLastName());
+        Assert.assertEquals("bob@builder.com", profile.getEmail());
     }
 
     @Test
@@ -120,18 +130,28 @@ public class SocialLoginTest {
 
             loginPage.clickSocial("dummy");
 
-            driver.findElement(By.id("username")).sendKeys("dummy-user-reg");
+            driver.findElement(By.id("username")).sendKeys("dummy-user2");
+            driver.findElement(By.id("firstname")).sendKeys("Bob");
+            driver.findElement(By.id("lastname")).sendKeys("Builder");
+            driver.findElement(By.id("email")).sendKeys("bob@builder.com");
             driver.findElement(By.id("submit")).click();
 
             profilePage.isCurrent();
 
-            Assert.assertEquals("", profilePage.getFirstName());
-            Assert.assertEquals("", profilePage.getLastName());
-            Assert.assertEquals("dummy-user-reg@dummy-social", profilePage.getEmail());
+            Assert.assertEquals("Bob", profilePage.getFirstName());
+            Assert.assertEquals("Builder", profilePage.getLastName());
+            Assert.assertEquals("bob@builder.com", profilePage.getEmail());
 
             profilePage.update("Dummy", "User", "dummy-user-reg@dummy-social");
 
             Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+            AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get("code"), "password");
+            UserRepresentation profile = oauth.getProfile(response.getAccessToken());
+
+            Assert.assertEquals("Dummy", profile.getFirstName());
+            Assert.assertEquals("User", profile.getLastName());
+            Assert.assertEquals("dummy-user-reg@dummy-social", profile.getEmail());
         } finally {
             keycloakRule.configure(new KeycloakSetup() {
                 @Override