KEYCLOAK-1150

'iss' should be URL not just realm name
This commit is contained in:
Stian Thorgersen committed 2015-03-26 13:50:36 +01:00
1 parent d36ee0d0af
commit b727087f04
36 files changed
+1041 -978

No files matched your search

@@ -59,6 +59,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
public static final String PROMPT_PARAM = "prompt";
public static final String LOGIN_HINT_PARAM = "login_hint";
public static final String LOGOUT_REDIRECT_URI = "OIDC_LOGOUT_REDIRECT_URI";
public static final String ISSUER = "iss";
private static final Logger log = Logger.getLogger(OIDCLoginProtocol.class);
@@ -314,7 +314,7 @@ public class TokenManager {
token.audience(client.getClientId());
token.issuedNow();
token.issuedFor(client.getClientId());
token.issuer(realm.getName());
token.issuer(clientSession.getNote(OIDCLoginProtocol.ISSUER));
if (session != null) {
token.setSessionState(session.getId());
}
@@ -223,6 +223,7 @@ public class AuthorizationEndpoint {
clientSession.setNote(ClientSessionCode.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
clientSession.setNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM, responseType);
clientSession.setNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUriParam);
clientSession.setNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
if (state != null) clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
if (scope != null) clientSession.setNote(OIDCLoginProtocol.SCOPE_PARAM, scope);
@@ -29,6 +29,7 @@ import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.resources.Cors;
import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.Consumes;
import javax.ws.rs.OPTIONS;
@@ -319,6 +320,7 @@ public class TokenEndpoint {
ClientSessionModel clientSession = sessions.createClientSession(realm, client);
clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
clientSession.setNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
TokenManager.attachClientSession(userSession, clientSession);
@@ -39,6 +39,7 @@ import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.EventsManager;
import org.keycloak.services.resources.Cors;
import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
@@ -52,6 +53,7 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import java.util.HashMap;
import java.util.Map;
@@ -66,6 +68,9 @@ public class UserInfoEndpoint {
@Context
private HttpResponse response;
@Context
private UriInfo uriInfo;
@Context
private KeycloakSession session;
@@ -114,7 +119,7 @@ public class UserInfoEndpoint {
AccessToken token = null;
try {
token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
} catch (Exception e) {
throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "Token invalid", Status.FORBIDDEN);
}
@@ -15,6 +15,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.representations.AccessToken;
import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -68,7 +69,7 @@ public class ValidateTokenEndpoint {
event.event(EventType.VALIDATE_ACCESS_TOKEN);
AccessToken token = null;
try {
token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
} catch (Exception e) {
Map<String, String> err = new HashMap<String, String>();
err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT);
@@ -32,6 +32,7 @@ import org.keycloak.services.resources.IdentityBrokerService;
import org.keycloak.services.resources.LoginActionsService;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.services.resources.flows.Flows;
import org.keycloak.services.resources.flows.Urls;
import org.keycloak.services.util.CookieHelper;
import org.keycloak.services.validation.Validation;
import org.keycloak.util.Time;
@@ -192,12 +193,12 @@ public class AuthenticationManager {
}
public static AccessToken createIdentityToken(RealmModel realm, UserModel user, UserSessionModel session) {
public static AccessToken createIdentityToken(RealmModel realm, UserModel user, UserSessionModel session, String issuer) {
AccessToken token = new AccessToken();
token.id(KeycloakModelUtils.generateId());
token.issuedNow();
token.subject(user.getId());
token.issuer(realm.getName());
token.issuer(issuer);
if (session != null) {
token.setSessionState(session.getId());
}
@@ -209,7 +210,8 @@ public class AuthenticationManager {
public static void createLoginCookie(RealmModel realm, UserModel user, UserSessionModel session, UriInfo uriInfo, ClientConnection connection) {
String cookiePath = getIdentityCookiePath(realm, uriInfo);
AccessToken identityToken = createIdentityToken(realm, user, session);
String issuer = Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName());
AccessToken identityToken = createIdentityToken(realm, user, session, issuer);
String encoded = encodeToken(realm, identityToken);
boolean secureOnly = realm.getSslRequired().isRequired(connection);
int maxAge = NewCookie.DEFAULT_MAX_AGE;
@@ -443,7 +445,7 @@ public class AuthenticationManager {
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) {
try {
AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()), checkActive);
if (checkActive) {
if (!token.isActive() || token.getIssuedAt() < realm.getNotBefore()) {
logger.debug("identity cookie expired");
@@ -140,7 +140,7 @@ public class AdminRoot {
} catch (IOException e) {
throw new UnauthorizedException("Bearer token format error");
}
String realmName = token.getIssuer();
String realmName = token.getIssuer().substring(token.getIssuer().lastIndexOf('/') + 1);
RealmManager realmManager = new RealmManager(session);
RealmModel realm = realmManager.getRealmByName(realmName);
if (realm == null) {
@@ -158,6 +158,10 @@ public class Urls {
return requiredActionsBase(baseUri).path(LoginActionsService.class, "usernameReminder");
}
public static String realmIssuer(URI baseUri, String realmId) {
return realmBase(baseUri).path("{realm}").build(realmId).toString();
}
private static UriBuilder realmBase(URI baseUri) {
return UriBuilder.fromUri(baseUri).path(RealmsResource.class);
}