Details
diff --git a/core/src/main/java/org/keycloak/AbstractOAuthClient.java b/core/src/main/java/org/keycloak/AbstractOAuthClient.java
index 592ddab..b5975d6 100755
--- a/core/src/main/java/org/keycloak/AbstractOAuthClient.java
+++ b/core/src/main/java/org/keycloak/AbstractOAuthClient.java
@@ -21,12 +21,14 @@ import java.util.concurrent.atomic.AtomicLong;
* @version $Revision: 1 $
*/
public class AbstractOAuthClient {
+ public static final String OAUTH_TOKEN_REQUEST_STATE = "OAuth_Token_Request_State";
protected String clientId;
protected String password;
protected KeyStore truststore;
protected String authUrl;
protected String codeUrl;
- protected String stateCookieName = "OAuth_Token_Request_State";
+ protected String stateCookieName = OAUTH_TOKEN_REQUEST_STATE;
+ protected String stateCookiePath;
protected Client client;
protected boolean isSecure;
protected final AtomicLong counter = new AtomicLong();
@@ -35,6 +37,9 @@ public class AbstractOAuthClient {
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
}
+ /**
+ * Creates a Client for obtaining access token from code
+ */
public void start() {
if (client == null) {
client = new ResteasyClientBuilder().trustStore(truststore)
@@ -44,6 +49,9 @@ public class AbstractOAuthClient {
}
}
+ /**
+ * closes cllient
+ */
public void stop() {
client.close();
}
@@ -76,6 +84,8 @@ public class AbstractOAuthClient {
return authUrl;
}
+
+
public void setAuthUrl(String authUrl) {
this.authUrl = authUrl;
}
@@ -96,6 +106,14 @@ public class AbstractOAuthClient {
this.stateCookieName = stateCookieName;
}
+ public String getStateCookiePath() {
+ return stateCookiePath;
+ }
+
+ public void setStateCookiePath(String stateCookiePath) {
+ this.stateCookiePath = stateCookiePath;
+ }
+
public Client getClient() {
return client;
}
@@ -128,7 +146,6 @@ public class AbstractOAuthClient {
}
protected String stripOauthParametersFromRedirect(String uri) {
- System.out.println("******************** redirect_uri: " + uri);
UriBuilder builder = UriBuilder.fromUri(uri)
.replaceQueryParam("code", null)
.replaceQueryParam("state", null);
diff --git a/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java b/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
index 380d3ae..71b58d7 100755
--- a/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
+++ b/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
@@ -1,5 +1,6 @@
package org.keycloak.jaxrs;
+import org.jboss.resteasy.logging.Logger;
import org.keycloak.AbstractOAuthClient;
import javax.ws.rs.BadRequestException;
@@ -19,6 +20,7 @@ import java.net.URI;
* @version $Revision: 1 $
*/
public class JaxrsOAuthClient extends AbstractOAuthClient {
+ protected static final Logger logger = Logger.getLogger(JaxrsOAuthClient.class);
public Response redirect(UriInfo uriInfo, String redirectUri) {
String state = getStateCode();
@@ -27,26 +29,42 @@ public class JaxrsOAuthClient extends AbstractOAuthClient {
.queryParam("redirect_uri", redirectUri)
.queryParam("state", state)
.build();
- NewCookie cookie = new NewCookie(stateCookieName, state, uriInfo.getBaseUri().getPath(), null, null, -1, true);
+ NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
+ logger.info("NewCookie: " + cookie.toString());
return Response.status(302)
.location(url)
.cookie(cookie).build();
}
+ public String getStateCookiePath(UriInfo uriInfo) {
+ if (stateCookiePath != null) return stateCookiePath;
+ return uriInfo.getBaseUri().getPath();
+ }
+
public String getBearerToken(UriInfo uriInfo, HttpHeaders headers) throws BadRequestException, InternalServerErrorException {
- String error = uriInfo.getQueryParameters().getFirst("error");
+ String error = getError(uriInfo);
if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error));
- Cookie stateCookie = headers.getCookies().get(stateCookieName);
- if (stateCookie == null) throw new BadRequestException(new Exception("state cookie not set"));
- ;
+ checkStateCookie(uriInfo, headers);
+ String code = getAccessCode(uriInfo);
+ if (code == null) throw new BadRequestException(new Exception("code parameter was null"));
+ return resolveBearerToken(uriInfo.getRequestUri().toString(), code);
+ }
+ public String getError(UriInfo uriInfo) {
+ return uriInfo.getQueryParameters().getFirst("error");
+ }
+
+ public String getAccessCode(UriInfo uriInfo) {
+ return uriInfo.getQueryParameters().getFirst("code");
+ }
+
+ public void checkStateCookie(UriInfo uriInfo, HttpHeaders headers) {
+ Cookie stateCookie = headers.getCookies().get(stateCookieName);
+ if (stateCookie == null) throw new BadRequestException("state cookie not set");
String state = uriInfo.getQueryParameters().getFirst("state");
- if (state == null) throw new BadRequestException(new Exception("state parameter was null"));
+ if (state == null) throw new BadRequestException("state parameter was null");
if (!state.equals(stateCookie.getValue())) {
- throw new BadRequestException(new Exception("state parameter invalid"));
+ throw new BadRequestException("state parameter invalid");
}
- String code = uriInfo.getQueryParameters().getFirst("code");
- if (code == null) throw new BadRequestException(new Exception("code parameter was null"));
- return resolveBearerToken(uriInfo.getRequestUri().toString(), code);
}
}
diff --git a/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java b/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
index 27693b4..95ea522 100755
--- a/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
+++ b/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
@@ -51,12 +51,13 @@ public class ServletOAuthClient extends AbstractOAuthClient {
.queryParam("redirect_uri", redirectUri)
.queryParam("state", state)
.build();
- String cookiePath = request.getContextPath();
- if (cookiePath.equals("")) cookiePath = "/";
+ String stateCookiePath = this.stateCookiePath;
+ if (stateCookiePath == null) stateCookiePath = request.getContextPath();
+ if (stateCookiePath.equals("")) stateCookiePath = "/";
Cookie cookie = new Cookie(stateCookieName, state);
cookie.setSecure(isSecure);
- cookie.setPath(cookiePath);
+ cookie.setPath(stateCookiePath);
response.addCookie(cookie);
response.sendRedirect(url.toString());
}
diff --git a/forms/src/main/java/org/keycloak/forms/UrlBean.java b/forms/src/main/java/org/keycloak/forms/UrlBean.java
old mode 100644
new mode 100755
index 0fb83c0..f527d38
--- a/forms/src/main/java/org/keycloak/forms/UrlBean.java
+++ b/forms/src/main/java/org/keycloak/forms/UrlBean.java
@@ -70,19 +70,11 @@ public class UrlBean {
}
public String getLoginAction() {
- if (realm.isSaas()) {
- return Urls.saasLoginAction(baseURI).toString();
- } else {
- return Urls.realmLoginAction(baseURI, realm.getId()).toString();
- }
+ return Urls.realmLoginAction(baseURI, realm.getId()).toString();
}
public String getLoginUrl() {
- if (realm.isSaas()) {
- return Urls.saasLoginPage(baseURI).toString();
- } else {
- return Urls.realmLoginPage(baseURI, realm.getId()).toString();
- }
+ return Urls.realmLoginPage(baseURI, realm.getId()).toString();
}
public String getPasswordUrl() {
diff --git a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
index fd1189f..9dceed8 100755
--- a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
+++ b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
@@ -1,5 +1,6 @@
package org.keycloak.services.managers;
+import org.keycloak.models.RealmModel;
import org.keycloak.representations.SkeletonKeyToken;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
@@ -23,6 +24,7 @@ public class AccessCodeEntry {
protected String redirectUri;
protected long expiration;
+ protected RealmModel realm;
protected SkeletonKeyToken token;
protected UserModel user;
protected Set<RequiredAction> requiredActions;
@@ -38,6 +40,14 @@ public class AccessCodeEntry {
return id;
}
+ public RealmModel getRealm() {
+ return realm;
+ }
+
+ public void setRealm(RealmModel realm) {
+ this.realm = realm;
+ }
+
public String getCode() {
return code;
}
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index e6d3cbb..9d36f8f 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -26,6 +26,7 @@ public class ApplianceBootstrap {
realm.addRequiredResourceCredential(CredentialRepresentation.PASSWORD);
realm.setTokenLifespan(300);
realm.setAccessCodeLifespan(60);
+ realm.setAccessCodeLifespanUserAction(300);
realm.setSslNotRequired(true);
realm.setCookieLoginAllowed(true);
realm.setRegistrationAllowed(false);
@@ -49,7 +50,7 @@ public class ApplianceBootstrap {
password.setType(UserCredentialModel.PASSWORD);
password.setValue("admin");
realm.updateCredential(adminUser, password);
- //adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+ adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
adminConsole.grantRole(adminUser, adminRole);
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index b48d710..925076a 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -99,7 +99,7 @@ public class AuthenticationManager {
expireCookie(SaasService.SAAS_IDENTITY_COOKIE, cookiePath);
}
- protected void expireCookie(String cookieName, String path) {
+ public void expireCookie(String cookieName, String path) {
HttpResponse response = ResteasyProviderFactory.getContextData(HttpResponse.class);
if (response == null) {
logger.info("can't expire identity cookie, no HttpResponse");
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index 47ed94d..e3012b6 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -3,6 +3,7 @@ package org.keycloak.services.managers;
import org.jboss.resteasy.jose.Base64Url;
import org.jboss.resteasy.jose.jws.JWSBuilder;
import org.jboss.resteasy.jwt.JsonSerialization;
+import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.*;
import org.keycloak.representations.SkeletonKeyScope;
import org.keycloak.representations.SkeletonKeyToken;
@@ -22,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @version $Revision: 1 $
*/
public class TokenManager {
+ protected static final Logger logger = Logger.getLogger(TokenManager.class);
protected Map<String, AccessCodeEntry> accessCodeMap = new ConcurrentHashMap<String, AccessCodeEntry>();
@@ -86,6 +88,9 @@ public class TokenManager {
createToken(code, realm, client, user);
+ logger.info("tokenmanager: access code id: " + code.getId());
+ logger.info("accesscode setExpiration: " + (System.currentTimeMillis() / 1000) + realm.getAccessCodeLifespan());
+ code.setRealm(realm);
code.setExpiration((System.currentTimeMillis() / 1000) + realm.getAccessCodeLifespan());
code.setClient(client);
code.setUser(user);
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index 0340751..7095eab 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -47,10 +47,9 @@ public class KeycloakApplication extends Application {
TokenManager tokenManager = new TokenManager();
singletons.add(new RealmsResource(tokenManager));
+ singletons.add(new SaasService(tokenManager));
singletons.add(new SocialResource(tokenManager, new SocialRequestManager()));
classes.add(SkeletonKeyContextResolver.class);
- classes.add(SaasService.class);
-
}
protected KeycloakSessionFactory createSessionFactory() {
diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
index 214a814..1517b79 100755
--- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
@@ -23,6 +23,7 @@ package org.keycloak.services.resources;
import org.jboss.resteasy.jose.jws.JWSInput;
import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
+import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
@@ -52,6 +53,7 @@ import java.util.Set;
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class RequiredActionsService {
+ protected static final Logger logger = Logger.getLogger(RequiredActionsService.class);
private RealmModel realm;
@@ -134,10 +136,13 @@ public class RequiredActionsService {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response updatePassword(final MultivaluedMap<String, String> formData) {
+ logger.info("updatePassword");
AccessCodeEntry accessCode = getAccessCodeEntry(RequiredAction.UPDATE_PASSWORD);
if (accessCode == null) {
+ logger.info("updatePassword access code is null");
return forwardToErrorPage();
}
+ logger.info("updatePassword has access code");
UserModel user = getUser(accessCode);
@@ -158,6 +163,8 @@ public class RequiredActionsService {
realm.updateCredential(user, credentials);
+ logger.info("updatePassword updated credential");
+
user.removeRequiredAction(RequiredAction.UPDATE_PASSWORD);
if (accessCode != null) {
accessCode.getRequiredActions().remove(RequiredAction.UPDATE_PASSWORD);
@@ -257,6 +264,7 @@ public class RequiredActionsService {
private AccessCodeEntry getAccessCodeEntry(RequiredAction requiredAction) {
String code = uriInfo.getQueryParameters().getFirst(FormFlows.CODE);
if (code == null) {
+ logger.info("getAccessCodeEntry code as not in query param");
return null;
}
@@ -265,24 +273,31 @@ public class RequiredActionsService {
try {
verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
} catch (Exception ignored) {
+ logger.info("getAccessCodeEntry code failed verification");
return null;
}
if (!verifiedCode) {
+ logger.info("getAccessCodeEntry code failed verification2");
return null;
}
String key = input.readContent(String.class);
AccessCodeEntry accessCodeEntry = tokenManager.getAccessCode(key);
if (accessCodeEntry == null) {
+ logger.info("getAccessCodeEntry access code entry null");
return null;
}
if (accessCodeEntry.isExpired()) {
+ logger.info("getAccessCodeEntry: access code id: " + accessCodeEntry.getId());
+ logger.info("getAccessCodeEntry access code entry expired: " + accessCodeEntry.getExpiration());
+ logger.info("getAccessCodeEntry current time: " + (System.currentTimeMillis() / 1000));
return null;
}
if (accessCodeEntry.getRequiredActions() == null || !accessCodeEntry.getRequiredActions().contains(requiredAction)) {
+ logger.info("getAccessCodeEntry required actions null || entry does not contain required action: " + (accessCodeEntry.getRequiredActions() == null) + "|" + !accessCodeEntry.getRequiredActions().contains(requiredAction) );
return null;
}
@@ -303,6 +318,7 @@ public class RequiredActionsService {
return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode).setUser(user)
.forwardToAction(requiredActions.iterator().next());
} else {
+ logger.info("redirectOauth: redirecting to: " + accessCode.getRedirectUri());
accessCode.setExpiration((System.currentTimeMillis() / 1000) + realm.getAccessCodeLifespan());
return Flows.oauth(realm, request, uriInfo, authManager, tokenManager).redirectAccessCode(accessCode,
accessCode.getState(), accessCode.getRedirectUri());
diff --git a/services/src/main/java/org/keycloak/services/resources/SaasService.java b/services/src/main/java/org/keycloak/services/resources/SaasService.java
index 0b2c08d..b8d2e82 100755
--- a/services/src/main/java/org/keycloak/services/resources/SaasService.java
+++ b/services/src/main/java/org/keycloak/services/resources/SaasService.java
@@ -1,21 +1,33 @@
package org.keycloak.services.resources;
import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.jose.jws.JWSInput;
+import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.jboss.resteasy.spi.NotImplementedYetException;
+import org.keycloak.AbstractOAuthClient;
+import org.keycloak.jaxrs.JaxrsOAuthClient;
import org.keycloak.models.*;
+import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.services.managers.AccessCodeEntry;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.admin.RealmsAdminResource;
import org.keycloak.services.resources.flows.Flows;
+import org.keycloak.services.resources.flows.OAuthFlows;
import javax.ws.rs.*;
import javax.ws.rs.container.ResourceContext;
import javax.ws.rs.core.*;
+import javax.ws.rs.ext.Providers;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -42,8 +54,17 @@ public class SaasService {
@Context
protected ResourceContext resourceContext;
+ @Context
+ protected Providers providers;
+
+
protected String adminPath = "/admin/index.html";
protected AuthenticationManager authManager = new AuthenticationManager();
+ protected TokenManager tokenManager;
+
+ public SaasService(TokenManager tokenManager) {
+ this.tokenManager = tokenManager;
+ }
public static class WhoAmI {
protected String userId;
@@ -168,7 +189,99 @@ public class SaasService {
RealmModel realm = getAdminstrationRealm(realmManager);
authManager.expireSaasIdentityCookie(uriInfo);
- return Flows.forms(realm, request, uriInfo).forwardToLogin();
+ JaxrsOAuthClient oauth = new JaxrsOAuthClient();
+ String authUrl = TokenService.loginPageUrl(uriInfo).build(Constants.ADMIN_REALM).toString();
+ logger.info("authUrl: " + authUrl);
+ oauth.setAuthUrl(authUrl);
+ oauth.setClientId(Constants.ADMIN_CONSOLE_APPLICATION);
+ URI redirectUri = uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "loginRedirect").build();
+ logger.info("redirectUri: " + redirectUri.toString());
+ oauth.setStateCookiePath(redirectUri.getPath());
+ return oauth.redirect(uriInfo, redirectUri.toString());
+ }
+
+ @Path("login-redirect")
+ @GET
+ @NoCache
+ public Response loginRedirect(@QueryParam("code") String code,
+ @QueryParam("state") String state,
+ @QueryParam("error") String error,
+ @Context HttpHeaders headers
+
+ ) {
+ try {
+ logger.info("loginRedirect ********************** <---");
+ if (error != null) {
+ logger.debug("error from oauth");
+ throw new ForbiddenException("error");
+ }
+ RealmManager realmManager = new RealmManager(session);
+ RealmModel realm = getAdminstrationRealm(realmManager);
+ if (!realm.isEnabled()) {
+ logger.debug("realm not enabled");
+ throw new ForbiddenException();
+ }
+ ApplicationModel adminConsole = realm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
+ UserModel adminConsoleUser = adminConsole.getApplicationUser();
+ if (!adminConsole.isEnabled() || !adminConsoleUser.isEnabled()) {
+ logger.debug("admin app not enabled");
+ throw new ForbiddenException();
+ }
+
+ if (code == null) {
+ logger.debug("code not specified");
+ throw new BadRequestException();
+ }
+ if (state == null) {
+ logger.debug("state not specified");
+ throw new BadRequestException();
+ }
+ new JaxrsOAuthClient().checkStateCookie(uriInfo, headers);
+
+ JWSInput input = new JWSInput(code, providers);
+ boolean verifiedCode = false;
+ try {
+ verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
+ } catch (Exception ignored) {
+ logger.debug("Failed to verify signature", ignored);
+ }
+ if (!verifiedCode) {
+ logger.debug("unverified access code");
+ throw new BadRequestException();
+ }
+ String key = input.readContent(String.class);
+ AccessCodeEntry accessCode = tokenManager.pullAccessCode(key);
+ if (accessCode == null) {
+ logger.debug("bad access code");
+ throw new BadRequestException();
+ }
+ if (accessCode.isExpired()) {
+ logger.debug("access code expired");
+ throw new BadRequestException();
+ }
+ if (!accessCode.getToken().isActive()) {
+ logger.debug("access token expired");
+ throw new BadRequestException();
+ }
+ if (!accessCode.getRealm().getId().equals(realm.getId())) {
+ logger.debug("bad realm");
+ throw new BadRequestException();
+
+ }
+ if (!adminConsoleUser.getLoginName().equals(accessCode.getClient().getLoginName())) {
+ logger.debug("bad client");
+ throw new BadRequestException();
+ }
+ if (!adminConsole.hasRole(accessCode.getUser(), Constants.ADMIN_CONSOLE_ADMIN_ROLE)) {
+ logger.debug("not allowed");
+ throw new ForbiddenException();
+ }
+ logger.info("loginRedirect SUCCESS");
+ NewCookie cookie = authManager.createSaasIdentityCookie(realm, accessCode.getUser(), uriInfo);
+ return Response.status(302).cookie(cookie).location(contextRoot(uriInfo).path(adminPath).build()).build();
+ } finally {
+ authManager.expireCookie(AbstractOAuthClient.OAUTH_TOKEN_REQUEST_STATE, uriInfo.getAbsolutePath().getPath());
+ }
}
@Path("logout")
@@ -178,8 +291,9 @@ public class SaasService {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = getAdminstrationRealm(realmManager);
authManager.expireSaasIdentityCookie(uriInfo);
+ authManager.expireIdentityCookie(realm, uriInfo);
- return Flows.forms(realm, request, uriInfo).forwardToLogin();
+ return Response.status(302).location(uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "loginPage").build()).build();
}
@Path("logout-cookie")
@@ -199,6 +313,8 @@ public class SaasService {
RealmModel realm = getAdminstrationRealm(realmManager);
if (realm == null)
throw new NotFoundException();
+ ApplicationModel adminConsole = realm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
+ UserModel adminConsoleUser = adminConsole.getApplicationUser();
if (!realm.isEnabled()) {
throw new NotImplementedYetException();
@@ -208,6 +324,8 @@ public class SaasService {
AuthenticationStatus status = authManager.authenticateForm(realm, user, formData);
+ OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager);
+
switch (status) {
case SUCCESS:
NewCookie cookie = authManager.createSaasIdentityCookie(realm, user, uriInfo);
@@ -216,7 +334,7 @@ public class SaasService {
return Flows.forms(realm, request, uriInfo).setError(Messages.ACCOUNT_DISABLED).setFormData(formData)
.forwardToLogin();
case ACTIONS_REQUIRED:
- return Flows.forms(realm, request, uriInfo).forwardToAction(user.getRequiredActions().iterator().next());
+ return oauth.processAccessCode(null, "n", contextRoot(uriInfo).path(adminPath).build().toString(), adminConsoleUser, user);
default:
return Flows.forms(realm, request, uriInfo).setError(Messages.INVALID_USER).setFormData(formData)
.forwardToLogin();