commit
1be8136347
33 changed files with 551 additions and 236 deletions
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
15
core/src/main/java/org/keycloak/TokenIdGenerator.java
Executable file
15
core/src/main/java/org/keycloak/TokenIdGenerator.java
Executable file
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
66
core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java
Executable file
66
core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java
Executable file
|
@ -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;
|
||||
}
|
||||
}
|
26
core/src/main/java/org/keycloak/representations/idm/admin/LogoutAction.java
Executable file
26
core/src/main/java/org/keycloak/representations/idm/admin/LogoutAction.java
Executable file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
8
examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
Normal file → Executable file
8
examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
Normal file → Executable file
|
@ -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>
|
||||
<%
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"realm" : "demo",
|
||||
"resource" : "database-service",
|
||||
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB"
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
9
examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
Normal file → Executable file
9
examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
Normal file → Executable file
|
@ -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>
|
||||
<%
|
||||
|
|
|
@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,7 +369,7 @@ public class TokenService {
|
|||
|
||||
@Path("login")
|
||||
@GET
|
||||
public Response loginRequest(@QueryParam("response_type") String responseType,
|
||||
public Response loginPage(@QueryParam("response_type") String responseType,
|
||||
@QueryParam("redirect_uri") String redirect,
|
||||
@QueryParam("client_id") String clientId,
|
||||
@QueryParam("scope") String scopeParam,
|
||||
|
@ -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>");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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("*"));
|
||||
|
||||
|
|
Loading…
Reference in a new issue