keycloak-uncached

improved oauth login/grant

8/5/2014 8:36:19 PM

Details

diff --git a/forms/common-themes/src/main/resources/theme/login/base/login.ftl b/forms/common-themes/src/main/resources/theme/login/base/login.ftl
index 9bc1570..6fd5808 100755
--- a/forms/common-themes/src/main/resources/theme/login/base/login.ftl
+++ b/forms/common-themes/src/main/resources/theme/login/base/login.ftl
@@ -1,9 +1,17 @@
 <#import "template.ftl" as layout>
 <@layout.registrationLayout displayInfo=social.displayInfo; section>
     <#if section = "title">
-        ${rb.loginTitle} ${realm.name}
+        <#if client.application>
+             ${rb.loginTitle} ${realm.name}
+        <#elseif client.oauthClient>
+             ${realm.name} ${rb.loginOauthTitle}
+        </#if>
     <#elseif section = "header">
-        ${rb.loginTitle} <strong>${(realm.name)!''}</strong>
+        <#if client.application>
+             ${rb.loginTitle} <strong>${(realm.name)!''}</strong>
+        <#elseif client.oauthClient>
+             Temporary access for <strong>${(realm.name)!''}</strong> requested by <strong>${(client.clientId)!''}</strong>.
+        </#if>
     <#elseif section = "form">
         <#if realm.password>
             <form id="kc-form-login" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
diff --git a/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl b/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl
index a44b2c7..e8cfbf3 100755
--- a/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl
+++ b/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl
@@ -4,10 +4,10 @@
     <#if section = "title">
         ${rb.oauthGrantTitle}
     <#elseif section = "header">
-        ${rb.oauthGrantTitleHtml}
+        Temporary access for <strong>${(realm.name)!''}</strong> requested by <strong>${(client.clientId)!''}</strong>.
     <#elseif section = "form">
         <div id="kc-oauth" class="content-area">
-            <h3><strong>${oauth.client}</strong> ${rb.oauthGrantRequest}</h3>
+            <h3>${rb.oauthGrantRequest}</h3>
             <ul>
                 <#if oauth.claimsRequested??>
                     <li>
@@ -45,8 +45,8 @@
 
                     <div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
                         <div class="${properties.kcFormButtonsWrapperClass!}">
-                            <input class="btn btn-primary btn-lg" name="accept" id="kc-login" type="submit" value="${rb.accept}"/>
-                            <input class="btn btn-default btn-lg" name="cancel" id="kc-cancel" type="submit" value="${rb.cancel}"/>
+                            <input class="btn btn-primary btn-lg" name="accept" id="kc-login" type="submit" value="${rb.yes}"/>
+                            <input class="btn btn-default btn-lg" name="cancel" id="kc-cancel" type="submit" value="${rb.no}"/>
                         </div>
                     </div>
                 </div>
diff --git a/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties b/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
index 5bac22e..e7a0eb9 100755
--- a/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
+++ b/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
@@ -23,6 +23,8 @@ passwordNewConfirm=New Password confirmation
 cancel=Cancel
 accept=Accept
 submit=Submit
+yes=Yes
+no=No
 
 authenticatorCode=One-time-password
 clientCertificate=Client Certificate
@@ -50,6 +52,8 @@ successTotpRemoved=Google authenticator removed.
 usernameExists=Username already exists
 
 loginTitle=Log in to
+loginOauthTitle=Temporary access.
+loginOauthTitleHtml=Temporary access requested.  Login to grant access.
 loginForgot=Forgot
 
 loginTotpTitle=Google Authenticator Setup
@@ -67,9 +71,10 @@ loginProfileError=Some required fields are empty or incorrect.
 loginProfileErrorSteps=Please correct the fields in red.
 
 oauthGrantTitle=OAuth Grant
-oauthGrantTitleHtml=<strong>Keycloak</strong> Central Login
+oauthGrantTitleHtml=Temporary access requested
 oauthGrantTerms=Keycloak Central Login and Google will use this information in accordance with their respective terms of service and privacy policies.
