Started UserSessionProvider

This commit is contained in:
Stian Thorgersen committed 2014-07-10 16:48:25 +01:00
1 parent 38abcd4a90
commit 86671a2354
106 files changed
+1354 -2368

No files matched your search

@@ -3,6 +3,7 @@ package org.keycloak.services;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.ModelProvider;
import org.keycloak.models.UserSessionProvider;
import org.keycloak.models.cache.CacheModelProvider;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
@@ -75,10 +76,15 @@ public class DefaultKeycloakSession implements KeycloakSession {
return providers;
}
public ModelProvider getModel() {
public ModelProvider model() {
return model;
}
@Override
public UserSessionProvider sessions() {
return getProvider(UserSessionProvider.class);
}
public void close() {
for (Provider p : providers.values()) {
p.close();
@@ -14,15 +14,12 @@ import javax.ws.rs.core.UriInfo;
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AppAuthManager extends AuthenticationManager {
protected static Logger logger = Logger.getLogger(AppAuthManager.class);
public AppAuthManager(KeycloakSession session) {
super(session);
}
@Override
public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
AuthResult authResult = super.authenticateIdentityCookie(realm, uriInfo, headers);
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
AuthResult authResult = super.authenticateIdentityCookie(session, realm, uriInfo, headers);
if (authResult == null) return null;
Cookie remember = headers.getCookies().get(AuthenticationManager.KEYCLOAK_REMEMBER_ME);
boolean rememberMe = remember != null;
@@ -44,10 +41,10 @@ public class AppAuthManager extends AuthenticationManager {
return tokenString;
}
public AuthResult authenticateBearerToken(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
public AuthResult authenticateBearerToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
String tokenString = extractAuthorizationHeaderToken(headers);
if (tokenString == null) return null;
AuthResult authResult = verifyIdentityToken(realm, uriInfo, true, tokenString);
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, true, tokenString);
return authResult;
}
@@ -8,7 +8,6 @@ import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ModelProvider;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
@@ -40,7 +39,7 @@ public class ApplianceBootstrap {
public void bootstrap(KeycloakSession session, String contextPath) {
String adminRealmName = Config.getAdminRealm();
if (session.getModel().getRealm(adminRealmName) != null) {
if (session.model().getRealm(adminRealmName) != null) {
return;
}
@@ -10,6 +10,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionProvider;
import org.keycloak.representations.adapters.config.BaseRealmConfig;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
@@ -150,6 +151,18 @@ public class ApplicationManager {
return app;
}
public boolean removeApplication(RealmModel realm, ApplicationModel application) {
if (realm.removeApplication(application.getId())) {
UserSessionProvider sessions = realmManager.getSession().sessions();
if (sessions != null) {
sessions.onClientRemoved(realm, application);
}
return true;
} else {
return false;
}
}
public UserCredentialModel generateSecret(ApplicationModel app) {
UserCredentialModel secret = UserCredentialModel.generateSecret();
app.setSecret(secret.getValue());
@@ -45,37 +45,34 @@ public class AuthenticationManager {
public static final String KEYCLOAK_SESSION_COOKIE = "KEYCLOAK_SESSION";
public static final String KEYCLOAK_REMEMBER_ME = "KEYCLOAK_REMEMBER_ME";
protected KeycloakSession session;
protected BruteForceProtector protector;
public AuthenticationManager(KeycloakSession session) {
this.session = session;
public AuthenticationManager() {
}
public AuthenticationManager(KeycloakSession session, BruteForceProtector protector) {
this.session = session;
public AuthenticationManager(BruteForceProtector protector) {
this.protector = protector;
}
public static boolean isSessionValid(RealmModel realm, UserSessionModel session) {
if (session == null) return false;
public static boolean isSessionValid(RealmModel realm, UserSessionModel userSession) {
if (userSession == null) return false;
int currentTime = Time.currentTime();
int max = session.getStarted() + realm.getSsoSessionMaxLifespan();
boolean valid = session != null && session.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout() > currentTime && max > currentTime;
int max = userSession.getStarted() + realm.getSsoSessionMaxLifespan();
boolean valid = userSession != null && userSession.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout() > currentTime && max > currentTime;
return valid;
}
public static void logout(RealmModel realm, UserSessionModel session, UriInfo uriInfo) {
if (session == null) return;
UserModel user = session.getUser();
public static void logout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo) {
if (userSession == null) return;
UserModel user = userSession.getUser();
logger.infov("Logging out: {0} ({1})", user.getUsername(), session.getId());
logger.infov("Logging out: {0} ({1})", user.getUsername(), userSession.getId());
realm.removeUserSession(session);
session.sessions().removeUserSession(realm, userSession);
expireIdentityCookie(realm, uriInfo);
expireRememberMeCookie(realm, uriInfo);
new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), session.getId());
new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), userSession.getId());
}
@@ -161,11 +158,11 @@ public class AuthenticationManager {
CookieHelper.addCookie(cookieName, "", path, null, "Expiring cookie", 0, secureOnly, httpOnly);
}
public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
return authenticateIdentityCookie(realm, uriInfo, headers, true);
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
return authenticateIdentityCookie(session, realm, uriInfo, headers, true);
}
public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers, boolean checkActive) {
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers, boolean checkActive) {
logger.info("authenticateIdentityCookie");
Cookie cookie = headers.getCookies().get(KEYCLOAK_IDENTITY_COOKIE);
if (cookie == null) {
@@ -174,7 +171,7 @@ public class AuthenticationManager {
}
String tokenString = cookie.getValue();
AuthResult authResult = verifyIdentityToken(realm, uriInfo, checkActive, tokenString);
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, checkActive, tokenString);
if (authResult == null) {
expireIdentityCookie(realm, uriInfo);
return null;
@@ -183,7 +180,7 @@ public class AuthenticationManager {
return authResult;
}
protected AuthResult verifyIdentityToken(RealmModel realm, UriInfo uriInfo, boolean checkActive, String tokenString) {
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, boolean checkActive, String tokenString) {
try {
AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
logger.info("identity token verified");
@@ -205,21 +202,21 @@ public class AuthenticationManager {
return null;
}
UserSessionModel session = realm.getUserSession(token.getSessionState());
if (!isSessionValid(realm, session)) {
if (session != null) logout(realm, session, uriInfo);
UserSessionModel userSession = session.sessions().getUserSession(realm, token.getSessionState());
if (!isSessionValid(realm, userSession)) {
if (userSession != null) logout(session, realm, userSession, uriInfo);
logger.info("User session not active");
return null;
}
return new AuthResult(user, session, token);
return new AuthResult(user, userSession, token);
} catch (VerificationException e) {
logger.info("Failed to verify identity token", e);
}
return null;
}
public AuthenticationStatus authenticateForm(ClientConnection clientConnection, RealmModel realm, MultivaluedMap<String, String> formData) {
public AuthenticationStatus authenticateForm(KeycloakSession session, ClientConnection clientConnection, RealmModel realm, MultivaluedMap<String, String> formData) {
String username = formData.getFirst(FORM_USERNAME);
if (username == null) {
logger.warn("Username not provided");
@@ -227,12 +224,12 @@ public class AuthenticationManager {
}
if (realm.isBruteForceProtected()) {
if (protector.isTemporarilyDisabled(realm, username)) {
if (protector.isTemporarilyDisabled(session, realm, username)) {
return AuthenticationStatus.ACCOUNT_TEMPORARILY_DISABLED;
}
}
AuthenticationStatus status = authenticateInternal(realm, formData, username);
AuthenticationStatus status = authenticateInternal(session, realm, formData, username);
if (realm.isBruteForceProtected()) {
switch (status) {
case SUCCESS:
@@ -255,7 +252,7 @@ public class AuthenticationManager {
return status;
}
protected AuthenticationStatus authenticateInternal(RealmModel realm, MultivaluedMap<String, String> formData, String username) {
protected AuthenticationStatus authenticateInternal(KeycloakSession session, RealmModel realm, MultivaluedMap<String, String> formData, String username) {
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
if (user == null) {
AuthUser authUser = AuthenticationProviderManager.getManager(realm, session).getUser(username);
@@ -83,7 +83,7 @@ public class BruteForceProtector implements Runnable {
logFailure(event);
UsernameLoginFailureModel user = getUserModel(session, event);
if (user == null) {
user = realm.addUserLoginFailure(event.username);
user = session.sessions().addUserLoginFailure(realm, event.username);
}
user.setLastIPFailure(event.ip);
long currentTime = System.currentTimeMillis();
@@ -122,13 +122,13 @@ public class BruteForceProtector implements Runnable {
protected UsernameLoginFailureModel getUserModel(KeycloakSession session, LoginEvent event) {
RealmModel realm = getRealmModel(session, event);
if (realm == null) return null;
UsernameLoginFailureModel user = realm.getUserLoginFailure(event.username);
UsernameLoginFailureModel user = session.sessions().getUserLoginFailure(realm, event.username);
if (user == null) return null;
return user;
}
protected RealmModel getRealmModel(KeycloakSession session, LoginEvent event) {
RealmModel realm = session.getModel().getRealm(event.realmId);
RealmModel realm = session.model().getRealm(event.realmId);
if (realm == null) return null;
return realm;
}
@@ -237,8 +237,8 @@ public class BruteForceProtector implements Runnable {
}
}
public boolean isTemporarilyDisabled(RealmModel realm, String username) {
UsernameLoginFailureModel failure = realm.getUserLoginFailure(username);
public boolean isTemporarilyDisabled(KeycloakSession session, RealmModel realm, String username) {
UsernameLoginFailureModel failure = session.sessions().getUserLoginFailure(realm, username);
if (failure == null) {
return false;
}
@@ -2,9 +2,11 @@ package org.keycloak.services.managers;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonPropertyOrder;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserSessionProvider;
import org.keycloak.representations.adapters.config.BaseRealmConfig;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
@@ -22,12 +24,18 @@ import java.util.Set;
* @version $Revision: 1 $
*/
public class OAuthClientManager {
private RealmManager realmManager;
protected RealmModel realm;
public OAuthClientManager(RealmModel realm) {
this.realm = realm;
}
public OAuthClientManager(RealmManager realmManager) {
this.realmManager = realmManager;
}
public UserCredentialModel generateSecret(OAuthClientModel app) {
UserCredentialModel secret = UserCredentialModel.generateSecret();
app.setSecret(secret.getValue());
@@ -47,6 +55,18 @@ public class OAuthClientManager {
return model;
}
public boolean removeClient(RealmModel realm, OAuthClientModel client) {
if (realm.removeOAuthClient(client.getId())) {
UserSessionProvider sessions = realmManager.getSession().sessions();
if (sessions != null) {
realmManager.getSession().sessions().onClientRemoved(realm, client);
}
return true;
} else {
return false;
}
}
public void update(OAuthClientRepresentation rep, OAuthClientModel model) {
if (rep.getName() != null) model.setClientId(rep.getName());
if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
@@ -19,6 +19,7 @@ import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.models.UserSessionProvider;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
@@ -31,7 +32,6 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation;
import org.keycloak.representations.idm.SocialLinkRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserRoleMappingRepresentation;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
@@ -67,7 +67,11 @@ public class RealmManager {
public RealmManager(KeycloakSession session) {
this.session = session;
this.model = session.getModel();
this.model = session.model();
}
public KeycloakSession getSession() {
return session;
}
public RealmModel getKeycloakAdminstrationRealm() {
@@ -148,7 +152,12 @@ public class RealmManager {
public boolean removeRealm(RealmModel realm) {
boolean removed = model.removeRealm(realm.getId());
if (removed) {
getKeycloakAdminstrationRealm().removeApplication(realm.getMasterAdminApp().getId());
new ApplicationManager(this).removeApplication(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp());
UserSessionProvider sessions = session.sessions();
if (sessions != null) {
sessions.onRealmRemoved(realm);
}
}
return removed;
}
@@ -11,6 +11,7 @@ import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
@@ -26,14 +27,12 @@ import org.keycloak.util.Time;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* Stateful object that creates tokens and manages oauth access codes
@@ -44,22 +43,6 @@ import java.util.concurrent.ConcurrentHashMap;
public class TokenManager {
protected static final Logger logger = Logger.getLogger(TokenManager.class);
/*
protected Map<String, AccessCodeEntry> accessCodeMap = new ConcurrentHashMap<String, AccessCodeEntry>();
public void clearAccessCodes() {
accessCodeMap.clear();
}
public AccessCodeEntry getAccessCode(String key) {
return accessCodeMap.get(key);
}
public AccessCodeEntry pullAccessCode(String key) {
return accessCodeMap.remove(key);
}
*/
public AccessCodeEntry parseCode(String code, RealmModel realm) {
try {
JWSInput input = new JWSInput(code);
@@ -114,7 +97,7 @@ public class TokenManager {
}
public AccessToken refreshAccessToken(UriInfo uriInfo, RealmModel realm, ClientModel client, String encodedRefreshToken, Audit audit) throws OAuthErrorException {
public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, RealmModel realm, ClientModel client, String encodedRefreshToken, Audit audit) throws OAuthErrorException {
JWSInput jws = new JWSInput(encodedRefreshToken);
RefreshToken refreshToken = null;
try {
@@ -144,10 +127,10 @@ public class TokenManager {
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "User disabled", "User disabled");
}
UserSessionModel session = realm.getUserSession(refreshToken.getSessionState());
UserSessionModel userSession = session.sessions().getUserSession(realm, refreshToken.getSessionState());
int currentTime = Time.currentTime();
if (!AuthenticationManager.isSessionValid(realm, session)) {
AuthenticationManager.logout(realm, session, uriInfo);
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Session not active", "Session not active");
}
@@ -198,13 +181,13 @@ public class TokenManager {
}
}
AccessToken accessToken = initToken(realm, client, user, session);
AccessToken accessToken = initToken(realm, client, user, userSession);
accessToken.setRealmAccess(refreshToken.getRealmAccess());
accessToken.setResourceAccess(refreshToken.getResourceAccess());
// only refresh session if next token refresh will be after idle timeout
if (currentTime + realm.getAccessTokenLifespan() > session.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout()) {
session.setLastSessionRefresh(currentTime);
if (currentTime + realm.getAccessTokenLifespan() > userSession.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout()) {
userSession.setLastSessionRefresh(currentTime);
}
return accessToken;
@@ -0,0 +1,30 @@
package org.keycloak.services.managers;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionProvider;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class UserManager {
private KeycloakSession session;
public UserManager(KeycloakSession session) {
this.session = session;
}
public boolean removeUser(RealmModel realm, UserModel user) {
if (realm.removeUser(user.getUsername())) {
UserSessionProvider sessions = session.sessions();
if (sessions != null) {
sessions.onUserRemoved(realm, user);
}
return true;
}
return false;
}
}
@@ -132,7 +132,7 @@ public class AccountService {
this.realm = realm;
this.application = application;
this.audit = audit;
this.authManager = new AppAuthManager(session);
this.authManager = new AppAuthManager();
}
public void init() {
@@ -141,11 +141,11 @@ public class AccountService {
account = session.getProvider(AccountProvider.class).setRealm(realm).setUriInfo(uriInfo);
boolean passwordUpdateSupported = false;
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers);
if (authResult != null) {
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, true);
} else {
authResult = authManager.authenticateBearerToken(realm, uriInfo, headers);
authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
if (authResult != null) {
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, false);
}
@@ -288,7 +288,7 @@ public class AccountService {
@GET
public Response sessionsPage() {
if (auth != null) {
account.setSessions(realm.getUserSessions(auth.getUser()));
account.setSessions(session.sessions().getUserSessions(realm, auth.getUser()));
}
return forwardToPage("sessions", AccountPages.SESSIONS);
}
@@ -369,7 +369,7 @@ public class AccountService {
require(AccountRoles.MANAGE_ACCOUNT);
UserModel user = auth.getUser();
realm.removeUserSessions(user);
session.sessions().removeUserSessions(realm, user);
return Response.seeOther(Urls.accountSessionsPage(uriInfo.getBaseUri(), realm.getName())).build();
}
@@ -94,7 +94,7 @@ public class RealmsResource {
@QueryParam("client_id") String client_id,
@QueryParam("origin") String origin) {
logger.info("getLoginStatusIframe");
AuthenticationManager auth = new AuthenticationManager(session);
AuthenticationManager auth = new AuthenticationManager();
//logger.info("getting login-status-iframe.html for client_id: " + client_id);
RealmManager realmManager = new RealmManager(session);
@@ -103,7 +103,7 @@ public class RealmsResource {
if (client == null) {
throw new NotFoundException("could not find client: " + client_id);
}
AuthenticationManager.AuthResult result = auth.authenticateIdentityCookie(realm, uriInfo, headers);
AuthenticationManager.AuthResult result = auth.authenticateIdentityCookie(session, realm, uriInfo, headers);
if (result == null) {
throw new UnauthorizedException("not logged in, can't get page");
}
@@ -148,7 +148,7 @@ public class RealmsResource {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = locateRealm(name, realmManager);
Audit audit = new AuditManager(realm, session, clientConnection).createAudit();
AuthenticationManager authManager = new AuthenticationManager(session, protector);
AuthenticationManager authManager = new AuthenticationManager(protector);
TokenService tokenService = new TokenService(realm, tokenManager, audit, authManager);
ResteasyProviderFactory.getInstance().injectProperties(tokenService);
//resourceContext.initResource(tokenService);
@@ -226,7 +226,7 @@ public class RequiredActionsService {
// Password reset through email won't have an associated session
if (accessCode.getSessionState() == null) {
UserSessionModel userSession = realm.createUserSession(realm.getUserById(accessCode.getUser().getId()), clientConnection.getRemoteAddr());
UserSessionModel userSession = session.sessions().createUserSession(realm, realm.getUserById(accessCode.getUser().getId()), clientConnection.getRemoteAddr());
accessCode.getToken().setSessionState(userSession.getId());
audit.session(userSession);
}
@@ -299,7 +299,7 @@ public class RequiredActionsService {
String redirect = uriInfo.getQueryParameters().getFirst(OAuth2Constants.REDIRECT_URI);
String clientId = uriInfo.getQueryParameters().getFirst(OAuth2Constants.CLIENT_ID);
AuthenticationManager authManager = new AuthenticationManager(session);
AuthenticationManager authManager = new AuthenticationManager();
ClientModel client = realm.findClient(clientId);
if (client == null) {
@@ -397,19 +397,19 @@ public class RequiredActionsService {
logger.debugv("redirectOauth: redirecting to: {0}", accessCode.getRedirectUri());
accessCode.resetExpiration();
AuthenticationManager authManager = new AuthenticationManager(session);
AuthenticationManager authManager = new AuthenticationManager();
UserSessionModel session = realm.getUserSession(accessCode.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, session)) {
AuthenticationManager.logout(realm, session, uriInfo);
UserSessionModel userSession = session.sessions().getUserSession(realm, accessCode.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
return Flows.oauth(this.session, realm, request, uriInfo, authManager, tokenManager).redirectError(accessCode.getClient(), "access_denied", accessCode.getState(), accessCode.getRedirectUri());
}
audit.session(session);
audit.session(userSession);
audit.success();
return Flows.oauth(this.session, realm, request, uriInfo, authManager, tokenManager).redirectAccessCode(accessCode,
session, accessCode.getState(), accessCode.getRedirectUri());
userSession, accessCode.getState(), accessCode.getRedirectUri());
}
}
@@ -125,7 +125,7 @@ public class SocialResource {
.detail(Details.RESPONSE_TYPE, initialRequest.get(OAuth2Constants.RESPONSE_TYPE))
.detail(Details.AUTH_METHOD, "social@" + provider.getId());
AuthenticationManager authManager = new AuthenticationManager(session);
AuthenticationManager authManager = new AuthenticationManager();
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
if (!realm.isEnabled()) {
@@ -251,10 +251,10 @@ public class SocialResource {
return oauth.forwardToSecurityFailure("Your account is not enabled.");
}
UserSessionModel session = realm.createUserSession(user, clientConnection.getRemoteAddr());
audit.session(session);
UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr());
audit.session(userSession);
return oauth.processAccessCode(scope, state, redirectUri, client, user, session, socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(), false, "social@" + provider.getId(), audit);
return oauth.processAccessCode(scope, state, redirectUri, client, user, userSession, socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(), false, "social@" + provider.getId(), audit);
}
@GET
@@ -249,7 +249,7 @@ public class TokenService {
return createError("realm_disabled", "Realm is disabled", Response.Status.UNAUTHORIZED);
}
AuthenticationStatus authenticationStatus = authManager.authenticateForm(clientConnection, realm, form);
AuthenticationStatus authenticationStatus = authManager.authenticateForm(session, clientConnection, realm, form);
Map<String, String> err;
switch (authenticationStatus) {
@@ -281,12 +281,12 @@ public class TokenService {
String scope = form.getFirst(OAuth2Constants.SCOPE);
UserSessionModel session = realm.createUserSession(user, clientConnection.getRemoteAddr());
session.associateClient(client);
audit.session(session);
UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr());
userSession.associateClient(client);
audit.session(userSession);
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, audit)
.generateAccessToken(scope, client, user, session)
.generateAccessToken(scope, client, user, userSession)
.generateRefreshToken()
.generateIDToken()
.build();
@@ -327,7 +327,7 @@ public class TokenService {
String refreshToken = form.getFirst(OAuth2Constants.REFRESH_TOKEN);
AccessToken accessToken;
try {
accessToken = tokenManager.refreshAccessToken(uriInfo, realm, client, refreshToken, audit);
accessToken = tokenManager.refreshAccessToken(session, uriInfo, realm, client, refreshToken, audit);
} catch (OAuthErrorException e) {
Map<String, String> error = new HashMap<String, String>();
error.put(OAuth2Constants.ERROR, e.getError());
@@ -412,7 +412,7 @@ public class TokenService {
return oauth.redirectError(client, "access_denied", state, redirect);
}
AuthenticationStatus status = authManager.authenticateForm(clientConnection, realm, formData);
AuthenticationStatus status = authManager.authenticateForm(session, clientConnection, realm, formData);
if (remember) {
authManager.createRememberMeCookie(realm, uriInfo);
@@ -428,10 +428,10 @@ public class TokenService {
switch (status) {
case SUCCESS:
case ACTIONS_REQUIRED:
UserSessionModel session = realm.createUserSession(user, clientConnection.getRemoteAddr());
audit.session(session);
UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr());
audit.session(userSession);
return oauth.processAccessCode(scopeParam, state, redirect, client, user, session, username, remember, "form", audit);
return oauth.processAccessCode(scopeParam, state, redirect, client, user, userSession, username, remember, "form", audit);
case ACCOUNT_TEMPORARILY_DISABLED:
audit.error(Errors.USER_TEMPORARILY_DISABLED);
return Flows.forms(this.session, realm, uriInfo).setError(Messages.ACCOUNT_TEMPORARILY_DISABLED).setFormData(formData).createLogin();
@@ -686,9 +686,9 @@ public class TokenService {
.build();
}
UserSessionModel session = realm.getUserSession(accessCode.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, session)) {
AuthenticationManager.logout(realm, session, uriInfo);
UserSessionModel userSession = session.sessions().getUserSession(realm, accessCode.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
Map<String, String> res = new HashMap<String, String>();
res.put(OAuth2Constants.ERROR, "invalid_grant");
res.put(OAuth2Constants.ERROR_DESCRIPTION, "Session not active");
@@ -699,7 +699,7 @@ public class TokenService {
logger.debug("accessRequest SUCCESS");
session.associateClient(client);
userSession.associateClient(client);
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, audit)
.accessToken(accessCode.getToken())
@@ -825,7 +825,7 @@ public class TokenService {
}
logger.info("Checking cookie...");
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers);
if (authResult != null) {
UserModel user = authResult.getUser();
UserSessionModel session = authResult.getSession();
@@ -924,11 +924,11 @@ public class TokenService {
}
// authenticate identity cookie, but ignore an access token timeout as we're logging out anyways.
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(realm, uriInfo, headers, false);
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers, false);
if (authResult != null) {
logout(authResult.getSession());
} else if (sessionState != null) {
UserSessionModel userSession = realm.getUserSession(sessionState);
UserSessionModel userSession = session.sessions().getUserSession(realm, sessionState);
if (userSession != null) {
logout(userSession);
} else {
@@ -946,10 +946,9 @@ public class TokenService {
}
}
private void logout(UserSessionModel session) {
UserModel user = session.getUser();
authManager.logout(realm, session, uriInfo);
audit.user(user).session(session).success();
private void logout(UserSessionModel userSession) {
authManager.logout(session, realm, userSession, uriInfo);
audit.user(userSession.getUser()).session(userSession).success();
}
/**
@@ -993,13 +992,13 @@ public class TokenService {
audit.detail(Details.REMEMBER_ME, "true");
}
UserSessionModel session = realm.getUserSession(accessCodeEntry.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, session)) {
AuthenticationManager.logout(realm, session, uriInfo);
UserSessionModel userSession = session.sessions().getUserSession(realm, accessCodeEntry.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
audit.error(Errors.INVALID_CODE);
return oauth.forwardToSecurityFailure("Session not active");
}
audit.session(session);
audit.session(userSession);
if (formData.containsKey("cancel")) {
audit.error(Errors.REJECTED_BY_USER);
@@ -1009,7 +1008,7 @@ public class TokenService {
audit.success();
accessCodeEntry.resetExpiration();
return oauth.redirectAccessCode(accessCodeEntry, session, state, redirect);
return oauth.redirectAccessCode(accessCodeEntry, userSession, state, redirect);
}
@Path("oauth/oob")
@@ -12,7 +12,6 @@ import org.keycloak.models.AdminRoles;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelProvider;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
@@ -79,7 +78,7 @@ public class AdminConsole {
public AdminConsole(RealmModel realm) {
this.realm = realm;
this.authManager = new AppAuthManager(session);
this.authManager = new AppAuthManager();
}
public static class WhoAmI {
@@ -174,7 +173,7 @@ public class AdminConsole {
@NoCache
public Response whoAmI(final @Context HttpHeaders headers) {
RealmManager realmManager = new RealmManager(session);
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
if (authResult == null) {
return Response.status(401).build();
}
@@ -225,7 +224,7 @@ public class AdminConsole {
}
private void addMasterRealmAccess(RealmModel masterRealm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
List<RealmModel> realms = session.getModel().getRealms();
List<RealmModel> realms = session.model().getRealms();
for (RealmModel realm : realms) {
ApplicationModel realmAdminApp = realm.getMasterAdminApp();
Set<RoleModel> roles = realmAdminApp.getRoles();
@@ -55,7 +55,7 @@ public class AdminRoot {
public AdminRoot(TokenManager tokenManager) {
this.tokenManager = tokenManager;
this.authManager = new AppAuthManager(null);
this.authManager = new AppAuthManager();
}
public static UriBuilder adminBaseUrl(UriInfo uriInfo) {
@@ -142,7 +142,7 @@ public class AdminRoot {
if (realm == null) {
throw new UnauthorizedException("Unknown realm in token");
}
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
if (authResult == null) {
logger.debug("Token not valid");
throw new UnauthorizedException("Bearer");
@@ -167,7 +167,7 @@ public class ApplicationResource {
public void deleteApplication() {
auth.requireManage();
realm.removeApplication(application.getId());
new ApplicationManager(new RealmManager(session)).removeApplication(realm, application);
}
@@ -327,7 +327,7 @@ public class ApplicationResource {
public Map<String, Integer> getApplicationSessionCount() {
auth.requireView();
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("count", application.getActiveUserSessions());
map.put("count", session.sessions().getActiveUserSessions(application.getRealm(), application));
return map;
}
@@ -343,8 +343,8 @@ public class ApplicationResource {
public List<UserSessionRepresentation> getUserSessions() {
auth.requireView();
List<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>();
for (UserSessionModel session : application.getUserSessions()) {
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);
for (UserSessionModel userSession : session.sessions().getUserSessions(application.getRealm(), application)) {
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession);
sessions.add(rep);
}
return sessions;
@@ -12,6 +12,7 @@ import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.OAuthClientManager;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.services.resources.flows.Flows;
import org.keycloak.util.JsonSerialization;
@@ -133,7 +134,7 @@ public class OAuthClientResource {
public void deleteOAuthClient() {
auth.requireManage();
realm.removeOAuthClient(oauthClient.getId());
new OAuthClientManager(new RealmManager(session)).removeClient(realm, oauthClient);
}
@@ -204,7 +204,7 @@ public class RealmAdminResource {
@POST
public void logoutAll() {
auth.requireManage();
realm.removeUserSessions();
session.sessions().removeUserSessions(realm);
new ResourceAdminManager().logoutAll(uriInfo.getRequestUri(), realm);
}
@@ -217,10 +217,10 @@ public class RealmAdminResource {
@Path("sessions/{session}")
@DELETE
public void deleteSession(@PathParam("session") String sessionId) {
UserSessionModel session = realm.getUserSession(sessionId);
if (session == null) throw new NotFoundException("Sesssion not found");
realm.removeUserSession(session);
new ResourceAdminManager().logoutSession(uriInfo.getRequestUri(), realm, session.getId());
UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
if (userSession == null) throw new NotFoundException("Sesssion not found");
session.sessions().removeUserSession(realm, userSession);
new ResourceAdminManager().logoutSession(uriInfo.getRequestUri(), realm, userSession.getId());
}
/**
@@ -236,10 +236,10 @@ public class RealmAdminResource {
public Map<String, Integer> getApplicationSessionStats() {
auth.requireView();
Map<String, Integer> stats = new HashMap<String, Integer>();
for (ApplicationModel applicationModel : realm.getApplications()) {
int size = applicationModel.getActiveUserSessions();
for (ApplicationModel application : realm.getApplications()) {
int size = session.sessions().getActiveUserSessions(application.getRealm(), application);
if (size == 0) continue;
stats.put(applicationModel.getName(), size);
stats.put(application.getName(), size);
}
return stats;
}
@@ -6,7 +6,6 @@ import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.util.GenericType;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
@@ -15,7 +14,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.ForbiddenException;
import org.keycloak.services.managers.Auth;
import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.TokenManager;
@@ -87,7 +85,7 @@ public class RealmsAdminResource {
RealmManager realmManager = new RealmManager(session);
List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
List<RealmModel> realms = session.getModel().getRealms();
List<RealmModel> realms = session.model().getRealms();
for (RealmModel realm : realms) {
addRealmRep(reps, realm, realm.getMasterAdminApp());
}
@@ -30,9 +30,9 @@ import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.managers.UserManager;
import org.keycloak.services.resources.flows.Flows;
import org.keycloak.services.resources.flows.Urls;
import org.keycloak.util.Time;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -228,7 +228,7 @@ public class UsersResource {
if (user == null) {
throw new NotFoundException("User not found");
}
List<UserSessionModel> sessions = realm.getUserSessions(user);
List<UserSessionModel> sessions = session.sessions().getUserSessions(realm, user);
List<UserSessionRepresentation> reps = new ArrayList<UserSessionRepresentation>();
for (UserSessionModel session : sessions) {
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);
@@ -276,7 +276,7 @@ public class UsersResource {
if (user == null) {
throw new NotFoundException("User not found");
}
realm.removeUserSessions(user);
session.sessions().removeUserSessions(realm, user);
new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), null);
}
@@ -291,7 +291,12 @@ public class UsersResource {
public void deleteUser(final @PathParam("username") String username) {
auth.requireManage();
realm.removeUser(username);
UserModel user = realm.getUser(username);
if (user == null) {
throw new NotFoundException("User not found");
}
new UserManager(session).removeUser(realm, user);
}
/**
@@ -42,7 +42,6 @@ import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.AccessCodeEntry;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.util.CookieHelper;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MultivaluedMap;
@@ -90,7 +89,7 @@ public class OAuthFlows {
}
public Response redirectAccessCode(AccessCodeEntry accessCode, UserSessionModel session, String state, String redirect, boolean rememberMe) {
public Response redirectAccessCode(AccessCodeEntry accessCode, UserSessionModel userSession, String state, String redirect, boolean rememberMe) {
String code = accessCode.getCode();
UriBuilder redirectUri = UriBuilder.fromUri(redirect).queryParam(OAuth2Constants.CODE, code);
log.debugv("redirectAccessCode: state: {0}", state);
@@ -103,17 +102,17 @@ public class OAuthFlows {
Cookie sessionCookie = request.getHttpHeaders().getCookies().get(AuthenticationManager.KEYCLOAK_SESSION_COOKIE);
if (sessionCookie != null) {
String oldSessionId = sessionCookie.getValue().split("/")[2];
if (!oldSessionId.equals(session.getId())) {
UserSessionModel oldSession = realm.getUserSession(oldSessionId);
if (!oldSessionId.equals(userSession.getId())) {
UserSessionModel oldSession = session.sessions().getUserSession(realm, oldSessionId);
if (oldSession != null) {
log.debugv("Removing old user session: session: {0}", oldSessionId);
realm.removeUserSession(oldSession);
session.sessions().removeUserSession(realm, oldSession);
}
}
}
// refresh the cookies!
authManager.createLoginCookie(realm, accessCode.getUser(), session, uriInfo, rememberMe);
authManager.createLoginCookie(realm, accessCode.getUser(), userSession, uriInfo, rememberMe);
if (rememberMe) authManager.createRememberMeCookie(realm, uriInfo);
return location.build();
}
@@ -13,7 +13,7 @@ public class ClearExpiredAuditEvents implements ScheduledTask {
public void run(KeycloakSession session) {
AuditProvider audit = session.getProvider(AuditProvider.class);
if (audit != null) {
for (RealmModel realm : session.getModel().getRealms()) {
for (RealmModel realm : session.model().getRealms()) {
if (realm.isAuditEnabled() && realm.getAuditExpiration() > 0) {
long olderThan = System.currentTimeMillis() - realm.getAuditExpiration() * 1000;
audit.clear(realm.getId(), olderThan);
@@ -2,6 +2,7 @@ package org.keycloak.services.scheduled;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionProvider;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -10,8 +11,9 @@ public class ClearExpiredUserSessions implements ScheduledTask {
@Override
public void run(KeycloakSession session) {
for (RealmModel realm : session.getModel().getRealms()) {
realm.removeExpiredUserSessions();
UserSessionProvider sessions = session.sessions();
for (RealmModel realm : session.model().getRealms()) {
sessions.removeExpiredUserSessions(realm);
}
}