KEYCLOAK-284 Subject in token is now user id instead of username

This commit is contained in:
Stian Thorgersen 2014-02-21 09:47:08 +00:00
parent c2ca1b2731
commit 9ce8e16063
28 changed files with 161 additions and 109 deletions

View file

@ -120,8 +120,8 @@ public class JsonWebToken implements Serializable {
return subject; return subject;
} }
public JsonWebToken principal(String principal) { public JsonWebToken subject(String subject) {
this.subject = principal; this.subject = subject;
return this; return this;
} }

View file

@ -136,8 +136,8 @@ public class SkeletonKeyToken extends JsonWebToken {
} }
@Override @Override
public SkeletonKeyToken principal(String principal) { public SkeletonKeyToken subject(String subject) {
return (SkeletonKeyToken) super.principal(principal); return (SkeletonKeyToken) super.subject(subject);
} }
@Override @Override

View file

@ -12,6 +12,7 @@ import java.util.Map;
public class UserRepresentation { public class UserRepresentation {
protected String self; // link protected String self; // link
protected String id;
protected String username; protected String username;
protected boolean enabled; protected boolean enabled;
protected boolean totp; protected boolean totp;
@ -31,6 +32,14 @@ public class UserRepresentation {
this.self = self; this.self = self;
} }
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() { public String getFirstName() {
return firstName; return firstName;
} }

View file

@ -70,7 +70,7 @@ public class RSAVerifierTest {
public void initTest() { public void initTest() {
token = new SkeletonKeyToken(); token = new SkeletonKeyToken();
token.principal("CN=Client") token.subject("CN=Client")
.audience("domain") .audience("domain")
.addAccess("service").addRole("admin"); .addAccess("service").addRole("admin");
} }
@ -212,7 +212,7 @@ public class RSAVerifierTest {
@Test @Test
public void testTokenAuth() throws Exception { public void testTokenAuth() throws Exception {
token = new SkeletonKeyToken(); token = new SkeletonKeyToken();
token.principal("CN=Client") token.subject("CN=Client")
.audience("domain") .audience("domain")
.addAccess("service").addRole("admin").verifyCaller(true); .addAccess("service").addRole("admin").verifyCaller(true);

View file

@ -84,6 +84,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
UserModel getUserByEmail(String email); UserModel getUserByEmail(String email);
UserModel getUserById(String name);
UserModel addUser(String username); UserModel addUser(String username);
boolean removeUser(String name); boolean removeUser(String name);

View file

@ -13,6 +13,8 @@ public interface UserModel {
public static final String FIRST_NAME = "firstName"; public static final String FIRST_NAME = "firstName";
public static final String EMAIL = "email"; public static final String EMAIL = "email";
String getId();
String getLoginName(); String getLoginName();
boolean isEnabled(); boolean isEnabled();

View file

@ -418,6 +418,11 @@ public class RealmAdapter implements RealmModel {
return results.isEmpty()? null : new UserAdapter(results.get(0)); return results.isEmpty()? null : new UserAdapter(results.get(0));
} }
@Override
public UserModel getUserById(String id) {
return new UserAdapter(em.find(UserEntity.class, id));
}
@Override @Override
public UserModel addUser(String username) { public UserModel addUser(String username) {
UserEntity entity = new UserEntity(); UserEntity entity = new UserEntity();

View file

@ -24,6 +24,11 @@ public class UserAdapter implements UserModel {
return user; return user;
} }
@Override
public String getId() {
return user.getId();
}
@Override @Override
public String getLoginName() { public String getLoginName() {
return user.getLoginName(); return user.getLoginName();

View file

@ -303,6 +303,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 @Override
public UserAdapter addUser(String username) { public UserAdapter addUser(String username) {
UserAdapter userModel = addUserEntity(username); UserAdapter userModel = addUserEntity(username);

View file

@ -27,6 +27,11 @@ public class UserAdapter extends AbstractAdapter implements UserModel {
this.user = userEntity; this.user = userEntity;
} }
@Override
public String getId() {
return user.getId();
}
@Override @Override
public String getLoginName() { public String getLoginName() {
return user.getLoginName(); return user.getLoginName();

View file

@ -40,11 +40,11 @@ public class AuthenticationManager {
public static final String FORM_USERNAME = "username"; public static final String FORM_USERNAME = "username";
public static final String KEYCLOAK_IDENTITY_COOKIE = "KEYCLOAK_IDENTITY"; 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(); SkeletonKeyToken token = new SkeletonKeyToken();
token.id(KeycloakModelUtils.generateId()); token.id(KeycloakModelUtils.generateId());
token.issuedNow(); token.issuedNow();
token.principal(username); token.subject(user.getId());
token.audience(realm.getName()); token.audience(realm.getName());
if (realm.getTokenLifespan() > 0) { if (realm.getTokenLifespan() > 0) {
token.expiration((System.currentTimeMillis() / 1000) + realm.getTokenLifespan()); 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) { 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) { if (client != null) {
identityToken.issuedFor(client.getLoginName()); identityToken.issuedFor(client.getLoginName());
} }
@ -177,7 +177,7 @@ public class AuthenticationManager {
Auth auth = new Auth(token); Auth auth = new Auth(token);
UserModel user = realm.getUser(token.getSubject()); UserModel user = realm.getUserById(token.getSubject());
if (user == null || !user.isEnabled()) { if (user == null || !user.isEnabled()) {
logger.debug("Unknown user in identity cookie"); logger.debug("Unknown user in identity cookie");
expireIdentityCookie(realm, uriInfo); expireIdentityCookie(realm, uriInfo);
@ -224,7 +224,7 @@ public class AuthenticationManager {
Auth auth = new Auth(token); Auth auth = new Auth(token);
UserModel user = realm.getUser(token.getSubject()); UserModel user = realm.getUserById(token.getSubject());
if (user == null || !user.isEnabled()) { if (user == null || !user.isEnabled()) {
throw new NotAuthorizedException("invalid_user"); throw new NotAuthorizedException("invalid_user");
} }

View file

@ -25,6 +25,7 @@ import java.util.Map;
public class ModelToRepresentation { public class ModelToRepresentation {
public static UserRepresentation toRepresentation(UserModel user) { public static UserRepresentation toRepresentation(UserModel user) {
UserRepresentation rep = new UserRepresentation(); UserRepresentation rep = new UserRepresentation();
rep.setId(user.getId());
rep.setUsername(user.getLoginName()); rep.setUsername(user.getLoginName());
rep.setLastName(user.getLastName()); rep.setLastName(user.getLastName());
rep.setFirstName(user.getFirstName()); rep.setFirstName(user.getFirstName());

View file

@ -3,7 +3,6 @@ package org.keycloak.services.managers;
import org.jboss.resteasy.logging.Logger; import org.jboss.resteasy.logging.Logger;
import org.keycloak.jose.jws.JWSBuilder; import org.keycloak.jose.jws.JWSBuilder;
import org.keycloak.models.ApplicationModel; import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
@ -16,7 +15,6 @@ import org.keycloak.util.JsonSerialization;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -136,7 +134,7 @@ public class TokenManager {
protected SkeletonKeyToken initToken(RealmModel realm, UserModel client, UserModel user) { protected SkeletonKeyToken initToken(RealmModel realm, UserModel client, UserModel user) {
SkeletonKeyToken token = new SkeletonKeyToken(); SkeletonKeyToken token = new SkeletonKeyToken();
token.id(KeycloakModelUtils.generateId()); token.id(KeycloakModelUtils.generateId());
token.principal(user.getLoginName()); token.subject(user.getId());
token.audience(realm.getName()); token.audience(realm.getName());
token.issuedNow(); token.issuedNow();
token.issuedFor(client.getLoginName()); token.issuedFor(client.getLoginName());
@ -224,7 +222,7 @@ public class TokenManager {
SkeletonKeyToken token = new SkeletonKeyToken(); SkeletonKeyToken token = new SkeletonKeyToken();
token.id(KeycloakModelUtils.generateId()); token.id(KeycloakModelUtils.generateId());
token.issuedNow(); token.issuedNow();
token.principal(user.getLoginName()); token.subject(user.getId());
token.audience(realm.getName()); token.audience(realm.getName());
if (realm.getTokenLifespan() > 0) { if (realm.getTokenLifespan() > 0) {
token.expiration((System.currentTimeMillis() / 1000) + realm.getTokenLifespan()); token.expiration((System.currentTimeMillis() / 1000) + realm.getTokenLifespan());

View file

@ -28,6 +28,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.SocialLinkModel; import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.TokenManager; import org.keycloak.services.managers.TokenManager;
@ -139,7 +140,7 @@ public class SocialResource {
return oauth.forwardToSecurityFailure("Failed to process social callback"); 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); UserModel user = realm.getUserBySocialLink(socialLink);
if (user == null) { if (user == null) {
@ -147,16 +148,7 @@ public class SocialResource {
return oauth.forwardToSecurityFailure("Registration not allowed"); return oauth.forwardToSecurityFailure("Registration not allowed");
} }
// Automatically register user into realm with his social username (don't redirect to registration screen) user = realm.addUser(KeycloakModelUtils.generateId());
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.setEnabled(true);
user.setFirstName(socialUser.getFirstName()); user.setFirstName(socialUser.getFirstName());
user.setLastName(socialUser.getLastName()); user.setLastName(socialUser.getLastName());
@ -165,7 +157,6 @@ public class SocialResource {
if (realm.isUpdateProfileOnInitialSocialLogin()) { if (realm.isUpdateProfileOnInitialSocialLogin()) {
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE); user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
} }
}
realm.addSocialLink(user, socialLink); realm.addSocialLink(user, socialLink);
} }

View file

@ -154,7 +154,7 @@ public class TokenService {
} }
tokenManager = new TokenManager(); tokenManager = new TokenManager();
SkeletonKeyToken token = authManager.createIdentityToken(realm, username); SkeletonKeyToken token = authManager.createIdentityToken(realm, user);
String encoded = tokenManager.encodeToken(realm, token); String encoded = tokenManager.encodeToken(realm, token);
AccessTokenResponse res = accessTokenResponse(token, encoded); AccessTokenResponse res = accessTokenResponse(token, encoded);
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build(); return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();

View file

@ -3,7 +3,6 @@ package org.keycloak.social;
public class SocialUser { public class SocialUser {
private String id; private String id;
private String username;
private String firstName; private String firstName;
private String lastName; private String lastName;
private String email; private String email;
@ -20,30 +19,29 @@ public class SocialUser {
this.id = id; this.id = id;
} }
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirstName() { public String getFirstName() {
return firstName; 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.firstName = firstName;
this.lastName = lastName;
} }
public String getLastName() { public String getLastName() {
return lastName; return lastName;
} }
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() { public String getEmail() {
return email; return email;
} }

View file

@ -53,14 +53,7 @@ public class FacebookProvider extends AbstractOAuth2Provider {
JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson(); JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
SocialUser user = new SocialUser(profile.getString("id")); SocialUser user = new SocialUser(profile.getString("id"));
user.setName(profile.optString("first_name"), profile.optString("last_name"));
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.setEmail(profile.optString("email")); user.setEmail(profile.optString("email"));
return user; return user;

View file

@ -53,9 +53,7 @@ public class GitHubProvider extends AbstractOAuth2Provider {
JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson(); JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
SocialUser user = new SocialUser(profile.get("id").toString()); SocialUser user = new SocialUser(profile.get("id").toString());
user.setName(profile.optString("name"));
user.setUsername(profile.getString("login"));
user.setFirstName(profile.optString("name"));
user.setEmail(profile.optString("email")); user.setEmail(profile.optString("email"));
return user; return user;

View file

@ -72,11 +72,7 @@ public class GoogleProvider extends AbstractOAuth2Provider {
JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson(); JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
SocialUser user = new SocialUser(profile.getString("sub")); SocialUser user = new SocialUser(profile.getString("sub"));
user.setName(profile.optString("given_name"), profile.optString("family_name"));
user.setUsername(profile.getString("email"));
user.setFirstName(profile.optString("given_name"));
user.setLastName(profile.optString("family_name"));
user.setEmail(profile.optString("email")); user.setEmail(profile.optString("email"));
return user; return user;

View file

@ -78,18 +78,7 @@ public class TwitterProvider implements SocialProvider {
twitter4j.User twitterUser = twitter.verifyCredentials(); twitter4j.User twitterUser = twitter.verifyCredentials();
SocialUser user = new SocialUser(Long.toString(twitterUser.getId())); SocialUser user = new SocialUser(Long.toString(twitterUser.getId()));
user.setName(twitterUser.getName());
// 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);
}
return user; return user;
} catch (Exception e) { } catch (Exception e) {

View file

@ -44,8 +44,8 @@ public class DummySocial implements SocialProvider {
String username = callback.getQueryParam("username"); String username = callback.getQueryParam("username");
SocialUser user = new SocialUser(username); SocialUser user = new SocialUser(username);
user.setEmail(username + "@dummy-social"); user.setName(callback.getQueryParam("firstname"), callback.getQueryParam("lastname"));
user.setUsername(username); user.setEmail(callback.getQueryParam("email"));
return user; return user;
} }

View file

@ -23,6 +23,9 @@ public class DummySocialServlet extends HttpServlet {
pw.print("<body>"); pw.print("<body>");
pw.print("<form method=\"post\">"); pw.print("<form method=\"post\">");
pw.print("<label for=\"username\">Username</label><input type=\"text\" id=\"username\" name=\"username\" />"); 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("<input type=\"submit\" id=\"submit\" value=\"login\" />");
pw.print("</form>"); pw.print("</form>");
pw.print("</body>"); 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(); 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); resp.sendRedirect(redirect);
} }

View file

@ -22,12 +22,15 @@
package org.keycloak.testsuite; package org.keycloak.testsuite;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair; import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity; 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.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.BasicNameValuePair;
import org.jboss.resteasy.security.PemUtils; import org.jboss.resteasy.security.PemUtils;
@ -35,6 +38,7 @@ import org.json.JSONObject;
import org.junit.Assert; import org.junit.Assert;
import org.keycloak.RSATokenVerifier; import org.keycloak.RSATokenVerifier;
import org.keycloak.VerificationException; import org.keycloak.VerificationException;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.util.BasicAuthHelper; import org.keycloak.util.BasicAuthHelper;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
import org.keycloak.representations.SkeletonKeyScope; 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) { public SkeletonKeyToken verifyToken(String token) {
try { try {
return RSATokenVerifier.verifyToken(token, realmPublicKey, realm); return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);

View file

@ -95,7 +95,7 @@ public class CompositeImportRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
@ -120,7 +120,7 @@ public class CompositeImportRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1")); Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
@ -144,7 +144,7 @@ public class CompositeImportRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(2, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1")); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
@ -167,7 +167,7 @@ public class CompositeImportRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(1, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
@ -189,7 +189,7 @@ public class CompositeImportRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(1, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));

View file

@ -166,7 +166,7 @@ public class CompositeRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
@ -191,7 +191,7 @@ public class CompositeRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1")); Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
@ -215,7 +215,7 @@ public class CompositeRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(2, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1")); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
@ -238,7 +238,7 @@ public class CompositeRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(1, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
@ -260,13 +260,10 @@ public class CompositeRoleTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(1, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
} }
} }

View file

@ -26,6 +26,7 @@ import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.representations.SkeletonKeyToken; import org.keycloak.representations.SkeletonKeyToken;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.OAuthClient; import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.OAuthClient.AccessTokenResponse; import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.LoginPage;
@ -69,7 +70,11 @@ public class AccessTokenTest {
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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.assertEquals(1, token.getRealmAccess().getRoles().size());
Assert.assertTrue(token.getRealmAccess().isUserInRole("user")); Assert.assertTrue(token.getRealmAccess().isUserInRole("user"));

View file

@ -21,22 +21,14 @@
*/ */
package org.keycloak.testsuite.rule; 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.Constants;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; 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.services.managers.RealmManager;
import org.keycloak.testsuite.ApplicationServlet; 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> * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>

View file

@ -28,6 +28,7 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.representations.SkeletonKeyToken; import org.keycloak.representations.SkeletonKeyToken;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.DummySocialServlet; import org.keycloak.testsuite.DummySocialServlet;
import org.keycloak.testsuite.OAuthClient; import org.keycloak.testsuite.OAuthClient;
@ -94,7 +95,10 @@ public class SocialLoginTest {
loginPage.clickSocial("dummy"); 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(); driver.findElement(By.id("submit")).click();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@ -102,8 +106,14 @@ public class SocialLoginTest {
AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get("code"), "password"); AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get("code"), "password");
SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); 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 @Test
@ -120,18 +130,28 @@ public class SocialLoginTest {
loginPage.clickSocial("dummy"); 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(); driver.findElement(By.id("submit")).click();
profilePage.isCurrent(); profilePage.isCurrent();
Assert.assertEquals("", profilePage.getFirstName()); Assert.assertEquals("Bob", profilePage.getFirstName());
Assert.assertEquals("", profilePage.getLastName()); Assert.assertEquals("Builder", profilePage.getLastName());
Assert.assertEquals("dummy-user-reg@dummy-social", profilePage.getEmail()); Assert.assertEquals("bob@builder.com", profilePage.getEmail());
profilePage.update("Dummy", "User", "dummy-user-reg@dummy-social"); profilePage.update("Dummy", "User", "dummy-user-reg@dummy-social");
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); 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 { } finally {
keycloakRule.configure(new KeycloakSetup() { keycloakRule.configure(new KeycloakSetup() {
@Override @Override