-oauthGrantRequest=requests access to:
+oauthGrantRequest=Do you grant these access privileges?
+oauthGrantLoginRequest=Do you grant access?
 
 emailVerifyTitle=Email verification
 emailVerifyInstr=An email with instructions to verify your email address has been sent to you.
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
index f0540ad..fcabeb1 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
@@ -10,6 +10,7 @@ import org.keycloak.freemarker.Theme;
 import org.keycloak.freemarker.ThemeProvider;
 import org.keycloak.login.LoginFormsPages;
 import org.keycloak.login.LoginFormsProvider;
+import org.keycloak.login.freemarker.model.ClientBean;
 import org.keycloak.login.freemarker.model.CodeBean;
 import org.keycloak.login.freemarker.model.LoginBean;
 import org.keycloak.login.freemarker.model.MessageBean;
@@ -189,6 +190,10 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
             attributes.put("url", new UrlBean(realm, theme, baseUri));
         }
 
+        if (client != null) {
+            attributes.put("client", new ClientBean(client));
+        }
+
         attributes.put("login", new LoginBean(formData));
 
         switch (page) {
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
new file mode 100755
index 0000000..4507762
--- /dev/null
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
@@ -0,0 +1,29 @@
+package org.keycloak.login.freemarker.model;
+
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.OAuthClientModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ClientBean {
+    protected ClientModel client;
+
+    public ClientBean(ClientModel client) {
+        this.client = client;
+    }
+
+    public boolean isApplication() {
+        return client instanceof ApplicationModel;
+    }
+
+    public boolean isOauthClient() {
+        return client instanceof OAuthClientModel;
+    }
+
+    public String getClientId() {
+        return client.getClientId();
+    }
+}
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
index 664b25b..a5551b0 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
@@ -41,8 +41,6 @@ public class OAuthGrantBean {
     private String code;
     private ClientModel client;
     private List<String> claimsRequested;
-    private String oAuthCode;
-    private String action;
 
     public OAuthGrantBean(String code, ClientModel client, List<RoleModel> realmRolesRequested, MultivaluedMap<String, RoleModel> resourceRolesRequested) {
         this.code = code;
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 17147fb..dca8ad1 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -189,7 +189,7 @@ public class AccountService {
             try {
                 require(AccountRoles.MANAGE_ACCOUNT);
             } catch (ForbiddenException e) {
-                return Flows.forms(session, realm, uriInfo).setError("No access").createErrorPage();
+                return Flows.forms(session, realm, null, uriInfo).setError("No access").createErrorPage();
             }
 
             String[] referrer = getReferrer();
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Flows.java b/services/src/main/java/org/keycloak/services/resources/flows/Flows.java
index 781edbc..9765c56 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Flows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Flows.java
@@ -24,6 +24,7 @@ package org.keycloak.services.resources.flows;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.keycloak.ClientConnection;
 import org.keycloak.login.LoginFormsProvider;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.services.managers.AuthenticationManager;
@@ -40,8 +41,8 @@ public class Flows {
     private Flows() {
     }
 
-    public static LoginFormsProvider forms(KeycloakSession session, RealmModel realm, UriInfo uriInfo) {
-        return session.getProvider(LoginFormsProvider.class).setRealm(realm).setUriInfo(uriInfo);
+    public static LoginFormsProvider forms(KeycloakSession session, RealmModel realm, ClientModel client, UriInfo uriInfo) {
+        return session.getProvider(LoginFormsProvider.class).setRealm(realm).setUriInfo(uriInfo).setClient(client);
     }
 
     public static OAuthFlows oauth(KeycloakSession session, RealmModel realm, HttpRequest request, UriInfo uriInfo, ClientConnection clientConnection, AuthenticationManager authManager,
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
index 621bb1c..68bf394 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
@@ -142,7 +142,7 @@ public class OAuthFlows {
                 audit.clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, accessCode.getUser().getEmail()).success();
             }
 
-            return Flows.forms(this.session, realm, uriInfo).setAccessCode(accessCode.getCode()).setUser(user)
+            return Flows.forms(this.session, realm, client, uriInfo).setAccessCode(accessCode.getCode()).setUser(user)
                     .createResponse(action);
         }
 
@@ -159,7 +159,7 @@ public class OAuthFlows {
                 }
             }
 
-            return Flows.forms(this.session, realm, uriInfo)
+            return Flows.forms(this.session, realm, client, uriInfo)
                     .setAccessCode(accessCode.getCode())
                     .setAccessRequest(realmRoles, resourceRoles)
                     .setClient(client)
@@ -177,7 +177,7 @@ public class OAuthFlows {
     }
 
     public Response forwardToSecurityFailure(String message) {
-        return Flows.forms(session, realm, uriInfo).setError(message).createErrorPage();
+        return Flows.forms(session, realm, null, uriInfo).setError(message).createErrorPage();
     }
 
     private void isTotpConfigurationRequired(UserModel user) {
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 5d598e6..4e33e75 100755
--- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
@@ -116,7 +116,7 @@ public class RequiredActionsService {
 
         String error = Validation.validateUpdateProfileForm(formData);
         if (error != null) {
-            return Flows.forms(session, realm, uriInfo).setUser(user).setError(error).createResponse(RequiredAction.UPDATE_PROFILE);
+            return Flows.forms(session, realm, null, uriInfo).setUser(user).setError(error).createResponse(RequiredAction.UPDATE_PROFILE);
         }
 
         user.setFirstName(formData.getFirst("firstName"));
@@ -155,7 +155,7 @@ public class RequiredActionsService {
         String totp = formData.getFirst("totp");
         String totpSecret = formData.getFirst("totpSecret");
 
-        LoginFormsProvider loginForms = Flows.forms(session, realm, uriInfo).setUser(user);
+        LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
         if (Validation.isEmpty(totp)) {
             return loginForms.setError(Messages.MISSING_TOTP).createResponse(RequiredAction.CONFIGURE_TOTP);
         } else if (!new TimeBasedOTP().validate(totp, totpSecret.getBytes())) {
@@ -195,7 +195,7 @@ public class RequiredActionsService {
         String passwordNew = formData.getFirst("password-new");
         String passwordConfirm = formData.getFirst("password-confirm");
 
-        LoginFormsProvider loginForms = Flows.forms(session, realm, uriInfo).setUser(user);
+        LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
         if (Validation.isEmpty(passwordNew)) {
             return loginForms.setError(Messages.MISSING_PASSWORD).createResponse(RequiredAction.UPDATE_PASSWORD);
         } else if (!passwordNew.equals(passwordConfirm)) {
@@ -251,7 +251,7 @@ public class RequiredActionsService {
 
             initAudit(accessCode);
 
-            return Flows.forms(session, realm, uriInfo).setAccessCode(accessCode.getCode()).setUser(accessCode.getUser())
+            return Flows.forms(session, realm, null, uriInfo).setAccessCode(accessCode.getCode()).setUser(accessCode.getUser())
                     .createResponse(RequiredAction.VERIFY_EMAIL);
         }
     }
@@ -265,9 +265,9 @@ public class RequiredActionsService {
                 return unauthorized();
             }
 
-            return Flows.forms(session, realm, uriInfo).setAccessCode(accessCode.getCode()).createResponse(RequiredAction.UPDATE_PASSWORD);
+            return Flows.forms(session, realm, null, uriInfo).setAccessCode(accessCode.getCode()).createResponse(RequiredAction.UPDATE_PASSWORD);
         } else {
-            return Flows.forms(session, realm, uriInfo).createPasswordReset();
+            return Flows.forms(session, realm, null, uriInfo).createPasswordReset();
         }
     }
 
@@ -327,11 +327,11 @@ public class RequiredActionsService {
                 audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success();
             } catch (EmailException e) {
                 logger.error("Failed to send password reset email", e);
-                return Flows.forms(this.session, realm, uriInfo).setError("emailSendError").createErrorPage();
+                return Flows.forms(this.session, realm, client, uriInfo).setError("emailSendError").createErrorPage();
             }
         }
 
-        return Flows.forms(session, realm, uriInfo).setSuccess("emailSent").createPasswordReset();
+        return Flows.forms(session, realm, client,  uriInfo).setSuccess("emailSent").createPasswordReset();
     }
 
     private AccessCode getAccessCodeEntry(RequiredAction requiredAction) {
@@ -368,7 +368,7 @@ public class RequiredActionsService {
         Set<RequiredAction> requiredActions = user.getRequiredActions();
         if (!requiredActions.isEmpty()) {
             accessCode.setRequiredAction(requiredActions.iterator().next());
-            return Flows.forms(session, realm, uriInfo).setAccessCode(accessCode.getCode()).setUser(user)
+            return Flows.forms(session, realm, null, uriInfo).setAccessCode(accessCode.getCode()).setUser(user)
                     .createResponse(requiredActions.iterator().next());
         } else {
             logger.debugv("redirectOauth: redirecting to: {0}", accessCode.getRedirectUri());
@@ -410,7 +410,7 @@ public class RequiredActionsService {
     }
 
     private Response unauthorized() {
-        return Flows.forms(session, realm, uriInfo).setError("Unauthorized request").createErrorPage();
+        return Flows.forms(session, realm, null, uriInfo).setError("Unauthorized request").createErrorPage();
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
index e9acd79..84439e4 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -110,7 +110,7 @@ public class SocialResource {
             initialRequest = new JWSInput(encodedState).readJsonContent(State.class);
         } catch (Throwable t) {
             logger.warn("Invalid social callback", t);
-            return Flows.forms(session, null, uriInfo).setError("Unexpected callback").createErrorPage();
+            return Flows.forms(session, null, null, uriInfo).setError("Unexpected callback").createErrorPage();
         }
 
         SocialProvider provider = SocialLoader.load(initialRequest.getProvider());
@@ -174,7 +174,7 @@ public class SocialResource {
             queryParms.putSingle(OAuth2Constants.RESPONSE_TYPE, responseType);
 
             audit.error(Errors.REJECTED_BY_USER);
-            return  Flows.forms(session, realm, uriInfo).setQueryParams(queryParms).setWarning("Access denied").createLogin();
+            return  Flows.forms(session, realm, client, uriInfo).setQueryParams(queryParms).setWarning("Access denied").createLogin();
         } catch (SocialProviderException e) {
             logger.error("Failed to process social callback", e);
             return oauth.forwardToSecurityFailure("Failed to process social callback");
@@ -278,25 +278,25 @@ public class SocialResource {
         SocialProvider provider = SocialLoader.load(providerId);
         if (provider == null) {
             audit.error(Errors.SOCIAL_PROVIDER_NOT_FOUND);
-            return Flows.forms(session, realm, uriInfo).setError("Social provider not found").createErrorPage();
+            return Flows.forms(session, realm, null, uriInfo).setError("Social provider not found").createErrorPage();
         }
 
         ClientModel client = realm.findClient(clientId);
         if (client == null) {
             audit.error(Errors.CLIENT_NOT_FOUND);
             logger.warn("Unknown login requester: " + clientId);
-            return Flows.forms(session, realm, uriInfo).setError("Unknown login requester.").createErrorPage();
+            return Flows.forms(session, realm, null, uriInfo).setError("Unknown login requester.").createErrorPage();
         }
 
         if (!client.isEnabled()) {
             audit.error(Errors.CLIENT_DISABLED);
             logger.warn("Login requester not enabled.");
-            return Flows.forms(session, realm, uriInfo).setError("Login requester not enabled.").createErrorPage();
+            return Flows.forms(session, realm, null, uriInfo).setError("Login requester not enabled.").createErrorPage();
         }
         redirectUri = TokenService.verifyRedirectUri(uriInfo, redirectUri, realm, client);
         if (redirectUri == null) {
             audit.error(Errors.INVALID_REDIRECT_URI);
-            return Flows.forms(session, realm, uriInfo).setError("Invalid redirect_uri.").createErrorPage();
+            return Flows.forms(session, realm, null, uriInfo).setError("Invalid redirect_uri.").createErrorPage();
         }
 
         try {
@@ -309,7 +309,7 @@ public class SocialResource {
                     .redirectToSocialProvider();
         } catch (Throwable t) {
             logger.error("Failed to redirect to social auth", t);
-            return Flows.forms(session, realm, uriInfo).setError("Failed to redirect to social auth").createErrorPage();
+            return Flows.forms(session, realm, null, uriInfo).setError("Failed to redirect to social auth").createErrorPage();
         }
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 67d29bb..a466c31 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -538,18 +538,18 @@ public class TokenService {
                 return oauth.processAccessCode(scopeParam, state, redirect, client, user, userSession, 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();
+                return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.ACCOUNT_TEMPORARILY_DISABLED).setFormData(formData).createLogin();
             case ACCOUNT_DISABLED:
                 audit.error(Errors.USER_DISABLED);
-                return Flows.forms(this.session, realm, uriInfo).setError(Messages.ACCOUNT_DISABLED).setFormData(formData).createLogin();
+                return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.ACCOUNT_DISABLED).setFormData(formData).createLogin();
             case MISSING_TOTP:
-                return Flows.forms(this.session, realm, uriInfo).setFormData(formData).createLoginTotp();
+                return Flows.forms(this.session, realm, client, uriInfo).setFormData(formData).createLoginTotp();
             case INVALID_USER:
                 audit.error(Errors.USER_NOT_FOUND);
-                return Flows.forms(this.session, realm, uriInfo).setError(Messages.INVALID_USER).setFormData(formData).createLogin();
+                return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER).setFormData(formData).createLogin();
             default:
                 audit.error(Errors.INVALID_USER_CREDENTIALS);
-                return Flows.forms(this.session, realm, uriInfo).setError(Messages.INVALID_USER).setFormData(formData).createLogin();
+                return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER).setFormData(formData).createLogin();
         }
     }
 
@@ -634,13 +634,13 @@ public class TokenService {
 
         if (error != null) {
             audit.error(Errors.INVALID_REGISTRATION);
-            return Flows.forms(session, realm, uriInfo).setError(error).setFormData(formData).createRegistration();
+            return Flows.forms(session, realm, client, uriInfo).setError(error).setFormData(formData).createRegistration();
         }
 
         // Validate that user with this username doesn't exist in realm or any authentication provider
         if (session.users().getUserByUsername(username, realm) != null) {
             audit.error(Errors.USERNAME_IN_USE);
-            return Flows.forms(session, realm, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).createRegistration();
+            return Flows.forms(session, realm, client, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).createRegistration();
         }
 
         UserModel user = session.users().addUser(realm, username);
@@ -668,7 +668,7 @@ public class TokenService {
             // User already registered, but force him to update password
             if (!passwordUpdateSuccessful) {
                 user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
-                return Flows.forms(session, realm, uriInfo).setError(passwordUpdateError).createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
+                return Flows.forms(session, realm, client, uriInfo).setError(passwordUpdateError).createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
             }
         }
 
@@ -959,7 +959,7 @@ public class TokenService {
             return oauth.redirectError(client, "access_denied", state, redirect);
         }
 
-        LoginFormsProvider forms = Flows.forms(session, realm, uriInfo);
+        LoginFormsProvider forms = Flows.forms(session, realm, client, uriInfo);
 
         if (loginHint != null) {
             MultivaluedMap<String, String> formData = new MultivaluedMapImpl<String, String>();
@@ -1028,7 +1028,7 @@ public class TokenService {
 
         authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
 
-        return Flows.forms(session, realm, uriInfo).createRegistration();
+        return Flows.forms(session, realm, client, uriInfo).createRegistration();
     }
 
     /**
@@ -1150,7 +1150,7 @@ public class TokenService {
     @Path("oauth/oob")
     @GET
     public Response installedAppUrnCallback(final @QueryParam("code") String code, final @QueryParam("error") String error, final @QueryParam("error_description") String errorDescription) {
-        LoginFormsProvider forms = Flows.forms(session, realm, uriInfo);
+        LoginFormsProvider forms = Flows.forms(session, realm, null, uriInfo);
         if (code != null) {
             return forms.setAccessCode(code).createCode();
         } else {