mirror of
https://github.com/keycloak/keycloak.git
synced 2026-02-11 17:59:09 -06:00
Merge pull request #1111 from patriot1burke/master
expire cookie on backchannel
This commit is contained in:
@@ -431,6 +431,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
logoutServiceUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);
|
||||
}
|
||||
if (logoutServiceUrl == null && client instanceof ApplicationModel) logoutServiceUrl = ((ApplicationModel)client).getManagementUrl();
|
||||
if (logoutServiceUrl == null || logoutServiceUrl.trim().equals("")) return null;
|
||||
return ResourceAdminManager.resolveUri(uriInfo.getRequestUri(), logoutServiceUrl);
|
||||
|
||||
}
|
||||
|
||||
@@ -85,14 +85,29 @@ public class AuthenticationManager {
|
||||
return userSession != null && userSession.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout() > currentTime && max > currentTime;
|
||||
}
|
||||
|
||||
public static void expireUserSessionCookie(KeycloakSession session, UserSessionModel userSession, RealmModel realm, UriInfo uriInfo, HttpHeaders headers, ClientConnection connection) {
|
||||
try {
|
||||
// check to see if any identity cookie is set with the same session and expire it if necessary
|
||||
Cookie cookie = headers.getCookies().get(KEYCLOAK_IDENTITY_COOKIE);
|
||||
if (cookie == null) return;
|
||||
String tokenString = cookie.getValue();
|
||||
AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()), false);
|
||||
UserSessionModel cookieSession = session.sessions().getUserSession(realm, token.getSessionState());
|
||||
if (cookieSession == null || !cookieSession.getId().equals(userSession.getId())) return;
|
||||
expireIdentityCookie(realm, uriInfo, connection);
|
||||
expireRememberMeCookie(realm, uriInfo, connection);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void backchannelLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
|
||||
if (userSession == null) return;
|
||||
UserModel user = userSession.getUser();
|
||||
userSession.setState(UserSessionModel.State.LOGGING_OUT);
|
||||
|
||||
logger.debugv("Logging out: {0} ({1})", user.getUsername(), userSession.getId());
|
||||
//expireIdentityCookie(realm, uriInfo, connection);
|
||||
//expireRememberMeCookie(realm, uriInfo, connection);
|
||||
expireUserSessionCookie(session, userSession, realm, uriInfo, headers, connection);
|
||||
|
||||
for (ClientSessionModel clientSession : userSession.getClientSessions()) {
|
||||
ClientModel client = clientSession.getClient();
|
||||
@@ -293,7 +308,7 @@ public class AuthenticationManager {
|
||||
return authenticateIdentityCookie(session, realm, uriInfo, connection, headers, true);
|
||||
}
|
||||
|
||||
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers, boolean checkActive) {
|
||||
public static AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers, boolean checkActive) {
|
||||
Cookie cookie = headers.getCookies().get(KEYCLOAK_IDENTITY_COOKIE);
|
||||
if (cookie == null || "".equals(cookie.getValue())) {
|
||||
logger.debugv("Could not find cookie: {0}", KEYCLOAK_IDENTITY_COOKIE);
|
||||
@@ -443,7 +458,7 @@ public class AuthenticationManager {
|
||||
}
|
||||
}
|
||||
|
||||
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) {
|
||||
protected static AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) {
|
||||
try {
|
||||
AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()), checkActive);
|
||||
if (checkActive) {
|
||||
@@ -594,7 +609,7 @@ public class AuthenticationManager {
|
||||
SUCCESS, ACCOUNT_TEMPORARILY_DISABLED, ACCOUNT_DISABLED, ACTIONS_REQUIRED, INVALID_USER, INVALID_CREDENTIALS, MISSING_PASSWORD, MISSING_TOTP, FAILED
|
||||
}
|
||||
|
||||
public class AuthResult {
|
||||
public static class AuthResult {
|
||||
private final UserModel user;
|
||||
private final UserSessionModel session;
|
||||
private final AccessToken token;
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.keycloak.models.OAuthClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.TokenManager;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.services.managers.AppAuthManager;
|
||||
@@ -492,7 +493,11 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||
String username = updatedIdentity.getUsername();
|
||||
if (this.realmModel.isRegistrationEmailAsUsername() && !Validation.isEmpty(updatedIdentity.getEmail())) {
|
||||
username = updatedIdentity.getEmail();
|
||||
}
|
||||
} else if (username == null) {
|
||||
username = updatedIdentity.getIdentityProviderId() + "." + updatedIdentity.getId();
|
||||
} else {
|
||||
username = updatedIdentity.getIdentityProviderId() + "." + updatedIdentity.getUsername();
|
||||
}
|
||||
if (username != null) {
|
||||
username = username.trim();
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ public class AccountTest {
|
||||
});
|
||||
}
|
||||
|
||||
//@Test @Ignore
|
||||
@Test @Ignore
|
||||
public void runit() throws Exception {
|
||||
Thread.sleep(10000000);
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ public class AdapterTestStrategy extends ExternalResource {
|
||||
});
|
||||
Integer custSessionsCount = stats.get("customer-portal");
|
||||
Assert.assertNotNull(custSessionsCount);
|
||||
Assert.assertTrue(1 == custSessionsCount);
|
||||
Assert.assertEquals(1, custSessionsCount.intValue());
|
||||
Integer prodStatsCount = stats.get("product-portal");
|
||||
Assert.assertNotNull(prodStatsCount);
|
||||
Assert.assertTrue(1 == prodStatsCount);
|
||||
|
||||
@@ -250,7 +250,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||
}
|
||||
|
||||
protected void doAssertFederatedUserNoEmail(UserModel federatedUser) {
|
||||
assertEquals("test-user-noemail", federatedUser.getUsername());
|
||||
assertEquals("kc-oidc-idp.test-user-noemail", federatedUser.getUsername());
|
||||
assertEquals(null, federatedUser.getEmail());
|
||||
assertEquals("Test", federatedUser.getFirstName());
|
||||
assertEquals("User", federatedUser.getLastName());
|
||||
@@ -580,7 +580,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||
FederatedIdentityModel federatedIdentityModel = federatedIdentities.iterator().next();
|
||||
|
||||
assertEquals(getProviderId(), federatedIdentityModel.getIdentityProvider());
|
||||
assertEquals(federatedUser.getUsername(), federatedIdentityModel.getUserName());
|
||||
assertEquals(federatedUser.getUsername(), federatedIdentityModel.getIdentityProvider() + "." + federatedIdentityModel.getUserName());
|
||||
|
||||
driver.navigate().to("http://localhost:8081/test-app/logout");
|
||||
driver.navigate().to("http://localhost:8081/test-app");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.AccessTokenResponse;
|
||||
@@ -66,4 +67,29 @@ public class OIDCKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
|
||||
protected String getProviderId() {
|
||||
return "kc-oidc-idp";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulAuthentication() {
|
||||
super.testSuccessfulAuthentication();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulAuthenticationWithoutUpdateProfile() {
|
||||
super.testSuccessfulAuthenticationWithoutUpdateProfile();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailNotProvided_emailVerifyEnabled() {
|
||||
super.testSuccessfulAuthenticationWithoutUpdateProfile_emailNotProvided_emailVerifyEnabled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername() {
|
||||
super.testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername_emailNotProvided() {
|
||||
super.testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername_emailNotProvided();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SAMLKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
|
||||
|
||||
@Override
|
||||
protected void doAssertFederatedUserNoEmail(UserModel federatedUser) {
|
||||
assertEquals("", federatedUser.getUsername());
|
||||
assertEquals("kc-saml-idp-basic.", federatedUser.getUsername());
|
||||
assertEquals("", federatedUser.getEmail());
|
||||
assertEquals(null, federatedUser.getFirstName());
|
||||
assertEquals(null, federatedUser.getLastName());
|
||||
|
||||
@@ -68,7 +68,7 @@ public class SAMLKeyCloakServerBrokerWithSignatureTest extends AbstractIdentityP
|
||||
|
||||
@Override
|
||||
protected void doAssertFederatedUserNoEmail(UserModel federatedUser) {
|
||||
assertEquals("", federatedUser.getUsername());
|
||||
assertEquals("kc-saml-signed-idp.", federatedUser.getUsername());
|
||||
assertEquals("", federatedUser.getEmail());
|
||||
assertEquals(null, federatedUser.getFirstName());
|
||||
assertEquals(null, federatedUser.getLastName());
|
||||
|
||||
Reference in New Issue
Block a user