keycloak-memoizeit
Changes
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/BearerTokenAuthenticatorValve.java 2(+1 -1)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java 9(+6 -3)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java 28(+14 -14)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java 3(+2 -1)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthAuthenticationServerValve.java 6(+3 -3)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthManagedResourceValve.java 88(+62 -26)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java 8(+3 -5)
Details
diff --git a/core/src/main/java/org/keycloak/RealmConfiguration.java b/core/src/main/java/org/keycloak/RealmConfiguration.java
index 8563cdf..5e4a7a4 100755
--- a/core/src/main/java/org/keycloak/RealmConfiguration.java
+++ b/core/src/main/java/org/keycloak/RealmConfiguration.java
@@ -15,8 +15,7 @@ public class RealmConfiguration {
protected ResteasyClient client;
protected UriBuilder authUrl;
protected ResteasyWebTarget codeUrl;
- protected String clientId;
- protected Form credentials = new Form();
+ protected Form resourceCredentials = new Form();
protected boolean sslRequired = true;
protected String stateCookieName = "OAuth_Token_Request_State";
@@ -44,16 +43,8 @@ public class RealmConfiguration {
this.authUrl = authUrl;
}
- public String getClientId() {
- return clientId;
- }
-
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-
- public Form getCredentials() {
- return credentials;
+ public Form getResourceCredentials() {
+ return resourceCredentials;
}
public ResteasyWebTarget getCodeUrl() {
diff --git a/core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java b/core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java
new file mode 100755
index 0000000..0a7f553
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java
@@ -0,0 +1,66 @@
+package org.keycloak.representations.idm.admin;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * Posted to managed client from admin server.
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class AdminAction {
+ protected String id;
+ protected long expiration;
+ protected String resource;
+ protected String action;
+
+ public AdminAction() {
+ }
+
+ public AdminAction(String id, long expiration, String resource, String action) {
+ this.id = id;
+ this.expiration = expiration;
+ this.resource = resource;
+ this.action = action;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ @JsonIgnore
+ public boolean isExpired()
+ {
+ long time = System.currentTimeMillis() / 1000;
+ return time > expiration;
+ }
+
+ public long getExpiration() {
+ return expiration;
+ }
+
+ public void setExpiration(long expiration) {
+ this.expiration = expiration;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/admin/LogoutAction.java b/core/src/main/java/org/keycloak/representations/idm/admin/LogoutAction.java
new file mode 100755
index 0000000..946b7f8
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/admin/LogoutAction.java
@@ -0,0 +1,26 @@
+package org.keycloak.representations.idm.admin;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class LogoutAction extends AdminAction {
+ public static final String LOGOUT_ACTION = "logout";
+ protected String user;
+
+ public LogoutAction() {
+ }
+
+ public LogoutAction(String id, long expiration, String resource, String user) {
+ super(id, expiration, resource, LOGOUT_ACTION);
+ this.user = user;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
new file mode 100755
index 0000000..2259317
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
@@ -0,0 +1,35 @@
+package org.keycloak.representations.idm;
+
+/**
+* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+* @version $Revision: 1 $
+*/
+public class CredentialRepresentation {
+ protected String type;
+ protected String value;
+ protected boolean hashed;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public boolean isHashed() {
+ return hashed;
+ }
+
+ public void setHashed(boolean hashed) {
+ this.hashed = hashed;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java
index 529ed35..15c49f9 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java
@@ -12,7 +12,10 @@ import java.util.Set;
public class ResourceRepresentation {
protected String self; // link
protected String name;
+ protected String adminUrl;
protected boolean surrogateAuthRequired;
+ protected boolean useRealmMappings;
+ protected List<CredentialRepresentation> credentials;
protected Set<String> roles;
protected List<RoleMappingRepresentation> roleMappings;
protected List<ScopeMappingRepresentation> scopeMappings;
@@ -79,5 +82,37 @@ public class ResourceRepresentation {
return mapping;
}
+ public String getAdminUrl() {
+ return adminUrl;
+ }
+
+ public void setAdminUrl(String adminUrl) {
+ this.adminUrl = adminUrl;
+ }
+
+ public List<CredentialRepresentation> getCredentials() {
+ return credentials;
+ }
+
+ public void setCredentials(List<CredentialRepresentation> credentials) {
+ this.credentials = credentials;
+ }
+ public ResourceRepresentation credential(String type, String value, boolean hashed) {
+ if (this.credentials == null) credentials = new ArrayList<CredentialRepresentation>();
+ CredentialRepresentation cred = new CredentialRepresentation();
+ cred.setType(type);
+ cred.setValue(value);
+ cred.setHashed(hashed);
+ credentials.add(cred);
+ return this;
+ }
+
+ public boolean isUseRealmMappings() {
+ return useRealmMappings;
+ }
+
+ public void setUseRealmMappings(boolean useRealmMappings) {
+ this.useRealmMappings = useRealmMappings;
+ }
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
index 96d2b72..cbbff89 100755
--- a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
@@ -10,41 +10,12 @@ import java.util.Map;
* @version $Revision: 1 $
*/
public class UserRepresentation {
- public static class Credential {
- protected String type;
- protected String value;
- protected boolean hashed;
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public boolean isHashed() {
- return hashed;
- }
-
- public void setHashed(boolean hashed) {
- this.hashed = hashed;
- }
- }
protected String self; // link
protected String username;
protected boolean enabled;
protected Map<String, String> attributes;
- protected List<Credential> credentials;
+ protected List<CredentialRepresentation> credentials;
public String getSelf() {
return self;
@@ -70,23 +41,23 @@ public class UserRepresentation {
this.attributes = attributes;
}
- public List<Credential> getCredentials() {
- return credentials;
- }
-
- public void setCredentials(List<Credential> credentials) {
- this.credentials = credentials;
- }
-
public UserRepresentation attribute(String name, String value) {
if (this.attributes == null) attributes = new HashMap<String, String>();
attributes.put(name, value);
return this;
}
+ public List<CredentialRepresentation> getCredentials() {
+ return credentials;
+ }
+
+ public void setCredentials(List<CredentialRepresentation> credentials) {
+ this.credentials = credentials;
+ }
+
public UserRepresentation credential(String type, String value, boolean hashed) {
- if (this.credentials == null) credentials = new ArrayList<Credential>();
- Credential cred = new Credential();
+ if (this.credentials == null) credentials = new ArrayList<CredentialRepresentation>();
+ CredentialRepresentation cred = new CredentialRepresentation();
cred.setType(type);
cred.setValue(value);
cred.setHashed(hashed);
diff --git a/core/src/main/java/org/keycloak/ResourceMetadata.java b/core/src/main/java/org/keycloak/ResourceMetadata.java
index 24a2772..0a3f811 100755
--- a/core/src/main/java/org/keycloak/ResourceMetadata.java
+++ b/core/src/main/java/org/keycloak/ResourceMetadata.java
@@ -8,8 +8,8 @@ import java.security.PublicKey;
* @version $Revision: 1 $
*/
public class ResourceMetadata {
- protected String resourceName;
protected String realm;
+ protected String resourceName;
protected KeyStore clientKeystore;
protected String clientKeyPassword;
protected KeyStore truststore;
diff --git a/core/src/main/java/org/keycloak/TokenIdGenerator.java b/core/src/main/java/org/keycloak/TokenIdGenerator.java
new file mode 100755
index 0000000..f1b5e55
--- /dev/null
+++ b/core/src/main/java/org/keycloak/TokenIdGenerator.java
@@ -0,0 +1,15 @@
+package org.keycloak;
+
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class TokenIdGenerator {
+ private static final AtomicLong counter = new AtomicLong();
+ public static String generateId() {
+ return UUID.randomUUID().toString() + "-" + System.currentTimeMillis();
+ }
+}
diff --git a/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp b/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
old mode 100644
new mode 100755
index f6bd0c5..91657c9
--- a/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
+++ b/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
@@ -1,11 +1,15 @@
-<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>Customer View Page</title>
</head>
<body bgcolor="#E3F6CE">
-<p>Goto: <a href="https://localhost:8443/product-portal">products</a> | <a href="https://localhost:8443/auth-server/j_oauth_logout">logout</a></p>
+<%
+ String logoutUri = UriBuilder.fromUri("http://localhost:8080/auth-server/rest/realms/demo/tokens/logout")
+ .queryParam("redirect_uri", "http://localhost:8080/customer-portal").build().toString();
+%>
+<p>Goto: <a href="http://localhost:8080/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a></p>
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
<h2>Customer Listing</h2>
<%
diff --git a/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json b/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json
index e0df12d..a36b5cf 100755
--- a/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json
+++ b/examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/resteasy-oauth.json
@@ -1,11 +1,11 @@
{
"realm" : "demo",
+ "resource" : "customer-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/login",
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
"ssl-not-required" : true,
- "client-id" : "customer-portal",
- "client-credentials" : {
+ "credentials" : {
"password" : "password"
}
}
diff --git a/examples/as7-eap-demo/database-service/src/main/webapp/WEB-INF/resteasy-oauth.json b/examples/as7-eap-demo/database-service/src/main/webapp/WEB-INF/resteasy-oauth.json
index 156706f..cacacd0 100755
--- a/examples/as7-eap-demo/database-service/src/main/webapp/WEB-INF/resteasy-oauth.json
+++ b/examples/as7-eap-demo/database-service/src/main/webapp/WEB-INF/resteasy-oauth.json
@@ -1,4 +1,5 @@
{
"realm" : "demo",
+ "resource" : "database-service",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB"
}
diff --git a/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp b/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
old mode 100644
new mode 100755
index 5a9a641..fe8d990
--- a/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
+++ b/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
@@ -1,11 +1,16 @@
-<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>Product View Page</title>
</head>
<body bgcolor="#F5F6CE">
-<p>Goto: <a href="https://localhost:8443/customer-portal">customers</a> | <a href="https://localhost:8443/auth-server/j_oauth_logout">logout</a></p>
+<%
+ String logoutUri = UriBuilder.fromUri("http://localhost:8080/auth-server/rest/realms/demo/tokens/logout")
+ .queryParam("redirect_uri", "http://localhost:8080/product-portal").build().toString();
+%>
+
+<p>Goto: <a href="http://localhost:8080/customer-portal">customers</a> | <a href="<%=logoutUri%>">logout</a></p>
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
<h2>Product Listing</h2>
<%
diff --git a/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json b/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json
index 53ad29f..26bc1fe 100755
--- a/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json
+++ b/examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/resteasy-oauth.json
@@ -1,11 +1,11 @@
{
"realm" : "demo",
+ "resource" : "product-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/login",
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
"ssl-not-required" : true,
- "client-id" : "product-portal",
- "client-credentials" : {
+ "credentials" : {
"password" : "password"
}
}
diff --git a/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json b/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json
index 150c218..db10768 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json
+++ b/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json
@@ -25,22 +25,6 @@
{ "type" : "Password",
"value" : "password" }
]
- },
- {
- "username" : "customer-portal",
- "enabled" : true,
- "credentials" : [
- { "type" : "Password",
- "value" : "password" }
- ]
- },
- {
- "username" : "product-portal",
- "enabled" : true,
- "credentials" : [
- { "type" : "Password",
- "value" : "password" }
- ]
}
],
"roleMappings" : [
@@ -49,14 +33,24 @@
"roles" : ["user"]
}
],
- "scopeMappings" : [
+ "resources" : [
{
- "username" : "customer-portal",
- "roles" : ["*"]
+ "name" : "customer-portal",
+ "adminUrl" : "http://localhost:8080/customer-portal/j_admin_request",
+ "useRealmMappings" : true,
+ "credentials" : [
+ { "type" : "Password",
+ "value" : "password" }
+ ]
},
{
- "username" : "product-portal",
- "roles" : ["*"]
+ "name" : "product-portal",
+ "adminUrl" : "http://localhost:8080/product-portal/j_admin_request",
+ "useRealmMappings" : true,
+ "credentials" : [
+ { "type" : "Password",
+ "value" : "password" }
+ ]
}
]
}
\ No newline at end of file
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/BearerTokenAuthenticatorValve.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/BearerTokenAuthenticatorValve.java
index b87ed0b..6ed560c 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/BearerTokenAuthenticatorValve.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/BearerTokenAuthenticatorValve.java
@@ -63,7 +63,7 @@ public class BearerTokenAuthenticatorValve extends AuthenticatorBase implements
@Override
protected boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
try {
- CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, !remoteSkeletonKeyConfig.isCancelPropagation(), true);
+ CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, !remoteSkeletonKeyConfig.isCancelPropagation(), true, remoteSkeletonKeyConfig.isUseResourceRoleMappings());
if (bearer.login(request, response)) {
return true;
}
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
index 835296b..b02cb45 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.security.cert.X509Certificate;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -29,11 +30,13 @@ public class CatalinaBearerTokenAuthenticator {
protected SkeletonKeyToken token;
private Principal principal;
protected boolean propagateToken;
+ protected boolean useResourceRoleMappings;
- public CatalinaBearerTokenAuthenticator(ResourceMetadata resourceMetadata, boolean propagateToken, boolean challenge) {
+ public CatalinaBearerTokenAuthenticator(ResourceMetadata resourceMetadata, boolean propagateToken, boolean challenge, boolean useResourceRoleMappings) {
this.resourceMetadata = resourceMetadata;
this.challenge = challenge;
this.propagateToken = propagateToken;
+ this.useResourceRoleMappings = useResourceRoleMappings;
}
public ResourceMetadata getResourceMetadata() {
@@ -77,8 +80,8 @@ public class CatalinaBearerTokenAuthenticator {
challengeResponse(response, "invalid_token", e.getMessage());
}
boolean verifyCaller = false;
- Set<String> roles = null;
- if (resourceMetadata.getResourceName() != null) {
+ Set<String> roles = new HashSet<String>();
+ if (useResourceRoleMappings) {
SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName());
if (access != null) roles = access.getRoles();
verifyCaller = token.isVerifyCaller(resourceMetadata.getResourceName());
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java
index 756950c..00da369 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java
@@ -26,6 +26,8 @@ public class ManagedResourceConfig {
protected String authUrl;
@JsonProperty("code-url")
protected String codeUrl;
+ @JsonProperty("use-resource-role-mappings")
+ protected boolean useResourceRoleMappings;
@JsonProperty("ssl-not-required")
protected boolean sslNotRequired;
@@ -37,21 +39,27 @@ public class ManagedResourceConfig {
protected String truststore;
@JsonProperty("truststore-password")
protected String truststorePassword;
- @JsonProperty("client-id")
- protected String clientId;
@JsonProperty("client-keystore")
protected String clientKeystore;
@JsonProperty("client-keystore-password")
protected String clientKeystorePassword;
@JsonProperty("client-key-password")
protected String clientKeyPassword;
- @JsonProperty("client-credentials")
- protected Map<String, String> clientCredentials = new HashMap<String, String>();
+ @JsonProperty("credentials")
+ protected Map<String, String> credentials = new HashMap<String, String>();
@JsonProperty("connection-pool-size")
protected int connectionPoolSize;
@JsonProperty("cancel-propagation")
protected boolean cancelPropagation;
+ public boolean isUseResourceRoleMappings() {
+ return useResourceRoleMappings;
+ }
+
+ public void setUseResourceRoleMappings(boolean useResourceRoleMappings) {
+ this.useResourceRoleMappings = useResourceRoleMappings;
+ }
+
public boolean isSslNotRequired() {
return sslNotRequired;
}
@@ -140,16 +148,8 @@ public class ManagedResourceConfig {
this.truststorePassword = truststorePassword;
}
- public String getClientId() {
- return clientId;
- }
-
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-
- public Map<String, String> getClientCredentials() {
- return clientCredentials;
+ public Map<String, String> getCredentials() {
+ return credentials;
}
public String getClientKeystore() {
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java
index e55c3c7..cc6a2d6 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java
@@ -103,8 +103,9 @@ public class ManagedResourceConfigLoader {
}
String realm = remoteSkeletonKeyConfig.getRealm();
- String resource = remoteSkeletonKeyConfig.getResource();
if (realm == null) throw new RuntimeException("Must set 'realm' in config");
+ String resource = remoteSkeletonKeyConfig.getResource();
+ if (resource == null) throw new RuntimeException("Must set 'resource' in config");
String realmKeyPem = remoteSkeletonKeyConfig.getRealmKey();
if (realmKeyPem == null) {
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthAuthenticationServerValve.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthAuthenticationServerValve.java
index 1b04c9a..66621df 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthAuthenticationServerValve.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthAuthenticationServerValve.java
@@ -527,8 +527,8 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
html.append("<br>");
writer = new StringWriter();
- rep.getClientCredentials().put("password", "REQUIRED");
- rep.setClientId("REQUIRED");
+ rep.getCredentials().put("password", "REQUIRED");
+ //rep.setClientId("REQUIRED");
rep.setTruststore("REQUIRED");
rep.setTruststorePassword("REQUIRED");
mapper.writeValue(writer, rep);
@@ -561,7 +561,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
public boolean bearer(Request request, HttpServletResponse response, boolean propagate) throws IOException {
if (request.getHeader("Authorization") != null) {
- CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, true, false);
+ CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, true, false, false);
try {
if (bearer.login(request, response)) {
return true;
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthManagedResourceValve.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthManagedResourceValve.java
index 6c1385c..3614d58 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthManagedResourceValve.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthManagedResourceValve.java
@@ -14,8 +14,9 @@ import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.realm.GenericPrincipal;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
-import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
-import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
+import org.jboss.resteasy.jose.jws.JWSInput;
+import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
+import org.jboss.resteasy.jwt.JsonSerialization;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.RealmConfiguration;
import org.keycloak.ResourceMetadata;
@@ -24,12 +25,14 @@ import org.keycloak.SkeletonKeySession;
import org.keycloak.adapters.as7.config.ManagedResourceConfig;
import org.keycloak.adapters.as7.config.ManagedResourceConfigLoader;
import org.keycloak.representations.SkeletonKeyToken;
+import org.keycloak.representations.idm.admin.LogoutAction;
import javax.security.auth.login.LoginException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -67,10 +70,6 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
managedResourceConfigLoader.init(true);
resourceMetadata = managedResourceConfigLoader.getResourceMetadata();
remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig();
- String client_id = remoteSkeletonKeyConfig.getClientId();
- if (client_id == null) {
- throw new IllegalArgumentException("Must set client-id to use with auth server");
- }
realmConfiguration = new RealmConfiguration();
String authUrl = remoteSkeletonKeyConfig.getAuthUrl();
if (authUrl == null) {
@@ -81,17 +80,16 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
throw new RuntimeException("You mut specify code-url");
}
realmConfiguration.setMetadata(resourceMetadata);
- realmConfiguration.setClientId(client_id);
realmConfiguration.setSslRequired(!remoteSkeletonKeyConfig.isSslNotRequired());
- for (Map.Entry<String, String> entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getClientCredentials().entrySet()) {
- realmConfiguration.getCredentials().param(entry.getKey(), entry.getValue());
+ for (Map.Entry<String, String> entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getCredentials().entrySet()) {
+ realmConfiguration.getResourceCredentials().param(entry.getKey(), entry.getValue());
}
ResteasyClient client = managedResourceConfigLoader.getClient();
realmConfiguration.setClient(client);
- realmConfiguration.setAuthUrl(UriBuilder.fromUri(authUrl).queryParam("client_id", client_id));
+ realmConfiguration.setAuthUrl(UriBuilder.fromUri(authUrl).queryParam("client_id", resourceMetadata.getResourceName()));
realmConfiguration.setCodeUrl(client.target(tokenUrl));
}
@@ -99,8 +97,8 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
public void invoke(Request request, Response response) throws IOException, ServletException {
try {
String requestURI = request.getDecodedRequestURI();
- if (requestURI.endsWith("j_oauth_remote_logout")) {
- remoteLogout(request, response);
+ if (requestURI.endsWith("j_admin_request")) {
+ adminRequest(request, response);
return;
}
super.invoke(request, response);
@@ -135,33 +133,71 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
return false;
}
- protected void remoteLogout(Request request, HttpServletResponse response) throws IOException {
+ protected void adminRequest(Request request, HttpServletResponse response) throws IOException {
+ String token = request.getParameter("token");
+ if (token == null) {
+ log.warn("admin request failed, no token");
+ response.sendError(403, "no token");
+ return;
+ }
+
+ JWSInput input = new JWSInput(token);
+ boolean verified = false;
+ try {
+ verified = RSAProvider.verify(input, resourceMetadata.getRealmKey());
+ } catch (Exception ignore) {
+ }
+ if (!verified) {
+ log.warn("admin request failed, unable to verify token");
+ response.sendError(403, "verification failed");
+ return;
+ }
+ String action = request.getParameter("action");
+ if (LogoutAction.LOGOUT_ACTION.equals(action)) {
+ remoteLogout(input, response);
+ } else {
+ log.warn("admin request failed, unknown action");
+ response.sendError(403, "Unknown action");
+ }
+ }
+
+ protected void remoteLogout(JWSInput token, HttpServletResponse response) throws IOException {
try {
log.debug("->> remoteLogout: ");
- if (!bearer(true, request, response)) {
- log.debug("remoteLogout: bearer auth failed");
+ LogoutAction action = JsonSerialization.fromBytes(LogoutAction.class, token.getContent());
+ if (action.isExpired()) {
+ log.warn("admin request failed, expired token");
+ response.sendError(400, "Expired token");
return;
}
- GenericPrincipal gp = (GenericPrincipal) request.getPrincipal();
- if (!gp.hasRole(remoteSkeletonKeyConfig.getAdminRole())) {
- log.debug("remoteLogout: role failure");
- response.sendError(403);
+ if (!LogoutAction.LOGOUT_ACTION.equals(action.getAction())) {
+ log.warn("Action doesn't match");
+ response.sendError(400, "Action does not match");
return;
}
- String user = request.getParameter("user");
+ if (!resourceMetadata.getResourceName().equals(action.getResource())) {
+ log.warn("Resource name does not match");
+ response.sendError(400, "Resource name does not match");
+ return;
+
+ }
+ String user = action.getUser();
if (user != null) {
+ log.info("logout of session for: " + user);
userSessionManagement.logout(user);
} else {
+ log.info("logout of all sessions");
userSessionManagement.logoutAll();
}
} catch (Exception e) {
- log.error("failed to logout", e);
+ log.warn("failed to logout", e);
+ response.sendError(500, "Failed to logout");
}
response.setStatus(204);
}
protected boolean bearer(boolean challenge, Request request, HttpServletResponse response) throws LoginException, IOException {
- CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(realmConfiguration.getMetadata(), !remoteSkeletonKeyConfig.isCancelPropagation(), challenge);
+ CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(realmConfiguration.getMetadata(), !remoteSkeletonKeyConfig.isCancelPropagation(), challenge, remoteSkeletonKeyConfig.isUseResourceRoleMappings());
if (bearer.login(request, response)) {
return true;
}
@@ -207,13 +243,13 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
if (!oauth.resolveCode(code)) return;
SkeletonKeyToken token = oauth.getToken();
- Set<String> roles = null;
- if (resourceMetadata.getResourceName() != null) {
+ Set<String> roles = new HashSet<String>();
+ if (remoteSkeletonKeyConfig.isUseResourceRoleMappings()) {
SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName());
- if (access != null) roles = access.getRoles();
+ if (access != null) roles.addAll(access.getRoles());
} else {
SkeletonKeyToken.Access access = token.getRealmAccess();
- if (access != null) roles = access.getRoles();
+ if (access != null) roles.addAll(access.getRoles());
}
SkeletonKeyPrincipal skp = new SkeletonKeyPrincipal(token.getPrincipal(), null);
GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(context.getRealm(), skp, roles);
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
index 8e177a8..b3cdebb 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
@@ -1,7 +1,6 @@
package org.keycloak.adapters.as7;
import org.jboss.logging.Logger;
-import org.jboss.resteasy.util.BasicAuthHelper;
import org.keycloak.RSATokenVerifier;
import org.keycloak.RealmConfiguration;
import org.keycloak.VerificationException;
@@ -14,7 +13,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
-import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
@@ -144,7 +142,7 @@ public class ServletOAuthLogin {
url = secureUrl.build().toString();
}
return realmInfo.getAuthUrl().clone()
- .queryParam("client_id", realmInfo.getClientId())
+ .queryParam("client_id", realmInfo.getMetadata().getResourceName())
.queryParam("redirect_uri", url)
.queryParam("state", state)
.queryParam("login", "true")
@@ -223,8 +221,8 @@ public class ServletOAuthLogin {
if (!checkStateCookie()) return false;
- String client_id = realmInfo.getClientId();
- String password = realmInfo.getCredentials().asMap().getFirst("password");
+ String client_id = realmInfo.getMetadata().getResourceName();
+ String password = realmInfo.getResourceCredentials().asMap().getFirst("password");
//String authHeader = BasicAuthHelper.createHeader(client_id, password);
String redirectUri = stripOauthParametersFromRedirect();
Form form = new Form();
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 fc62795..00c8bd2 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -9,6 +9,7 @@ import org.keycloak.representations.SkeletonKeyToken;
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.RequiredCredentialModel;
+import org.keycloak.services.resources.RealmsResource;
import org.picketlink.idm.credential.Credentials;
import org.picketlink.idm.credential.Password;
import org.picketlink.idm.credential.TOTPCredentials;
@@ -20,6 +21,8 @@ import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.NewCookie;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
import java.util.HashSet;
import java.util.Set;
@@ -45,14 +48,19 @@ public class AuthenticationManager {
return realm.isRealmAdmin(user);
}
- protected void expireIdentityCookie(Cookie cookie) {
+ public void expireIdentityCookie(RealmModel realm, UriInfo uriInfo) {
+ URI uri = RealmsResource.realmBaseUrl(uriInfo).build(realm.getId());
HttpResponse response = ResteasyProviderFactory.getContextData(HttpResponse.class);
- if (response == null) return;
- NewCookie expireIt = new NewCookie(cookie.getName(), "", cookie.getPath(), null, "Expiring cookie", 0, false);
+ if (response == null) {
+ logger.info("can't expire identity cookie, no HttpResponse");
+ return;
+ }
+ logger.info("Expiring identity cookie");
+ NewCookie expireIt = new NewCookie(TokenManager.KEYCLOAK_IDENTITY_COOKIE, "", uri.getPath(), null, "Expiring cookie", 0, false);
response.addNewCookie(expireIt);
}
- public User authenticateIdentityCookie(RealmModel realm, HttpHeaders headers) {
+ public User authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
Cookie cookie = headers.getCookies().get(TokenManager.KEYCLOAK_IDENTITY_COOKIE);
if (cookie == null) return null;
@@ -61,19 +69,19 @@ public class AuthenticationManager {
SkeletonKeyToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getId());
if (!token.isActive()) {
logger.info("identity cookie expired");
- expireIdentityCookie(cookie);
+ expireIdentityCookie(realm, uriInfo);
return null;
}
User user = realm.getIdm().getUser(token.getPrincipal());
if (user == null || !user.isEnabled()) {
logger.info("Unknown user in identity cookie");
- expireIdentityCookie(cookie);
+ expireIdentityCookie(realm, uriInfo);
return null;
}
return user;
} catch (VerificationException e) {
logger.info("Failed to verify identity cookie", e);
- expireIdentityCookie(cookie);
+ expireIdentityCookie(realm, uriInfo);
}
return null;
}
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 18a10e3..080e688 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -1,17 +1,16 @@
package org.keycloak.services.managers;
+import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
import org.keycloak.representations.idm.ResourceRepresentation;
import org.keycloak.representations.idm.RoleMappingRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.RequiredCredentialModel;
import org.keycloak.services.models.ResourceModel;
import org.keycloak.services.models.UserCredentialModel;
-import org.keycloak.services.resources.RegistrationService;
import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.IdentitySession;
import org.picketlink.idm.model.Attribute;
@@ -22,7 +21,6 @@ import org.picketlink.idm.model.SimpleRole;
import org.picketlink.idm.model.SimpleUser;
import org.picketlink.idm.model.User;
-import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.security.KeyPair;
@@ -73,6 +71,7 @@ public class RealmManager {
SimpleAgent agent = new SimpleAgent(RealmModel.REALM_AGENT_ID);
idm.add(agent);
RealmModel realm = new RealmModel(newRealm, identitySession);
+ idm.add(new SimpleRole("*"));
return realm;
}
@@ -135,7 +134,7 @@ public class RealmManager {
}
newRealm.getIdm().add(user);
if (userRep.getCredentials() != null) {
- for (UserRepresentation.Credential cred : userRep.getCredentials()) {
+ for (CredentialRepresentation cred : userRep.getCredentials()) {
UserCredentialModel credential = new UserCredentialModel();
credential.setType(cred.getType());
credential.setValue(cred.getValue());
@@ -145,25 +144,25 @@ public class RealmManager {
userMap.put(user.getLoginName(), user);
}
- Map<String, Role> roles = new HashMap<String, Role>();
-
if (rep.getRoles() != null) {
for (String roleString : rep.getRoles()) {
SimpleRole role = new SimpleRole(roleString.trim());
newRealm.getIdm().add(role);
- roles.put(role.getName(), role);
}
}
+ if (rep.getResources() != null) {
+ createResources(rep, newRealm, userMap);
+ }
+
if (rep.getRoleMappings() != null) {
for (RoleMappingRepresentation mapping : rep.getRoleMappings()) {
User user = userMap.get(mapping.getUsername());
for (String roleString : mapping.getRoles()) {
- Role role = roles.get(roleString.trim());
+ Role role = newRealm.getIdm().getRole(roleString.trim());
if (role == null) {
role = new SimpleRole(roleString.trim());
newRealm.getIdm().add(role);
- roles.put(role.getName(), role);
}
newRealm.getIdm().grantRole(user, role);
}
@@ -173,11 +172,10 @@ public class RealmManager {
if (rep.getScopeMappings() != null) {
for (ScopeMappingRepresentation scope : rep.getScopeMappings()) {
for (String roleString : scope.getRoles()) {
- Role role = roles.get(roleString.trim());
+ Role role = newRealm.getIdm().getRole(roleString.trim());
if (role == null) {
role = new SimpleRole(roleString.trim());
newRealm.getIdm().add(role);
- roles.put(role.getName(), role);
}
User user = userMap.get(scope.getUsername());
newRealm.addScope(user, role.getName());
@@ -185,43 +183,43 @@ public class RealmManager {
}
}
-
- if (!roles.containsKey("*")) {
- SimpleRole wildcard = new SimpleRole("*");
- newRealm.getIdm().add(wildcard);
- roles.put("*", wildcard);
- }
-
- if (rep.getResources() != null) {
- createResources(rep, newRealm, userMap);
- }
}
protected void createResources(RealmRepresentation rep, RealmModel realm, Map<String, User> userMap) {
for (ResourceRepresentation resourceRep : rep.getResources()) {
ResourceModel resource = realm.addResource(resourceRep.getName());
+ resource.setManagementUrl(resourceRep.getAdminUrl());
resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
resource.updateResource();
- Map<String, Role> roles = new HashMap<String, Role>();
+
+ User resourceUser = resource.getResourceUser();
+ if (resourceRep.getCredentials() != null) {
+ for (CredentialRepresentation cred : resourceRep.getCredentials()) {
+ UserCredentialModel credential = new UserCredentialModel();
+ credential.setType(cred.getType());
+ credential.setValue(cred.getValue());
+ realm.updateCredential(resourceUser, credential);
+ }
+ }
+ userMap.put(resourceUser.getLoginName(), resourceUser);
+
+
if (resourceRep.getRoles() != null) {
for (String roleString : resourceRep.getRoles()) {
SimpleRole role = new SimpleRole(roleString.trim());
resource.getIdm().add(role);
- roles.put(role.getName(), role);
}
}
if (resourceRep.getRoleMappings() != null) {
for (RoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
User user = userMap.get(mapping.getUsername());
for (String roleString : mapping.getRoles()) {
- Role role = roles.get(roleString.trim());
+ Role role = resource.getIdm().getRole(roleString.trim());
if (role == null) {
role = new SimpleRole(roleString.trim());
resource.getIdm().add(role);
- roles.put(role.getName(), role);
}
- Role role1 = resource.getIdm().getRole(role.getName());
- realm.getIdm().grantRole(user, role1);
+ realm.getIdm().grantRole(user, role);
}
}
}
@@ -229,22 +227,16 @@ public class RealmManager {
for (ScopeMappingRepresentation mapping : resourceRep.getScopeMappings()) {
User user = userMap.get(mapping.getUsername());
for (String roleString : mapping.getRoles()) {
- Role role = roles.get(roleString.trim());
+ Role role = resource.getIdm().getRole(roleString.trim());
if (role == null) {
role = new SimpleRole(roleString.trim());
resource.getIdm().add(role);
- roles.put(role.getName(), role);
}
resource.addScope(user, role.getName());
}
}
}
- if (!roles.containsKey("*")) {
- SimpleRole wildcard = new SimpleRole("*");
- resource.getIdm().add(wildcard);
- roles.put("*", wildcard);
- }
-
+ if (resourceRep.isUseRealmMappings()) realm.addScope(resource.getResourceUser(), "*");
}
}
@@ -266,7 +258,7 @@ public class RealmManager {
boolean hasBrowserCredentials = true;
for (RequiredCredentialRepresentation credential : rep.getRequiredCredentials()) {
boolean hasCredential = false;
- for (UserRepresentation.Credential cred : userRep.getCredentials()) {
+ for (CredentialRepresentation cred : userRep.getCredentials()) {
if (cred.getType().equals(credential.getType())) {
hasCredential = true;
break;
diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
new file mode 100755
index 0000000..fd2fe2a
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
@@ -0,0 +1,47 @@
+package org.keycloak.services.managers;
+
+import org.jboss.resteasy.client.jaxrs.ResteasyClient;
+import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.keycloak.TokenIdGenerator;
+import org.keycloak.representations.idm.admin.LogoutAction;
+import org.keycloak.services.models.RealmModel;
+import org.keycloak.services.models.ResourceModel;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ResourceAdminManager {
+
+ public void logoutAll(RealmModel realm) {
+ singleLogOut(realm, null);
+ }
+
+ public void singleLogOut(RealmModel realm, String user) {
+ ResteasyClient client = new ResteasyClientBuilder()
+ .disableTrustManager() // todo fix this, should have a trust manager or a good default
+ .build();
+
+ List<ResourceModel> resources = realm.getResources();
+ for (ResourceModel resource : resources) {
+ logoutResource(realm, resource, user, client);
+ }
+ }
+
+ protected boolean logoutResource(RealmModel realm, ResourceModel resource, String user, ResteasyClient client) {
+ LogoutAction adminAction = new LogoutAction(TokenIdGenerator.generateId(), System.currentTimeMillis() / 1000 + 30, resource.getName(), user);
+ String token = new TokenManager().encodeToken(realm, adminAction);
+ Form form = new Form();
+ form.param("token", token);
+ Response response = client.target(resource.getManagementUrl()).queryParam("action", "logout").request().post(Entity.form(form));
+ boolean success = response.getStatus() == 204;
+ response.close();
+ return success;
+ }
+
+}
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 6e7f287..68ef550 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -3,15 +3,17 @@ 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.spi.HttpResponse;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.representations.SkeletonKeyScope;
import org.keycloak.representations.SkeletonKeyToken;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.ResourceModel;
import org.keycloak.services.resources.RealmsResource;
-import org.keycloak.services.resources.TokenService;
import org.picketlink.idm.model.User;
import javax.ws.rs.ForbiddenException;
+import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
@@ -38,6 +40,7 @@ public class TokenManager {
accessCodeMap.clear();
}
+
public AccessCodeEntry pullAccessCode(String key) {
return accessCodeMap.remove(key);
}
@@ -55,7 +58,7 @@ public class TokenManager {
{
SkeletonKeyToken token = null;
if (scopeParam != null) token = createScopedToken(scopeParam, realm, client, user);
- else token = createLoginToken(realm, client, user);
+ else token = createUnscopedToken(realm, client, user);
AccessCodeEntry code = new AccessCodeEntry();
code.setExpiration((System.currentTimeMillis() / 1000) + realm.getAccessCodeLifespan());
@@ -72,15 +75,7 @@ public class TokenManager {
}
public SkeletonKeyToken createScopedToken(SkeletonKeyScope scope, RealmModel realm, User client, User user) {
- SkeletonKeyToken token = new SkeletonKeyToken();
- token.id(RealmManager.generateId());
- token.principal(user.getLoginName());
- token.audience(realm.getName());
- token.issuedNow();
- token.issuedFor(client.getLoginName());
- if (realm.getTokenLifespan() > 0) {
- token.expiration((System.currentTimeMillis() / 1000) + realm.getTokenLifespan());
- }
+ SkeletonKeyToken token = initToken(realm, client, user);
Map<String, ResourceModel> resourceMap = realm.getResourceMap();
for (String res : scope.keySet()) {
@@ -102,23 +97,53 @@ public class TokenManager {
return token;
}
+ protected SkeletonKeyToken initToken(RealmModel realm, User client, User user) {
+ SkeletonKeyToken token = new SkeletonKeyToken();
+ token.id(RealmManager.generateId());
+ token.principal(user.getLoginName());
+ token.audience(realm.getName());
+ token.issuedNow();
+ token.issuedFor(client.getLoginName());
+ if (realm.getTokenLifespan() > 0) {
+ token.expiration((System.currentTimeMillis() / 1000) + realm.getTokenLifespan());
+ }
+ return token;
+ }
+
public SkeletonKeyToken createScopedToken(String scopeParam, RealmModel realm, User client, User user) {
SkeletonKeyScope scope = decodeScope(scopeParam);
return createScopedToken(scope, realm, client, user);
}
- public SkeletonKeyToken createLoginToken(RealmModel realm, User client, User user) {
- Set<String> mapping = realm.getScopes(client);
- if (!mapping.contains("*")) {
- throw new ForbiddenException(Response.status(403).entity("<h1>Security Alert</h1><p>Known client not authorized to request a user login.</p>").type("text/html").build());
+ public SkeletonKeyToken createUnscopedToken(RealmModel realm, User client, User user) {
+
+ SkeletonKeyToken token = initToken(realm, client, user);
+
+ Set<String> realmMapping = realm.getRoleMappings(user);
+
+ if (realmMapping != null && realmMapping.size() > 0) {
+ Set<String> scope = realm.getScope(client);
+ SkeletonKeyToken.Access access = new SkeletonKeyToken.Access();
+ for (String role : realmMapping) {
+ if (scope.contains("*") || scope.contains(role)) access.addRole(role);
+ }
+ token.setRealmAccess(access);
+ }
+ List<ResourceModel> resources = realm.getResources();
+ for (ResourceModel resource : resources) {
+ Set<String> scope = resource.getScope(client);
+ Set<String> mapping = resource.getRoleMappings(user);
+ if (mapping.size() == 0 || scope.size() == 0) continue;
+ SkeletonKeyToken.Access access = token.addAccess(resource.getName())
+ .verifyCaller(resource.isSurrogateAuthRequired());
+ for (String role : mapping) {
+ if (scope.contains("*") || scope.contains(role)) access.addRole(role);
+ }
}
- SkeletonKeyToken token = createAccessToken(realm, user);
- token.issuedFor(client.getLoginName());
return token;
}
-
public String encodeScope(SkeletonKeyScope scope) {
String token = null;
try {
@@ -187,7 +212,7 @@ public class TokenManager {
return token;
}
- public String encodeToken(RealmModel realm, SkeletonKeyToken token) {
+ public String encodeToken(RealmModel realm, Object token) {
byte[] tokenBytes = null;
try {
tokenBytes = JsonSerialization.toByteArray(token, false);
diff --git a/services/src/main/java/org/keycloak/services/models/RealmModel.java b/services/src/main/java/org/keycloak/services/models/RealmModel.java
index 76f5d4d..6ab850a 100755
--- a/services/src/main/java/org/keycloak/services/models/RealmModel.java
+++ b/services/src/main/java/org/keycloak/services/models/RealmModel.java
@@ -18,6 +18,8 @@ import org.picketlink.idm.model.Attribute;
import org.picketlink.idm.model.Grant;
import org.picketlink.idm.model.Realm;
import org.picketlink.idm.model.Role;
+import org.picketlink.idm.model.SimpleRole;
+import org.picketlink.idm.model.SimpleUser;
import org.picketlink.idm.model.Tier;
import org.picketlink.idm.model.User;
import org.picketlink.idm.query.IdentityQuery;
@@ -293,8 +295,15 @@ public class RealmModel {
relationship.setResourceName(name);
relationship.setRealmAgent(realmAgent);
relationship.setResourceId(newTier.getId());
+ relationship.setManagementUrl(""); // Picketlink doesn't like null attribute values
+ User resourceUser = new SimpleUser(name);
+ idm.add(resourceUser);
+ relationship.setResourceUser(resourceUser);
idm.add(relationship);
- return new ResourceModel(newTier, relationship, this, identitySession);
+ ResourceModel resource = new ResourceModel(newTier, relationship, this, identitySession);
+ resource.getIdm().add(new SimpleRole("*"));
+ resource.addScope(resourceUser, "*");
+ return resource;
}
public Set<String> getRoleMappings(User user) {
@@ -320,7 +329,7 @@ public class RealmModel {
}
- public Set<String> getScopes(Agent agent) {
+ public Set<String> getScope(Agent agent) {
RelationshipQuery<ScopeRelationship> query = getIdm().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, agent);
List<ScopeRelationship> scope = query.getResultList();
diff --git a/services/src/main/java/org/keycloak/services/models/relationships/ResourceRelationship.java b/services/src/main/java/org/keycloak/services/models/relationships/ResourceRelationship.java
index 10d1030..f63e76a 100755
--- a/services/src/main/java/org/keycloak/services/models/relationships/ResourceRelationship.java
+++ b/services/src/main/java/org/keycloak/services/models/relationships/ResourceRelationship.java
@@ -3,6 +3,7 @@ package org.keycloak.services.models.relationships;
import org.picketlink.idm.model.AbstractAttributedType;
import org.picketlink.idm.model.Agent;
import org.picketlink.idm.model.Relationship;
+import org.picketlink.idm.model.User;
import org.picketlink.idm.model.annotation.AttributeProperty;
import org.picketlink.idm.model.annotation.IdentityProperty;
import org.picketlink.idm.query.RelationshipQueryParameter;
@@ -23,8 +24,10 @@ public class ResourceRelationship extends AbstractAttributedType implements Rela
};
protected Agent realmAgent;
+ protected User resourceUser;
protected String resourceId;
protected String resourceName;
+ protected String managementUrl = ""; // Picketlink doesn't like null attribute values
protected boolean surrogateAuthRequired;
protected boolean enabled;
@@ -37,6 +40,15 @@ public class ResourceRelationship extends AbstractAttributedType implements Rela
this.realmAgent = realmAgent;
}
+ @IdentityProperty
+ public User getResourceUser() {
+ return resourceUser;
+ }
+
+ public void setResourceUser(User resourceUser) {
+ this.resourceUser = resourceUser;
+ }
+
@AttributeProperty
public String getResourceId() {
return resourceId;
@@ -72,4 +84,15 @@ public class ResourceRelationship extends AbstractAttributedType implements Rela
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
+
+ @AttributeProperty
+ public String getManagementUrl()
+ {
+ return managementUrl;
+ }
+
+ public void setManagementUrl(String managementUrl) {
+ if (managementUrl == null) managementUrl = ""; // Picketlink doesn't like NULL attribute values.
+ this.managementUrl = managementUrl;
+ }
}
diff --git a/services/src/main/java/org/keycloak/services/models/ResourceModel.java b/services/src/main/java/org/keycloak/services/models/ResourceModel.java
index bad532c..c47785b 100755
--- a/services/src/main/java/org/keycloak/services/models/ResourceModel.java
+++ b/services/src/main/java/org/keycloak/services/models/ResourceModel.java
@@ -41,6 +41,10 @@ public class ResourceModel {
getIdm().update(agent);
}
+ public User getResourceUser() {
+ return agent.getResourceUser();
+ }
+
public String getId() {
return tier.getId();
}
@@ -69,6 +73,14 @@ public class ResourceModel {
agent.setSurrogateAuthRequired(surrogateAuthRequired);
}
+ public String getManagementUrl() {
+ return agent.getManagementUrl();
+ }
+
+ public void setManagementUrl(String url) {
+ agent.setManagementUrl(url);
+ }
+
public List<Role> getRoles() {
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
query.setParameter(Role.PARTITION, tier);
@@ -90,10 +102,14 @@ public class ResourceModel {
IdentityManager idm = getIdm();
Role role = idm.getRole(roleName);
if (role == null) throw new RuntimeException("role not found");
+ addScope(agent, role);
+
+ }
+
+ public void addScope(Agent agent, Role role) {
ScopeRelationship scope = new ScopeRelationship();
scope.setClient(agent);
scope.setScope(role);
-
}
public Set<String> getScope(Agent agent) {
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java b/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java
index 7d2ab1f..4221f12 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java
@@ -52,9 +52,9 @@ public class RealmSubResource {
StringBuffer html = new StringBuffer();
String authUri = TokenService.loginPageUrl(uriInfo).build(realm.getId()).toString();
- String codeUri = TokenService.accessCodeRequest(uriInfo).build(realm.getId()).toString();
- String grantUrl = TokenService.grantRequest(uriInfo).build(realm.getId()).toString();
- String idGrantUrl = TokenService.identityGrantRequest(uriInfo).build(realm.getId()).toString();
+ String codeUri = TokenService.accessCodeToTokenUrl(uriInfo).build(realm.getId()).toString();
+ String grantUrl = TokenService.grantAccessTokenUrl(uriInfo).build(realm.getId()).toString();
+ String idGrantUrl = TokenService.grantIdentityTokenUrl(uriInfo).build(realm.getId()).toString();
html.append("<html><body><h1>Realm: ").append(realm.getName()).append("</h1>");
html.append("<p>auth: ").append(authUri).append("</p>");
@@ -76,9 +76,9 @@ public class RealmSubResource {
rep.setAdminRole(ADMIN_ROLE);
rep.setAuthorizationUrl(TokenService.loginPageUrl(uriInfo).build(realm.getId()).toString());
- rep.setCodeUrl(TokenService.accessCodeRequest(uriInfo).build(realm.getId()).toString());
- rep.setGrantUrl(TokenService.grantRequest(uriInfo).build(realm.getId()).toString());
- String idGrantUrl = TokenService.identityGrantRequest(uriInfo).build(realm.getId()).toString();
+ rep.setCodeUrl(TokenService.accessCodeToTokenUrl(uriInfo).build(realm.getId()).toString());
+ rep.setGrantUrl(TokenService.grantAccessTokenUrl(uriInfo).build(realm.getId()).toString());
+ String idGrantUrl = TokenService.grantIdentityTokenUrl(uriInfo).build(realm.getId()).toString();
rep.setIdentityGrantUrl(idGrantUrl);
return rep;
}
diff --git a/services/src/main/java/org/keycloak/services/resources/RegistrationService.java b/services/src/main/java/org/keycloak/services/resources/RegistrationService.java
index 2dfda68..7bd38fe 100755
--- a/services/src/main/java/org/keycloak/services/resources/RegistrationService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RegistrationService.java
@@ -1,6 +1,7 @@
package org.keycloak.services.resources;
import org.jboss.resteasy.logging.Logger;
+import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.models.RealmModel;
@@ -12,10 +13,8 @@ import org.picketlink.idm.model.User;
import javax.ws.rs.Consumes;
import javax.ws.rs.ForbiddenException;
-import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -57,7 +56,7 @@ public class RegistrationService {
user = new SimpleUser(newUser.getUsername());
defaultRealm.getIdm().add(user);
- for (UserRepresentation.Credential cred : newUser.getCredentials()) {
+ for (CredentialRepresentation cred : newUser.getCredentials()) {
UserCredentialModel credModel = new UserCredentialModel();
credModel.setType(cred.getType());
credModel.setValue(cred.getValue());
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 0f10ec8..eaaaf74 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -13,6 +13,7 @@ import org.keycloak.representations.SkeletonKeyToken;
import org.keycloak.services.JspRequestParameters;
import org.keycloak.services.managers.AccessCodeEntry;
import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.RequiredCredentialModel;
@@ -31,7 +32,6 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriBuilder;
@@ -51,7 +51,6 @@ public class TokenService {
protected static final Logger logger = Logger.getLogger(TokenService.class);
- //protected Map<String, AccessCodeEntry> accessCodeMap;
@Context
protected UriInfo uriInfo;
@@ -73,39 +72,40 @@ public class TokenService {
protected RealmModel realm;
protected TokenManager tokenManager;
protected AuthenticationManager authManager = new AuthenticationManager();
+ private ResourceAdminManager resourceAdminManager = new ResourceAdminManager();
public TokenService(RealmModel realm, TokenManager tokenManager) {
this.realm = realm;
this.tokenManager = tokenManager;
}
- public static UriBuilder tokenServiceBase(UriInfo uriInfo) {
+ public static UriBuilder tokenServiceBaseUrl(UriInfo uriInfo) {
UriBuilder base = uriInfo.getBaseUriBuilder()
.path(RealmsResource.class).path(RealmsResource.class, "getTokenService");
return base;
}
- public static UriBuilder accessCodeRequest(UriInfo uriInfo) {
- return tokenServiceBase(uriInfo).path(TokenService.class, "accessRequest");
+ public static UriBuilder accessCodeToTokenUrl(UriInfo uriInfo) {
+ return tokenServiceBaseUrl(uriInfo).path(TokenService.class, "accessCodeToToken");
}
- public static UriBuilder grantRequest(UriInfo uriInfo) {
- return tokenServiceBase(uriInfo).path(TokenService.class, "accessTokenGrant");
+ public static UriBuilder grantAccessTokenUrl(UriInfo uriInfo) {
+ return tokenServiceBaseUrl(uriInfo).path(TokenService.class, "grantAccessToken");
}
- public static UriBuilder identityGrantRequest(UriInfo uriInfo) {
- return tokenServiceBase(uriInfo).path(TokenService.class, "accessTokenGrant");
+ public static UriBuilder grantIdentityTokenUrl(UriInfo uriInfo) {
+ return tokenServiceBaseUrl(uriInfo).path(TokenService.class, "grantIdentityToken");
}
public static UriBuilder loginPageUrl(UriInfo uriInfo) {
- return tokenServiceBase(uriInfo).path(TokenService.class, "loginRequest");
+ return tokenServiceBaseUrl(uriInfo).path(TokenService.class, "loginPage");
}
- public static UriBuilder logainActionUrl(UriInfo uriInfo) {
- return tokenServiceBase(uriInfo).path(TokenService.class, "login");
+ public static UriBuilder processLoginUrl(UriInfo uriInfo) {
+ return tokenServiceBaseUrl(uriInfo).path(TokenService.class, "processLogin");
}
@@ -113,7 +113,7 @@ public class TokenService {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
- public Response identityTokenGrant(MultivaluedMap<String, String> form) {
+ public Response grantIdentityToken(MultivaluedMap<String, String> form) {
String username = form.getFirst(AuthenticationManager.FORM_USERNAME);
if (username == null) {
throw new NotAuthorizedException("No user");
@@ -142,7 +142,7 @@ public class TokenService {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
- public Response accessTokenGrant(MultivaluedMap<String, String> form) {
+ public Response grantAccessToken(MultivaluedMap<String, String> form) {
String username = form.getFirst(AuthenticationManager.FORM_USERNAME);
if (username == null) {
throw new NotAuthorizedException("No user");
@@ -169,7 +169,7 @@ public class TokenService {
@Path("auth/request/login")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
- public Response login(MultivaluedMap<String, String> formData) {
+ public Response processLogin(MultivaluedMap<String, String> formData) {
String clientId = formData.getFirst("client_id");
String scopeParam = formData.getFirst("scope");
String state = formData.getFirst("state");
@@ -226,7 +226,7 @@ public class TokenService {
@Path("access/codes")
@POST
@Produces("application/json")
- public Response accessRequest(MultivaluedMap<String, String> formData) {
+ public Response accessCodeToToken(MultivaluedMap<String, String> formData) {
logger.info("accessRequest <---");
if (!realm.isEnabled()) {
throw new NotAuthorizedException("Realm not enabled");
@@ -356,7 +356,7 @@ public class TokenService {
String scopeParam,
String state) {
request.setAttribute(RealmModel.class.getName(), realm);
- request.setAttribute("KEYCLOAK_LOGIN_ACTION", logainActionUrl(uriInfo).build(realm.getId()));
+ request.setAttribute("KEYCLOAK_LOGIN_ACTION", processLoginUrl(uriInfo).build(realm.getId()));
// RESTEASY eats the form data, so we send via an attribute
request.setAttribute("redirect_uri", redirect);
@@ -369,11 +369,11 @@ public class TokenService {
@Path("login")
@GET
- public Response loginRequest(@QueryParam("response_type") String responseType,
- @QueryParam("redirect_uri") String redirect,
- @QueryParam("client_id") String clientId,
- @QueryParam("scope") String scopeParam,
- @QueryParam("state") String state) {
+ public Response loginPage(@QueryParam("response_type") String responseType,
+ @QueryParam("redirect_uri") String redirect,
+ @QueryParam("client_id") String clientId,
+ @QueryParam("scope") String scopeParam,
+ @QueryParam("state") String state) {
if (!realm.isEnabled()) {
securityFailureForward("Realm not enabled");
return null;
@@ -390,7 +390,7 @@ public class TokenService {
return null;
}
- User user = authManager.authenticateIdentityCookie(realm, headers);
+ User user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
if (user != null) {
return redirectAccessCode(scopeParam, state, redirect, client, user);
}
@@ -400,6 +400,21 @@ public class TokenService {
return null;
}
+ @Path("logout")
+ @GET
+ public Response logout(@QueryParam("redirect_uri") String redirectUri) {
+ // todo do we care if anybody can trigger this?
+
+ User user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
+ if (user != null) {
+ logger.info("Logging out: " + user.getLoginName());
+ authManager.expireIdentityCookie(realm, uriInfo);
+ resourceAdminManager.singleLogOut(realm, user.getLoginName());
+ }
+ // todo manage legal redirects
+ return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build();
+ }
+
private Response loginForm(String validationError, String redirect, String clientId, String scopeParam, String state, RealmModel realm, User client) {
StringBuffer html = new StringBuffer();
if (scopeParam != null) {
@@ -431,7 +446,7 @@ public class TokenService {
}
html.append("</table><p>To Authorize, please login below</p>");
} else {
- Set<String> scopeMapping = realm.getScopes(client);
+ Set<String> scopeMapping = realm.getScope(client);
if (scopeMapping.contains("*")) {
html.append("<h1>Login For ").append(realm.getName()).append(" Realm</h1>");
if (validationError != null) {
@@ -485,7 +500,7 @@ public class TokenService {
}
}
- UriBuilder formActionUri = logainActionUrl(uriInfo);
+ UriBuilder formActionUri = processLoginUrl(uriInfo);
String action = formActionUri.build(realm.getId()).toString();
html.append("<form action=\"").append(action).append("\" method=\"POST\">");
html.append("Username: <input type=\"text\" name=\"username\" size=\"20\"><br>");
diff --git a/services/src/test/java/org/keycloak/test/AdapterTest.java b/services/src/test/java/org/keycloak/test/AdapterTest.java
index 78622cc..f798539 100755
--- a/services/src/test/java/org/keycloak/test/AdapterTest.java
+++ b/services/src/test/java/org/keycloak/test/AdapterTest.java
@@ -166,7 +166,7 @@ public class AdapterTest {
idm.add(new SimpleRole("admin"));
idm.add(new SimpleRole("user"));
List<Role> roles = realmModel.getRoles();
- Assert.assertEquals(2, roles.size());
+ Assert.assertEquals(3, roles.size());
SimpleUser user = new SimpleUser("bburke");
idm.add(user);
Role role = idm.getRole("user");
diff --git a/services/src/test/java/org/keycloak/test/ImportTest.java b/services/src/test/java/org/keycloak/test/ImportTest.java
index 335169a..c785e21 100755
--- a/services/src/test/java/org/keycloak/test/ImportTest.java
+++ b/services/src/test/java/org/keycloak/test/ImportTest.java
@@ -104,7 +104,7 @@ public class ImportTest {
User user = realm.getIdm().getUser("loginclient");
Assert.assertNotNull(user);
- Set<String> scopes = realm.getScopes(user);
+ Set<String> scopes = realm.getScope(user);
System.out.println("Scopes size: " + scopes.size());
Assert.assertTrue(scopes.contains("*"));