keycloak-memoizeit
Changes
examples/as7-eap-demo/server/pom.xml 2(+1 -1)
forms/pom.xml 4(+2 -2)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/customer-login-screen-bg.jpg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/customer-login-screen-bg.svg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/feedback-error-arrow-down.png 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/feedback-error-arrow-down.svg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/feedback-error-sign.png 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/feedback-error-sign.svg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/login-register-separator.svg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/login-register-separators.png 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/login-register-social-separators.png 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/login-register-social-separators.svg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/img/register-login-bg.png 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/zocial/zocial-regular-webfont.eot 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/zocial/zocial-regular-webfont.svg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/zocial/zocial-regular-webfont.ttf 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/css/zocial/zocial-regular-webfont.woff 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/img/customer-login-screen-bg2.jpg 0(+0 -0)
forms/src/main/resources/META-INF/resources/sdk/theme/default/img/login-screen-background.jpg 0(+0 -0)
pom.xml 2(+1 -1)
Details
examples/as7-eap-demo/server/pom.xml 2(+1 -1)
diff --git a/examples/as7-eap-demo/server/pom.xml b/examples/as7-eap-demo/server/pom.xml
index 5cfb75b..a0b7c26 100755
--- a/examples/as7-eap-demo/server/pom.xml
+++ b/examples/as7-eap-demo/server/pom.xml
@@ -52,7 +52,7 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-sdk-html</artifactId>
+ <artifactId>keycloak-forms</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html
index e10cd0c..21c4733 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/menu.html
@@ -12,8 +12,8 @@
<!-- <select class="nav pull-left" ng-options="r.name for r in current.realms"></select> -->
</div>
<ul class="nav pull-right" data-ng-hide="auth.loggedIn">
- <li><a href="/auth-server/rest/saas/loginPage.html">Login</a></li>
- <li><a href="/auth-server/saas/saas-register.jsp">Register</a></li>
+ <li><a href="/auth-server/rest/saas/login">Login</a></li>
+ <li><a href="/auth-server/rest/saas/registrations">Register</a></li>
</ul>
<ul class="nav pull-right" data-ng-show="auth.loggedIn">
<li class="divider-vertical-left dropdown"><a data-toggle="dropdown" class="dropdown-toggle" href="#"><i
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index b55e06d..b0e3b22 100755
--- a/pom.xml
+++ b/pom.xml
@@ -58,7 +58,7 @@
<module>integration</module>
<module>examples</module>
<module>social</module>
- <module>sdk-html</module>
+ <module>forms</module>
<!--<module>ui</module> -->
</modules>
diff --git a/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java b/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java
index 857c0ce..e834965 100644
--- a/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java
+++ b/services/src/main/java/org/keycloak/services/resources/OAuthUtil.java
@@ -1,7 +1,5 @@
package org.keycloak.services.resources;
-import java.net.URI;
-
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
@@ -22,7 +20,6 @@ public class OAuthUtil {
private static final Logger log = Logger.getLogger(OAuthUtil.class);
public final static String securityFailurePath = "/saas/securityFailure.jsp";
- public final static String loginFormPath = "/sdk/login.xhtml";
public final static String oauthFormPath = "/saas/oauthGrantForm.jsp";
public static Response processAccessCode(RealmModel realm, TokenManager tokenManager, AuthenticationManager authManager,
@@ -75,16 +72,22 @@ public class OAuthUtil {
public static void forwardToLoginForm(RealmModel realm, HttpRequest request, UriInfo uriInfo, String redirect,
String clientId, String scopeParam, String state) {
request.setAttribute(RealmModel.class.getName(), realm);
- request.setAttribute("KEYCLOAK_LOGIN_ACTION", TokenService.processLoginUrl(uriInfo).build(realm.getId()));
- request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", SocialResource.redirectToProviderAuthUrl(uriInfo).build(realm.getId()));
- request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", URI.create("not-implemented-yet"));
+
+ request.setAttribute("KEYCLOAK_LOGIN_PAGE", Urls.realmLoginPage(uriInfo, realm.getId()));
+ request.setAttribute("KEYCLOAK_LOGIN_ACTION", Urls.realmLoginAction(uriInfo, realm.getId()));
+
+ request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", Urls.realmRegisterPage(uriInfo, realm.getId()));
+ request.setAttribute("KEYCLOAK_REGISTRATION_ACTION", Urls.realmRegisterAction(uriInfo, realm.getId()));
+
+ request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", Urls.socialRedirectToProviderAuth(uriInfo, realm.getId()));
// RESTEASY eats the form data, so we send via an attribute
request.setAttribute("redirect_uri", redirect);
request.setAttribute("client_id", clientId);
request.setAttribute("scope", scopeParam);
request.setAttribute("state", state);
- request.forward(loginFormPath);
+
+ request.forward(Pages.loginForm);
}
public static void oauthGrantPage(RealmModel realm, HttpRequest request, UriInfo uriInfo, AccessCodeEntry accessCode,
diff --git a/services/src/main/java/org/keycloak/services/resources/Pages.java b/services/src/main/java/org/keycloak/services/resources/Pages.java
new file mode 100644
index 0000000..ae56297
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/Pages.java
@@ -0,0 +1,8 @@
+package org.keycloak.services.resources;
+
+public class Pages {
+
+ public final static String loginForm = "/sdk/login.xhtml";
+ public final static String registerForm = "/sdk/register.xhtml";
+
+}
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 7b5cb43..af8b1aa 100755
--- a/services/src/main/java/org/keycloak/services/resources/SaasService.java
+++ b/services/src/main/java/org/keycloak/services/resources/SaasService.java
@@ -39,8 +39,6 @@ public class SaasService {
@Context
HttpResponse response;
- protected String saasLoginPath = "/saas/saas-login.jsp";
- protected String saasRegisterPath = "/saas/saas-register.jsp";
protected String adminPath = "/saas/admin/index.html";
protected AuthenticationManager authManager = new AuthenticationManager();
@@ -170,7 +168,7 @@ public class SaasService {
}.call();
}
- @Path("loginPage.html")
+ @Path("login")
@GET
@NoCache
public void loginPage() {
@@ -180,7 +178,22 @@ public class SaasService {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = realmManager.defaultRealm();
authManager.expireSaasIdentityCookie(uriInfo);
- forwardToLoginForm(realm);
+ forwardToLoginForm(realm, null, null);
+ }
+ }.run();
+ }
+
+ @Path("registrations")
+ @GET
+ @NoCache
+ public void registerPage() {
+ new Transaction() {
+ @Override
+ protected void runImpl() {
+ RealmManager realmManager = new RealmManager(session);
+ RealmModel realm = realmManager.defaultRealm();
+ authManager.expireSaasIdentityCookie(uriInfo);
+ forwardToRegisterForm(realm, null, null);
}
}.run();
}
@@ -195,7 +208,7 @@ public class SaasService {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = realmManager.defaultRealm();
authManager.expireSaasIdentityCookie(uriInfo);
- forwardToLoginForm(realm);
+ forwardToLoginForm(realm, null, null);
}
}.run();
}
@@ -214,16 +227,42 @@ public class SaasService {
}.run();
}
- public final static String loginFormPath = "/sdk/login.xhtml";
+ protected void forwardToLoginForm(RealmModel realm, String error, MultivaluedMap<String, String> formData) {
+ if (error != null) {
+ request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", error);
+ }
+
+ if (formData != null) {
+ request.setAttribute("KEYCLOAK_FORM_DATA", formData);
+ }
+
+ forwardToForm(realm, Pages.loginForm);
+ }
+
+ protected void forwardToRegisterForm(RealmModel realm, String error, MultivaluedMap<String, String> formData) {
+ if (error != null) {
+ request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", error);
+ }
+
+ if (formData != null) {
+ request.setAttribute("KEYCLOAK_FORM_DATA", formData);
+ }
+
+ forwardToForm(realm, Pages.registerForm);
+ }
- protected void forwardToLoginForm(RealmModel realm) {
+ protected void forwardToForm(RealmModel realm, String form) {
request.setAttribute(RealmModel.class.getName(), realm);
- URI action = uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processLogin").build();
- URI register = contextRoot(uriInfo).path(saasRegisterPath).build();
- request.setAttribute("KEYCLOAK_LOGIN_ACTION", action);
- request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", register);
- request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", SocialResource.redirectToProviderAuthUrl(uriInfo).build(realm.getId()));
- request.forward(loginFormPath);
+
+ request.setAttribute("KEYCLOAK_LOGIN_PAGE", Urls.saasLoginPage(uriInfo));
+ request.setAttribute("KEYCLOAK_LOGIN_ACTION", Urls.saasLoginAction(uriInfo));
+
+ request.setAttribute("KEYCLOAK_REGISTRATION_PAGE", Urls.saasRegisterPage(uriInfo));
+ request.setAttribute("KEYCLOAK_REGISTRATION_ACTION", Urls.saasRegisterAction(uriInfo));
+
+ request.setAttribute("KEYCLOAK_SOCIAL_LOGIN", Urls.socialRedirectToProviderAuth(uriInfo, realm.getId()));
+
+ request.forward(form);
}
@@ -246,22 +285,19 @@ public class SaasService {
UserModel user = realm.getUser(username);
if (user == null) {
logger.info("Not Authenticated! Incorrect user name");
- request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
- forwardToLoginForm(realm);
+ forwardToLoginForm(realm, "Invalid username or password", formData);
return null;
}
if (!user.isEnabled()) {
logger.info("NAccount is disabled, contact admin.");
- request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Account is disabled, contact admin.");
- forwardToLoginForm(realm);
+ forwardToLoginForm(realm, "Account is disabled, contact admin.", formData);
return null;
}
boolean authenticated = authManager.authenticateForm(realm, user, formData);
if (!authenticated) {
logger.info("Not Authenticated! Invalid credentials");
- request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid credentials.");
- forwardToLoginForm(realm);
+ forwardToLoginForm(realm, "Invalid username or password", formData);
return null;
}
@@ -295,24 +331,24 @@ public class SaasService {
@Path("registrations")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
- public Response processRegister(final @FormParam("name") String fullname,
- final @FormParam("email") String email,
- final @FormParam("username") String username,
- final @FormParam("password") String password,
- final @FormParam("password-confirm") String confirm) {
- if (!password.equals(confirm)) {
- request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Password confirmation doesn't match.");
- request.forward(saasRegisterPath);
- return null;
- }
+ public Response processRegister(final MultivaluedMap<String, String> formData) {
return new Transaction() {
@Override
protected Response callImpl() {
RealmManager realmManager = new RealmManager(session);
RealmModel defaultRealm = realmManager.defaultRealm();
+
+ String error = validateRegistrationForm(formData);
+ if (error != null) {
+ forwardToRegisterForm(defaultRealm, error, formData);
+ return null;
+ }
+
UserRepresentation newUser = new UserRepresentation();
- newUser.setUsername(username);
- newUser.setEmail(email);
+ newUser.setUsername(formData.getFirst("username"));
+ newUser.setEmail(formData.getFirst("email"));
+
+ String fullname = formData.getFirst("name");
if (fullname != null) {
StringTokenizer tokenizer = new StringTokenizer(fullname, " ");
StringBuffer first = null;
@@ -334,11 +370,11 @@ public class SaasService {
newUser.setFirstName(first.toString());
newUser.setLastName(last);
}
- newUser.credential(CredentialRepresentation.PASSWORD, password);
+ newUser.credential(CredentialRepresentation.PASSWORD, formData.getFirst("password"));
UserModel user = registerMe(defaultRealm, newUser);
if (user == null) {
request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Username already exists.");
- request.forward(saasRegisterPath);
+ forwardToRegisterForm(defaultRealm, "Username already exists.", formData);
return null;
}
@@ -376,5 +412,32 @@ public class SaasService {
return user;
}
+ private String validateRegistrationForm(MultivaluedMap<String, String> formData) {
+ if (isEmpty(formData.getFirst("name"))) {
+ return "Please specify full name";
+ }
+
+ if (isEmpty(formData.getFirst("email"))) {
+ return "Please specify email";
+ }
+
+ if (isEmpty(formData.getFirst("username"))) {
+ return "Please specify username";
+ }
+
+ if (isEmpty(formData.getFirst("password"))) {
+ return "Please specify password";
+ }
+
+ if (!formData.getFirst("password").equals(formData.getFirst("password-confirm"))) {
+ return "Password confirmation doesn't match.";
+ }
+
+ return null;
+ }
+
+ private boolean isEmpty(String s) {
+ return s == null || s.length() == 0;
+ }
}
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 8d749a0..a9b1e8f 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -199,7 +199,8 @@ public class TokenService {
UserModel user = realm.getUser(username);
if (user == null) {
logger.error("Incorrect user name.");
- request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
+ request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid username or password");
+ request.setAttribute("KEYCLOAK_FORM_DATA", formData);
OAuthUtil.forwardToLoginForm(realm, request, uriInfo, redirect, clientId, scopeParam, state);
return null;
}
@@ -211,7 +212,8 @@ public class TokenService {
if (!authenticated) {
logger.error("Authentication failed");
request.setAttribute("username", username);
- request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid credentials.");
+ request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid username or password");
+ request.setAttribute("KEYCLOAK_FORM_DATA", formData);
OAuthUtil.forwardToLoginForm(realm, request, uriInfo, redirect, clientId, scopeParam, state);
return null;
}
diff --git a/services/src/main/java/org/keycloak/services/resources/Urls.java b/services/src/main/java/org/keycloak/services/resources/Urls.java
new file mode 100644
index 0000000..7e2b2e8
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/Urls.java
@@ -0,0 +1,45 @@
+package org.keycloak.services.resources;
+
+import java.net.URI;
+
+import javax.ws.rs.core.UriInfo;
+
+public class Urls {
+
+ public static URI realmLoginAction(UriInfo uriInfo, String realmId) {
+ return TokenService.processLoginUrl(uriInfo).build(realmId);
+ }
+
+ public static URI realmLoginPage(UriInfo uriInfo, String realmId) {
+ return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processLogin").build();
+ }
+
+ public static URI realmRegisterAction(UriInfo uriInfo, String realmId) {
+ return URI.create("not-implemented-yet");
+ }
+
+ public static URI realmRegisterPage(UriInfo uriInfo, String realmId) {
+ return URI.create("not-implemented-yet");
+ }
+
+ public static URI saasLoginAction(UriInfo uriInfo) {
+ return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processLogin").build();
+ }
+
+ public static URI saasLoginPage(UriInfo uriInfo) {
+ return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "loginPage").build();
+ }
+
+ public static URI saasRegisterAction(UriInfo uriInfo) {
+ return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "processRegister").build();
+ }
+
+ public static URI saasRegisterPage(UriInfo uriInfo) {
+ return uriInfo.getBaseUriBuilder().path(SaasService.class).path(SaasService.class, "registerPage").build();
+ }
+
+ public static URI socialRedirectToProviderAuth(UriInfo uriInfo, String realmId) {
+ return SocialResource.redirectToProviderAuthUrl(uriInfo).build(realmId);
+ }
+
+}