KEYCLOAK-1150
'iss' should be URL not just realm name
This commit is contained in:
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);
|
||||
}
|
||||
|
||||
+2
-1
@@ -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);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user