From 33e9de654b7dc9e944aa4065dc28040f1ed1c692 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Fri, 19 Jul 2013 21:33:44 -0400 Subject: [PATCH] more --- .../org/keycloak/AbstractOAuthClient.java | 213 +-- .../java/org/keycloak/BouncyIntegration.java | 17 +- core/src/main/java/org/keycloak/DerUtils.java | 72 +- core/src/main/java/org/keycloak/EnvUtil.java | 43 +- core/src/main/java/org/keycloak/PemUtils.java | 166 +- .../java/org/keycloak/RSATokenVerifier.java | 76 +- .../java/org/keycloak/RealmConfiguration.java | 124 +- .../java/org/keycloak/ResourceMetadata.java | 131 +- .../keycloak/SkeletonKeyContextResolver.java | 37 +- .../org/keycloak/SkeletonKeyPrincipal.java | 73 +- .../java/org/keycloak/SkeletonKeySession.java | 35 +- .../org/keycloak/VerificationException.java | 29 +- .../jaxrs/JaxrsBearerTokenFilter.java | 156 +- .../org/keycloak/jaxrs/JaxrsOAuthClient.java | 59 +- .../representations/AccessTokenResponse.java | 75 +- .../representations/SkeletonKeyScope.java | 3 +- .../representations/SkeletonKeyToken.java | 286 ++- .../idm/PublishedRealmRepresentation.java | 214 +-- .../idm/RealmRepresentation.java | 257 ++- .../idm/RequiredCredentialRepresentation.java | 59 +- .../idm/ResourceRepresentation.java | 132 +- .../idm/RoleMappingRepresentation.java | 64 +- .../idm/ScopeMappingRepresentation.java | 64 +- .../idm/UserRepresentation.java | 172 +- .../keycloak/servlet/ServletOAuthClient.java | 181 +- .../WEB-INF/jboss-deployment-structure.xml | 3 - .../org/keycloak/adapters/as7/Actions.java | 13 +- .../as7/BearerTokenAuthenticatorValve.java | 94 +- .../as7/CatalinaBearerTokenAuthenticator.java | 227 +-- .../as7/CatalinaSecurityContextHelper.java | 204 +- .../as7/OAuthAuthenticationServerValve.java | 1635 ++++++++--------- .../as7/OAuthManagedResourceValve.java | 418 ++--- .../adapters/as7/ServletOAuthLogin.java | 482 +++-- .../adapters/as7/UserSessionManagement.java | 144 +- .../adapters/as7/config/AuthServerConfig.java | 374 ++-- .../as7/config/ManagedResourceConfig.java | 307 ++-- .../config/ManagedResourceConfigLoader.java | 270 +-- .../services/resources/RealmSubResource.java | 32 +- 38 files changed, 3141 insertions(+), 3800 deletions(-) diff --git a/core/src/main/java/org/keycloak/AbstractOAuthClient.java b/core/src/main/java/org/keycloak/AbstractOAuthClient.java index 180bd5f310..bf40101188 100755 --- a/core/src/main/java/org/keycloak/AbstractOAuthClient.java +++ b/core/src/main/java/org/keycloak/AbstractOAuthClient.java @@ -1,8 +1,8 @@ package org.keycloak; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.keycloak.representations.AccessTokenResponse; import org.jboss.resteasy.util.BasicAuthHelper; +import org.keycloak.representations.AccessTokenResponse; import javax.ws.rs.BadRequestException; import javax.ws.rs.InternalServerErrorException; @@ -20,143 +20,116 @@ import java.util.concurrent.atomic.AtomicLong; * @author Bill Burke * @version $Revision: 1 $ */ -public class AbstractOAuthClient -{ - protected String clientId; - protected String password; - protected KeyStore truststore; - protected String authUrl; - protected String codeUrl; - protected String stateCookieName = "OAuth_Token_Request_State"; - protected Client client; - protected final AtomicLong counter = new AtomicLong(); +public class AbstractOAuthClient { + protected String clientId; + protected String password; + protected KeyStore truststore; + protected String authUrl; + protected String codeUrl; + protected String stateCookieName = "OAuth_Token_Request_State"; + protected Client client; + protected final AtomicLong counter = new AtomicLong(); - protected String getStateCode() - { - return counter.getAndIncrement() + "/" + UUID.randomUUID().toString(); - } + protected String getStateCode() { + return counter.getAndIncrement() + "/" + UUID.randomUUID().toString(); + } - public void start() - { - if (client == null) - { - client = new ResteasyClientBuilder().trustStore(truststore) - .hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY) - .connectionPoolSize(10) - .build(); - } - } + public void start() { + if (client == null) { + client = new ResteasyClientBuilder().trustStore(truststore) + .hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY) + .connectionPoolSize(10) + .build(); + } + } - public void stop() - { - client.close(); - } + public void stop() { + client.close(); + } - public String getClientId() - { - return clientId; - } + public String getClientId() { + return clientId; + } - public void setClientId(String clientId) - { - this.clientId = clientId; - } + public void setClientId(String clientId) { + this.clientId = clientId; + } - public String getPassword() - { - return password; - } + public String getPassword() { + return password; + } - public void setPassword(String password) - { - this.password = password; - } + public void setPassword(String password) { + this.password = password; + } - public KeyStore getTruststore() - { - return truststore; - } + public KeyStore getTruststore() { + return truststore; + } - public void setTruststore(KeyStore truststore) - { - this.truststore = truststore; - } + public void setTruststore(KeyStore truststore) { + this.truststore = truststore; + } - public String getAuthUrl() - { - return authUrl; - } + public String getAuthUrl() { + return authUrl; + } - public void setAuthUrl(String authUrl) - { - this.authUrl = authUrl; - } + public void setAuthUrl(String authUrl) { + this.authUrl = authUrl; + } - public String getCodeUrl() - { - return codeUrl; - } + public String getCodeUrl() { + return codeUrl; + } - public void setCodeUrl(String codeUrl) - { - this.codeUrl = codeUrl; - } + public void setCodeUrl(String codeUrl) { + this.codeUrl = codeUrl; + } - public String getStateCookieName() - { - return stateCookieName; - } + public String getStateCookieName() { + return stateCookieName; + } - public void setStateCookieName(String stateCookieName) - { - this.stateCookieName = stateCookieName; - } + public void setStateCookieName(String stateCookieName) { + this.stateCookieName = stateCookieName; + } - public Client getClient() - { - return client; - } + public Client getClient() { + return client; + } - public void setClient(Client client) - { - this.client = client; - } + public void setClient(Client client) { + this.client = client; + } - public String resolveBearerToken(String redirectUri, String code) - { - redirectUri = stripOauthParametersFromRedirect(redirectUri); - String authHeader = BasicAuthHelper.createHeader(clientId, password); - Form codeForm = new Form() - .param("grant_type", "authorization_code") - .param("code", code) - .param("redirect_uri", redirectUri); - Response res = client.target(codeUrl).request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(codeForm)); - try - { - if (res.getStatus() == 400) - { - throw new BadRequestException(); - } - else if (res.getStatus() != 200) - { - throw new InternalServerErrorException(new Exception("Unknown error when getting acess token")); - } - AccessTokenResponse tokenResponse = res.readEntity(AccessTokenResponse.class); - return tokenResponse.getToken(); - } - finally - { - res.close(); - } - } + public String resolveBearerToken(String redirectUri, String code) { + redirectUri = stripOauthParametersFromRedirect(redirectUri); + String authHeader = BasicAuthHelper.createHeader(clientId, password); + Form codeForm = new Form() + .param("grant_type", "authorization_code") + .param("code", code) + .param("redirect_uri", redirectUri); + Response res = client.target(codeUrl).request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(codeForm)); + try { + if (res.getStatus() == 400) { + throw new BadRequestException(); + } else if (res.getStatus() != 200) { + throw new InternalServerErrorException(new Exception("Unknown error when getting acess token")); + } + AccessTokenResponse tokenResponse = res.readEntity(AccessTokenResponse.class); + return tokenResponse.getToken(); + } finally { + res.close(); + } + } - protected String stripOauthParametersFromRedirect(String uri) - { - System.out.println("******************** redirect_uri: " + uri); - UriBuilder builder = UriBuilder.fromUri(uri) - .replaceQueryParam("code", null) - .replaceQueryParam("state", null); - return builder.build().toString(); - } + protected String stripOauthParametersFromRedirect(String uri) { + System.out.println("******************** redirect_uri: " + uri); + UriBuilder builder = UriBuilder.fromUri(uri) + .replaceQueryParam("code", null) + .replaceQueryParam("state", null); + return builder.build().toString(); + } } diff --git a/core/src/main/java/org/keycloak/BouncyIntegration.java b/core/src/main/java/org/keycloak/BouncyIntegration.java index 7d1635b109..defdd5c03e 100755 --- a/core/src/main/java/org/keycloak/BouncyIntegration.java +++ b/core/src/main/java/org/keycloak/BouncyIntegration.java @@ -8,15 +8,12 @@ import java.security.Security; * @author Bill Burke * @version $Revision: 1 $ */ -public class BouncyIntegration -{ - static - { - if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider()); - } +public class BouncyIntegration { + static { + if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider()); + } - public static void init() - { - // empty, the static class does it - } + public static void init() { + // empty, the static class does it + } } diff --git a/core/src/main/java/org/keycloak/DerUtils.java b/core/src/main/java/org/keycloak/DerUtils.java index ca92418c67..6854677bc6 100755 --- a/core/src/main/java/org/keycloak/DerUtils.java +++ b/core/src/main/java/org/keycloak/DerUtils.java @@ -20,49 +20,43 @@ import java.security.spec.X509EncodedKeySpec; * @author Bill Burke * @version $Revision: 1 $ */ -public class DerUtils -{ - static - { - BouncyIntegration.init(); - } +public class DerUtils { + static { + BouncyIntegration.init(); + } - public static PrivateKey decodePrivateKey(InputStream is) - throws Exception - { + public static PrivateKey decodePrivateKey(InputStream is) + throws Exception { - DataInputStream dis = new DataInputStream(is); - byte[] keyBytes = new byte[dis.available()]; - dis.readFully(keyBytes); - dis.close(); + DataInputStream dis = new DataInputStream(is); + byte[] keyBytes = new byte[dis.available()]; + dis.readFully(keyBytes); + dis.close(); - PKCS8EncodedKeySpec spec = - new PKCS8EncodedKeySpec(keyBytes); - KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); - return kf.generatePrivate(spec); - } + PKCS8EncodedKeySpec spec = + new PKCS8EncodedKeySpec(keyBytes); + KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); + return kf.generatePrivate(spec); + } - public static PublicKey decodePublicKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException - { - X509EncodedKeySpec spec = - new X509EncodedKeySpec(der); - KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); - return kf.generatePublic(spec); - } + public static PublicKey decodePublicKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { + X509EncodedKeySpec spec = + new X509EncodedKeySpec(der); + KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); + return kf.generatePublic(spec); + } - public static X509Certificate decodeCertificate(InputStream is) throws Exception - { - CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); - X509Certificate cert = (X509Certificate) cf.generateCertificate(is); - is.close(); - return cert; - } + public static X509Certificate decodeCertificate(InputStream is) throws Exception { + CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(is); + is.close(); + return cert; + } - public static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException - { - PKCS8EncodedKeySpec spec = - new PKCS8EncodedKeySpec(der); - KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); - return kf.generatePrivate(spec); - } + public static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { + PKCS8EncodedKeySpec spec = + new PKCS8EncodedKeySpec(der); + KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); + return kf.generatePrivate(spec); + } } diff --git a/core/src/main/java/org/keycloak/EnvUtil.java b/core/src/main/java/org/keycloak/EnvUtil.java index 66917f0cb0..c60111867b 100755 --- a/core/src/main/java/org/keycloak/EnvUtil.java +++ b/core/src/main/java/org/keycloak/EnvUtil.java @@ -7,30 +7,27 @@ import java.util.regex.Pattern; * @author Bill Burke * @version $Revision: 1 $ */ -public class EnvUtil -{ - private static final Pattern p = Pattern.compile("[$][{]([^}]+)[}]"); +public class EnvUtil { + private static final Pattern p = Pattern.compile("[$][{]([^}]+)[}]"); - /** - * Replaces any ${} strings with their corresponding environent variable. - * - * @param val - * @return - */ - public static String replace(String val) - { - Matcher matcher = p.matcher(val); - StringBuffer buf = new StringBuffer(); - while (matcher.find()) - { - String envVar = matcher.group(1); - String envVal = System.getProperty(envVar); - if (envVal == null) envVal = "NOT-SPECIFIED"; - matcher.appendReplacement(buf, envVal.replace("\\", "\\\\")); - } - matcher.appendTail(buf); - return buf.toString(); - } + /** + * Replaces any ${} strings with their corresponding environent variable. + * + * @param val + * @return + */ + public static String replace(String val) { + Matcher matcher = p.matcher(val); + StringBuffer buf = new StringBuffer(); + while (matcher.find()) { + String envVar = matcher.group(1); + String envVal = System.getProperty(envVar); + if (envVal == null) envVal = "NOT-SPECIFIED"; + matcher.appendReplacement(buf, envVal.replace("\\", "\\\\")); + } + matcher.appendTail(buf); + return buf.toString(); + } } diff --git a/core/src/main/java/org/keycloak/PemUtils.java b/core/src/main/java/org/keycloak/PemUtils.java index 5f2fcebbe1..32babcb196 100755 --- a/core/src/main/java/org/keycloak/PemUtils.java +++ b/core/src/main/java/org/keycloak/PemUtils.java @@ -16,102 +16,92 @@ import java.security.cert.X509Certificate; * @author Bill Burke * @version $Revision: 1 $ */ -public class PemUtils -{ - static - { - BouncyIntegration.init(); - } - public static X509Certificate decodeCertificate(InputStream is) throws Exception - { - byte[] der = pemToDer(is); - ByteArrayInputStream bis = new ByteArrayInputStream(der); - return DerUtils.decodeCertificate(bis); - } +public class PemUtils { + static { + BouncyIntegration.init(); + } - public static X509Certificate decodeCertificate(String cert) throws Exception - { - byte[] der = pemToDer(cert); - ByteArrayInputStream bis = new ByteArrayInputStream(der); - return DerUtils.decodeCertificate(bis); - } + public static X509Certificate decodeCertificate(InputStream is) throws Exception { + byte[] der = pemToDer(is); + ByteArrayInputStream bis = new ByteArrayInputStream(der); + return DerUtils.decodeCertificate(bis); + } + + public static X509Certificate decodeCertificate(String cert) throws Exception { + byte[] der = pemToDer(cert); + ByteArrayInputStream bis = new ByteArrayInputStream(der); + return DerUtils.decodeCertificate(bis); + } - /** - * Extract a public key from a PEM string - * - * @param pem - * @return - * @throws Exception - */ - public static PublicKey decodePublicKey(String pem) throws Exception - { - byte[] der = pemToDer(pem); - return DerUtils.decodePublicKey(der); - } + /** + * Extract a public key from a PEM string + * + * @param pem + * @return + * @throws Exception + */ + public static PublicKey decodePublicKey(String pem) throws Exception { + byte[] der = pemToDer(pem); + return DerUtils.decodePublicKey(der); + } - /** - * Extract a private key that is a PKCS8 pem string (base64 encoded PKCS8) - * - * @param pem - * @return - * @throws Exception - */ - public static PrivateKey decodePrivateKey(String pem) throws Exception - { - byte[] der = pemToDer(pem); - return DerUtils.decodePrivateKey(der); - } + /** + * Extract a private key that is a PKCS8 pem string (base64 encoded PKCS8) + * + * @param pem + * @return + * @throws Exception + */ + public static PrivateKey decodePrivateKey(String pem) throws Exception { + byte[] der = pemToDer(pem); + return DerUtils.decodePrivateKey(der); + } - public static PrivateKey decodePrivateKey(InputStream is) throws Exception - { - String pem = pemFromStream(is); - return decodePrivateKey(pem); - } + public static PrivateKey decodePrivateKey(InputStream is) throws Exception { + String pem = pemFromStream(is); + return decodePrivateKey(pem); + } - /** - * Decode a PEM file to DER format - * - * @param is - * @return - * @throws java.io.IOException - */ - public static byte[] pemToDer(InputStream is) throws IOException - { - String pem = pemFromStream(is); - byte[] der = pemToDer(pem); - return der; - } + /** + * Decode a PEM file to DER format + * + * @param is + * @return + * @throws java.io.IOException + */ + public static byte[] pemToDer(InputStream is) throws IOException { + String pem = pemFromStream(is); + byte[] der = pemToDer(pem); + return der; + } - /** - * Decode a PEM string to DER format - * - * @param pem - * @return - * @throws java.io.IOException - */ - public static byte[] pemToDer(String pem) throws IOException - { - pem = removeBeginEnd(pem); - return Base64.decode(pem); - } + /** + * Decode a PEM string to DER format + * + * @param pem + * @return + * @throws java.io.IOException + */ + public static byte[] pemToDer(String pem) throws IOException { + pem = removeBeginEnd(pem); + return Base64.decode(pem); + } - public static String removeBeginEnd(String pem) - { - pem = pem.replaceAll("-----BEGIN (.*)-----", ""); - pem = pem.replaceAll("-----END (.*)----", ""); - pem = pem.replaceAll("\r\n", ""); - pem = pem.replaceAll("\n", ""); - return pem.trim(); - } + public static String removeBeginEnd(String pem) { + pem = pem.replaceAll("-----BEGIN (.*)-----", ""); + pem = pem.replaceAll("-----END (.*)----", ""); + pem = pem.replaceAll("\r\n", ""); + pem = pem.replaceAll("\n", ""); + return pem.trim(); + } - public static String pemFromStream(InputStream is) throws IOException - { - DataInputStream dis = new DataInputStream(is); - byte[] keyBytes = new byte[dis.available()]; - dis.readFully(keyBytes); - dis.close(); - return new String(keyBytes, "utf-8"); - } + public static String pemFromStream(InputStream is) throws IOException { + DataInputStream dis = new DataInputStream(is); + byte[] keyBytes = new byte[dis.available()]; + dis.readFully(keyBytes); + dis.close(); + return new String(keyBytes, "utf-8"); + } } diff --git a/core/src/main/java/org/keycloak/RSATokenVerifier.java b/core/src/main/java/org/keycloak/RSATokenVerifier.java index 7b4b2a0976..8c703d7f10 100755 --- a/core/src/main/java/org/keycloak/RSATokenVerifier.java +++ b/core/src/main/java/org/keycloak/RSATokenVerifier.java @@ -12,52 +12,40 @@ import java.security.PublicKey; * @author Bill Burke * @version $Revision: 1 $ */ -public class RSATokenVerifier -{ - public static SkeletonKeyToken verifyToken(String tokenString, ResourceMetadata metadata) throws VerificationException - { - PublicKey realmKey = metadata.getRealmKey(); - String realm = metadata.getRealm(); - return verifyToken(tokenString, realmKey, realm); - } +public class RSATokenVerifier { + public static SkeletonKeyToken verifyToken(String tokenString, ResourceMetadata metadata) throws VerificationException { + PublicKey realmKey = metadata.getRealmKey(); + String realm = metadata.getRealm(); + return verifyToken(tokenString, realmKey, realm); + } - public static SkeletonKeyToken verifyToken(String tokenString, PublicKey realmKey, String realm) throws VerificationException - { - JWSInput input = new JWSInput(tokenString); - boolean verified = false; - try - { - verified = RSAProvider.verify(input, realmKey); - } - catch (Exception ignore) - { + public static SkeletonKeyToken verifyToken(String tokenString, PublicKey realmKey, String realm) throws VerificationException { + JWSInput input = new JWSInput(tokenString); + boolean verified = false; + try { + verified = RSAProvider.verify(input, realmKey); + } catch (Exception ignore) { - } - if (!verified) throw new VerificationException("Token signature not validated"); + } + if (!verified) throw new VerificationException("Token signature not validated"); - SkeletonKeyToken token = null; - try - { - token = JsonSerialization.fromBytes(SkeletonKeyToken.class, input.getContent()); - } - catch (IOException e) - { - throw new VerificationException(e); - } - if (!token.isActive()) - { - throw new VerificationException("Token is not active."); - } - String user = token.getPrincipal(); - if (user == null) - { - throw new VerificationException("Token user was null"); - } - if (!realm.equals(token.getAudience())) - { - throw new VerificationException("Token audience doesn't match domain"); + SkeletonKeyToken token = null; + try { + token = JsonSerialization.fromBytes(SkeletonKeyToken.class, input.getContent()); + } catch (IOException e) { + throw new VerificationException(e); + } + if (!token.isActive()) { + throw new VerificationException("Token is not active."); + } + String user = token.getPrincipal(); + if (user == null) { + throw new VerificationException("Token user was null"); + } + if (!realm.equals(token.getAudience())) { + throw new VerificationException("Token audience doesn't match domain"); - } - return token; - } + } + return token; + } } diff --git a/core/src/main/java/org/keycloak/RealmConfiguration.java b/core/src/main/java/org/keycloak/RealmConfiguration.java index c19c21fd71..8563cdf875 100755 --- a/core/src/main/java/org/keycloak/RealmConfiguration.java +++ b/core/src/main/java/org/keycloak/RealmConfiguration.java @@ -10,89 +10,73 @@ import javax.ws.rs.core.UriBuilder; * @author Bill Burke * @version $Revision: 1 $ */ -public class RealmConfiguration -{ - protected ResourceMetadata metadata; - protected ResteasyClient client; - protected UriBuilder authUrl; - protected ResteasyWebTarget codeUrl; - protected String clientId; - protected Form credentials = new Form(); - protected boolean sslRequired = true; - protected String stateCookieName = "OAuth_Token_Request_State"; +public class RealmConfiguration { + protected ResourceMetadata metadata; + protected ResteasyClient client; + protected UriBuilder authUrl; + protected ResteasyWebTarget codeUrl; + protected String clientId; + protected Form credentials = new Form(); + protected boolean sslRequired = true; + protected String stateCookieName = "OAuth_Token_Request_State"; - public ResourceMetadata getMetadata() - { - return metadata; - } + public ResourceMetadata getMetadata() { + return metadata; + } - public void setMetadata(ResourceMetadata metadata) - { - this.metadata = metadata; - } + public void setMetadata(ResourceMetadata metadata) { + this.metadata = metadata; + } - public ResteasyClient getClient() - { - return client; - } + public ResteasyClient getClient() { + return client; + } - public void setClient(ResteasyClient client) - { - this.client = client; - } + public void setClient(ResteasyClient client) { + this.client = client; + } - public UriBuilder getAuthUrl() - { - return authUrl; - } + public UriBuilder getAuthUrl() { + return authUrl; + } - public void setAuthUrl(UriBuilder authUrl) - { - this.authUrl = authUrl; - } + public void setAuthUrl(UriBuilder authUrl) { + this.authUrl = authUrl; + } - public String getClientId() - { - return clientId; - } + public String getClientId() { + return clientId; + } - public void setClientId(String clientId) - { - this.clientId = clientId; - } + public void setClientId(String clientId) { + this.clientId = clientId; + } - public Form getCredentials() - { - return credentials; - } + public Form getCredentials() { + return credentials; + } - public ResteasyWebTarget getCodeUrl() - { - return codeUrl; - } + public ResteasyWebTarget getCodeUrl() { + return codeUrl; + } - public void setCodeUrl(ResteasyWebTarget codeUrl) - { - this.codeUrl = codeUrl; - } + public void setCodeUrl(ResteasyWebTarget codeUrl) { + this.codeUrl = codeUrl; + } - public boolean isSslRequired() - { - return sslRequired; - } + public boolean isSslRequired() { + return sslRequired; + } - public void setSslRequired(boolean sslRequired) - { - this.sslRequired = sslRequired; - } + public void setSslRequired(boolean sslRequired) { + this.sslRequired = sslRequired; + } - public String getStateCookieName() - { - return stateCookieName; - } + public String getStateCookieName() { + return stateCookieName; + } - public void setStateCookieName(String stateCookieName) - { - this.stateCookieName = stateCookieName; - } + public void setStateCookieName(String stateCookieName) { + this.stateCookieName = stateCookieName; + } } diff --git a/core/src/main/java/org/keycloak/ResourceMetadata.java b/core/src/main/java/org/keycloak/ResourceMetadata.java index 02e75dbb51..24a277297e 100755 --- a/core/src/main/java/org/keycloak/ResourceMetadata.java +++ b/core/src/main/java/org/keycloak/ResourceMetadata.java @@ -7,88 +7,75 @@ import java.security.PublicKey; * @author Bill Burke * @version $Revision: 1 $ */ -public class ResourceMetadata -{ - protected String resourceName; - protected String realm; - protected KeyStore clientKeystore; - protected String clientKeyPassword; - protected KeyStore truststore; - protected PublicKey realmKey; +public class ResourceMetadata { + protected String resourceName; + protected String realm; + protected KeyStore clientKeystore; + protected String clientKeyPassword; + protected KeyStore truststore; + protected PublicKey realmKey; - public String getResourceName() - { - return resourceName; - } + public String getResourceName() { + return resourceName; + } - public String getRealm() - { - return realm; - } + public String getRealm() { + return realm; + } - /** - * keystore that contains service's private key and certificate. - * Used when making invocations on remote HTTPS endpoints that require client-cert authentication - * - * @return - */ - public KeyStore getClientKeystore() - { - return clientKeystore; - } + /** + * keystore that contains service's private key and certificate. + * Used when making invocations on remote HTTPS endpoints that require client-cert authentication + * + * @return + */ + public KeyStore getClientKeystore() { + return clientKeystore; + } - public String getClientKeyPassword() - { - return clientKeyPassword; - } + public String getClientKeyPassword() { + return clientKeyPassword; + } - public void setClientKeyPassword(String clientKeyPassword) - { - this.clientKeyPassword = clientKeyPassword; - } + public void setClientKeyPassword(String clientKeyPassword) { + this.clientKeyPassword = clientKeyPassword; + } - /** - * Truststore to use if this service makes client invocations on remote HTTPS endpoints. - * - * @return - */ - public KeyStore getTruststore() - { - return truststore; - } + /** + * Truststore to use if this service makes client invocations on remote HTTPS endpoints. + * + * @return + */ + public KeyStore getTruststore() { + return truststore; + } - /** - * Public key of the realm. Used to verify access tokens - * - * @return - */ - public PublicKey getRealmKey() - { - return realmKey; - } + /** + * Public key of the realm. Used to verify access tokens + * + * @return + */ + public PublicKey getRealmKey() { + return realmKey; + } - public void setResourceName(String resourceName) - { - this.resourceName = resourceName; - } + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } - public void setRealm(String realm) - { - this.realm = realm; - } + public void setRealm(String realm) { + this.realm = realm; + } - public void setClientKeystore(KeyStore clientKeystore) - { - this.clientKeystore = clientKeystore; - } + public void setClientKeystore(KeyStore clientKeystore) { + this.clientKeystore = clientKeystore; + } - public void setTruststore(KeyStore truststore) - { - this.truststore = truststore; - } + public void setTruststore(KeyStore truststore) { + this.truststore = truststore; + } - public void setRealmKey(PublicKey realmKey) - { - this.realmKey = realmKey; - } + public void setRealmKey(PublicKey realmKey) { + this.realmKey = realmKey; + } } diff --git a/core/src/main/java/org/keycloak/SkeletonKeyContextResolver.java b/core/src/main/java/org/keycloak/SkeletonKeyContextResolver.java index 9b83907d35..805a8438d1 100755 --- a/core/src/main/java/org/keycloak/SkeletonKeyContextResolver.java +++ b/core/src/main/java/org/keycloak/SkeletonKeyContextResolver.java @@ -14,29 +14,24 @@ import javax.ws.rs.ext.Provider; * @version $Revision: 1 $ */ @Provider -public class SkeletonKeyContextResolver implements ContextResolver -{ - protected ObjectMapper mapper = new ObjectMapper(); +public class SkeletonKeyContextResolver implements ContextResolver { + protected ObjectMapper mapper = new ObjectMapper(); - public SkeletonKeyContextResolver() - { - mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); - } + public SkeletonKeyContextResolver() { + mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); + } - public SkeletonKeyContextResolver(boolean indent) - { - mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); - if (indent) - { - mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT); - } - } + public SkeletonKeyContextResolver(boolean indent) { + mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); + if (indent) { + mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT); + } + } - @Override - public ObjectMapper getContext(Class type) - { - if (type.getPackage().getName().startsWith(getClass().getPackage().getName())) return mapper; - return null; - } + @Override + public ObjectMapper getContext(Class type) { + if (type.getPackage().getName().startsWith(getClass().getPackage().getName())) return mapper; + return null; + } } diff --git a/core/src/main/java/org/keycloak/SkeletonKeyPrincipal.java b/core/src/main/java/org/keycloak/SkeletonKeyPrincipal.java index bdba805c5e..eeb4e522f5 100755 --- a/core/src/main/java/org/keycloak/SkeletonKeyPrincipal.java +++ b/core/src/main/java/org/keycloak/SkeletonKeyPrincipal.java @@ -6,53 +6,46 @@ import java.security.Principal; * @author Bill Burke * @version $Revision: 1 $ */ -public class SkeletonKeyPrincipal implements Principal -{ - protected String name; - protected String surrogate; +public class SkeletonKeyPrincipal implements Principal { + protected String name; + protected String surrogate; - public SkeletonKeyPrincipal(String name, String surrogate) - { - this.name = name; - this.surrogate = surrogate; - } + public SkeletonKeyPrincipal(String name, String surrogate) { + this.name = name; + this.surrogate = surrogate; + } - @Override - public String getName() - { - return name; - } + @Override + public String getName() { + return name; + } - public String getSurrogate() - { - return surrogate; - } + public String getSurrogate() { + return surrogate; + } - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - SkeletonKeyPrincipal that = (SkeletonKeyPrincipal) o; + SkeletonKeyPrincipal that = (SkeletonKeyPrincipal) o; - if (!name.equals(that.name)) return false; - if (surrogate != null ? !surrogate.equals(that.surrogate) : that.surrogate != null) return false; + if (!name.equals(that.name)) return false; + if (surrogate != null ? !surrogate.equals(that.surrogate) : that.surrogate != null) return false; - return true; - } + return true; + } - @Override - public int hashCode() - { - int result = name.hashCode(); - result = 31 * result + (surrogate != null ? surrogate.hashCode() : 0); - return result; - } + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + (surrogate != null ? surrogate.hashCode() : 0); + return result; + } - @Override - public String toString() - { - return name; - } + @Override + public String toString() { + return name; + } } diff --git a/core/src/main/java/org/keycloak/SkeletonKeySession.java b/core/src/main/java/org/keycloak/SkeletonKeySession.java index e3a2f5548d..52332aac0b 100755 --- a/core/src/main/java/org/keycloak/SkeletonKeySession.java +++ b/core/src/main/java/org/keycloak/SkeletonKeySession.java @@ -6,29 +6,24 @@ import java.io.Serializable; * @author Bill Burke * @version $Revision: 1 $ */ -public class SkeletonKeySession implements Serializable -{ - protected String token; - protected transient ResourceMetadata metadata; +public class SkeletonKeySession implements Serializable { + protected String token; + protected transient ResourceMetadata metadata; - public SkeletonKeySession() - { - } + public SkeletonKeySession() { + } - public SkeletonKeySession(String token, ResourceMetadata metadata) - { - this.token = token; - this.metadata = metadata; - } + public SkeletonKeySession(String token, ResourceMetadata metadata) { + this.token = token; + this.metadata = metadata; + } - public String getToken() - { - return token; - } + public String getToken() { + return token; + } - public ResourceMetadata getMetadata() - { - return metadata; - } + public ResourceMetadata getMetadata() { + return metadata; + } } diff --git a/core/src/main/java/org/keycloak/VerificationException.java b/core/src/main/java/org/keycloak/VerificationException.java index 6ef877d479..ee34b71829 100755 --- a/core/src/main/java/org/keycloak/VerificationException.java +++ b/core/src/main/java/org/keycloak/VerificationException.java @@ -4,24 +4,19 @@ package org.keycloak; * @author Bill Burke * @version $Revision: 1 $ */ -public class VerificationException extends Exception -{ - public VerificationException() - { - } +public class VerificationException extends Exception { + public VerificationException() { + } - public VerificationException(String message) - { - super(message); - } + public VerificationException(String message) { + super(message); + } - public VerificationException(String message, Throwable cause) - { - super(message, cause); - } + public VerificationException(String message, Throwable cause) { + super(message, cause); + } - public VerificationException(Throwable cause) - { - super(cause); - } + public VerificationException(Throwable cause) { + super(cause); + } } diff --git a/core/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java b/core/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java index 69c7b0f96c..264db016c4 100755 --- a/core/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java +++ b/core/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java @@ -1,13 +1,13 @@ package org.keycloak.jaxrs; import org.jboss.resteasy.logging.Logger; +import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.RSATokenVerifier; import org.keycloak.ResourceMetadata; import org.keycloak.SkeletonKeyPrincipal; import org.keycloak.SkeletonKeySession; import org.keycloak.VerificationException; import org.keycloak.representations.SkeletonKeyToken; -import org.jboss.resteasy.spi.ResteasyProviderFactory; import javax.annotation.Priority; import javax.ws.rs.Priorities; @@ -25,105 +25,87 @@ import java.security.Principal; * @version $Revision: 1 $ */ @Priority(Priorities.AUTHENTICATION) -public class JaxrsBearerTokenFilter implements ContainerRequestFilter -{ - protected ResourceMetadata resourceMetadata; - private static Logger log = Logger.getLogger(JaxrsBearerTokenFilter.class); +public class JaxrsBearerTokenFilter implements ContainerRequestFilter { + protected ResourceMetadata resourceMetadata; + private static Logger log = Logger.getLogger(JaxrsBearerTokenFilter.class); - public JaxrsBearerTokenFilter(ResourceMetadata resourceMetadata) - { - this.resourceMetadata = resourceMetadata; - } + public JaxrsBearerTokenFilter(ResourceMetadata resourceMetadata) { + this.resourceMetadata = resourceMetadata; + } - protected void challengeResponse(ContainerRequestContext request, String error, String description) - { - StringBuilder header = new StringBuilder("Bearer realm=\""); - header.append(resourceMetadata.getRealm()).append("\""); - if (error != null) - { - header.append(", error=\"").append(error).append("\""); - } - if (description != null) - { - header.append(", error_description=\"").append(description).append("\""); - } - request.abortWith(Response.status(401).header("WWW-Authenticate", header.toString()).build()); - return; - } + protected void challengeResponse(ContainerRequestContext request, String error, String description) { + StringBuilder header = new StringBuilder("Bearer realm=\""); + header.append(resourceMetadata.getRealm()).append("\""); + if (error != null) { + header.append(", error=\"").append(error).append("\""); + } + if (description != null) { + header.append(", error_description=\"").append(description).append("\""); + } + request.abortWith(Response.status(401).header("WWW-Authenticate", header.toString()).build()); + return; + } - @Context - protected SecurityContext securityContext; + @Context + protected SecurityContext securityContext; - @Override - public void filter(ContainerRequestContext request) throws IOException - { - String authHeader = request.getHeaderString(HttpHeaders.AUTHORIZATION); - if (authHeader == null) - { - challengeResponse(request, null, null); - return; - } + @Override + public void filter(ContainerRequestContext request) throws IOException { + String authHeader = request.getHeaderString(HttpHeaders.AUTHORIZATION); + if (authHeader == null) { + challengeResponse(request, null, null); + return; + } - String[] split = authHeader.trim().split("\\s+"); - if (split == null || split.length != 2) challengeResponse(request, null, null); - if (!split[0].equalsIgnoreCase("Bearer")) challengeResponse(request, null, null); + String[] split = authHeader.trim().split("\\s+"); + if (split == null || split.length != 2) challengeResponse(request, null, null); + if (!split[0].equalsIgnoreCase("Bearer")) challengeResponse(request, null, null); - String tokenString = split[1]; + String tokenString = split[1]; - try - { - SkeletonKeyToken token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata); - SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata); - ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); - String callerPrincipal = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : null; + try { + SkeletonKeyToken token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata); + SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata); + ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); + String callerPrincipal = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : null; - final SkeletonKeyPrincipal principal = new SkeletonKeyPrincipal(token.getPrincipal(), callerPrincipal); - final boolean isSecure = securityContext.isSecure(); - final SkeletonKeyToken.Access access; - if (resourceMetadata.getResourceName() != null) - { - access = token.getResourceAccess(resourceMetadata.getResourceName()); - } - else - { - access = token.getRealmAccess(); - } - SecurityContext ctx = new SecurityContext() - { - @Override - public Principal getUserPrincipal() - { - return principal; + final SkeletonKeyPrincipal principal = new SkeletonKeyPrincipal(token.getPrincipal(), callerPrincipal); + final boolean isSecure = securityContext.isSecure(); + final SkeletonKeyToken.Access access; + if (resourceMetadata.getResourceName() != null) { + access = token.getResourceAccess(resourceMetadata.getResourceName()); + } else { + access = token.getRealmAccess(); } + SecurityContext ctx = new SecurityContext() { + @Override + public Principal getUserPrincipal() { + return principal; + } - @Override - public boolean isUserInRole(String role) - { - if (access.getRoles() == null) return false; - return access.getRoles().contains(role); - } + @Override + public boolean isUserInRole(String role) { + if (access.getRoles() == null) return false; + return access.getRoles().contains(role); + } - @Override - public boolean isSecure() - { - return isSecure; - } + @Override + public boolean isSecure() { + return isSecure; + } - @Override - public String getAuthenticationScheme() - { - return "OAUTH_BEARER"; - } - }; - request.setSecurityContext(ctx); - } - catch (VerificationException e) - { - log.error("Failed to verify token", e); - challengeResponse(request, "invalid_token", e.getMessage()); - } - } + @Override + public String getAuthenticationScheme() { + return "OAUTH_BEARER"; + } + }; + request.setSecurityContext(ctx); + } catch (VerificationException e) { + log.error("Failed to verify token", e); + challengeResponse(request, "invalid_token", e.getMessage()); + } + } } diff --git a/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java b/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java index acc99a59f2..380d3ae03f 100755 --- a/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java +++ b/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java @@ -18,38 +18,35 @@ import java.net.URI; * @author Bill Burke * @version $Revision: 1 $ */ -public class JaxrsOAuthClient extends AbstractOAuthClient -{ - public Response redirect(UriInfo uriInfo, String redirectUri) - { - String state = getStateCode(); +public class JaxrsOAuthClient extends AbstractOAuthClient { + public Response redirect(UriInfo uriInfo, String redirectUri) { + String state = getStateCode(); - URI url = UriBuilder.fromUri(authUrl) - .queryParam("client_id", clientId) - .queryParam("redirect_uri", redirectUri) - .queryParam("state", state) - .build(); - NewCookie cookie = new NewCookie(stateCookieName, state, uriInfo.getBaseUri().getPath(), null, null, -1, true); - return Response.status(302) - .location(url) - .cookie(cookie).build(); - } + URI url = UriBuilder.fromUri(authUrl) + .queryParam("client_id", clientId) + .queryParam("redirect_uri", redirectUri) + .queryParam("state", state) + .build(); + NewCookie cookie = new NewCookie(stateCookieName, state, uriInfo.getBaseUri().getPath(), null, null, -1, true); + return Response.status(302) + .location(url) + .cookie(cookie).build(); + } - public String getBearerToken(UriInfo uriInfo, HttpHeaders headers) throws BadRequestException, InternalServerErrorException - { - String error = uriInfo.getQueryParameters().getFirst("error"); - if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error)); - Cookie stateCookie = headers.getCookies().get(stateCookieName); - if (stateCookie == null) throw new BadRequestException(new Exception("state cookie not set"));; + public String getBearerToken(UriInfo uriInfo, HttpHeaders headers) throws BadRequestException, InternalServerErrorException { + String error = uriInfo.getQueryParameters().getFirst("error"); + if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error)); + Cookie stateCookie = headers.getCookies().get(stateCookieName); + if (stateCookie == null) throw new BadRequestException(new Exception("state cookie not set")); + ; - String state = uriInfo.getQueryParameters().getFirst("state"); - if (state == null) throw new BadRequestException(new Exception("state parameter was null")); - if (!state.equals(stateCookie.getValue())) - { - throw new BadRequestException(new Exception("state parameter invalid")); - } - String code = uriInfo.getQueryParameters().getFirst("code"); - if (code == null) throw new BadRequestException(new Exception("code parameter was null")); - return resolveBearerToken(uriInfo.getRequestUri().toString(), code); - } + String state = uriInfo.getQueryParameters().getFirst("state"); + if (state == null) throw new BadRequestException(new Exception("state parameter was null")); + if (!state.equals(stateCookie.getValue())) { + throw new BadRequestException(new Exception("state parameter invalid")); + } + String code = uriInfo.getQueryParameters().getFirst("code"); + if (code == null) throw new BadRequestException(new Exception("code parameter was null")); + return resolveBearerToken(uriInfo.getRequestUri().toString(), code); + } } diff --git a/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java b/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java index a5eec7af5f..985dae4aa4 100755 --- a/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java +++ b/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java @@ -8,57 +8,48 @@ import org.codehaus.jackson.annotate.JsonProperty; * @author Bill Burke * @version $Revision: 1 $ */ -public class AccessTokenResponse -{ - @JsonProperty("access_token") - protected String token; +public class AccessTokenResponse { + @JsonProperty("access_token") + protected String token; - @JsonProperty("expires_in") - protected long expiresIn; + @JsonProperty("expires_in") + protected long expiresIn; - @JsonProperty("refresh_token") - protected String refreshToken; + @JsonProperty("refresh_token") + protected String refreshToken; - @JsonProperty("token_type") - protected String tokenType; + @JsonProperty("token_type") + protected String tokenType; - public String getToken() - { - return token; - } + public String getToken() { + return token; + } - public void setToken(String token) - { - this.token = token; - } + public void setToken(String token) { + this.token = token; + } - public long getExpiresIn() - { - return expiresIn; - } + public long getExpiresIn() { + return expiresIn; + } - public void setExpiresIn(long expiresIn) - { - this.expiresIn = expiresIn; - } + public void setExpiresIn(long expiresIn) { + this.expiresIn = expiresIn; + } - public String getRefreshToken() - { - return refreshToken; - } + public String getRefreshToken() { + return refreshToken; + } - public void setRefreshToken(String refreshToken) - { - this.refreshToken = refreshToken; - } + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } - public String getTokenType() - { - return tokenType; - } + public String getTokenType() { + return tokenType; + } - public void setTokenType(String tokenType) - { - this.tokenType = tokenType; - } + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } } diff --git a/core/src/main/java/org/keycloak/representations/SkeletonKeyScope.java b/core/src/main/java/org/keycloak/representations/SkeletonKeyScope.java index 8f48d966c1..4076b9e1a9 100755 --- a/core/src/main/java/org/keycloak/representations/SkeletonKeyScope.java +++ b/core/src/main/java/org/keycloak/representations/SkeletonKeyScope.java @@ -8,6 +8,5 @@ import javax.ws.rs.core.MultivaluedHashMap; * @author Bill Burke * @version $Revision: 1 $ */ -public class SkeletonKeyScope extends MultivaluedHashMap -{ +public class SkeletonKeyScope extends MultivaluedHashMap { } diff --git a/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java b/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java index b73478180d..3458d707ef 100755 --- a/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java +++ b/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java @@ -13,190 +13,164 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class SkeletonKeyToken extends JsonWebToken -{ - public static class Access - { - @JsonProperty("roles") - protected Set roles; - @JsonProperty("verify_caller") - protected Boolean verifyCaller; +public class SkeletonKeyToken extends JsonWebToken { + public static class Access { + @JsonProperty("roles") + protected Set roles; + @JsonProperty("verify_caller") + protected Boolean verifyCaller; - public Set getRoles() - { - return roles; - } + public Set getRoles() { + return roles; + } - public Access roles(Set roles) - { - this.roles = roles; - return this; - } + public Access roles(Set roles) { + this.roles = roles; + return this; + } - @JsonIgnore - public boolean isUserInRole(String role) - { - if (roles == null) return false; - return roles.contains(role); - } + @JsonIgnore + public boolean isUserInRole(String role) { + if (roles == null) return false; + return roles.contains(role); + } - public Access addRole(String role) - { - if (roles == null) roles = new HashSet(); - roles.add(role); - return this; - } + public Access addRole(String role) { + if (roles == null) roles = new HashSet(); + roles.add(role); + return this; + } - public Boolean getVerifyCaller() - { - return verifyCaller; - } + public Boolean getVerifyCaller() { + return verifyCaller; + } - public Access verifyCaller(Boolean required) - { - this.verifyCaller = required; - return this; - } - } + public Access verifyCaller(Boolean required) { + this.verifyCaller = required; + return this; + } + } - @JsonProperty("issuedFor") - public String issuedFor; + @JsonProperty("issuedFor") + public String issuedFor; - @JsonProperty("trusted-certs") - protected Set trustedCertificates; + @JsonProperty("trusted-certs") + protected Set trustedCertificates; - @JsonProperty("realm_access") - protected Access realmAccess; + @JsonProperty("realm_access") + protected Access realmAccess; - @JsonProperty("resource_access") - protected Map resourceAccess = new HashMap(); + @JsonProperty("resource_access") + protected Map resourceAccess = new HashMap(); - public Map getResourceAccess() - { - return resourceAccess; - } + public Map getResourceAccess() { + return resourceAccess; + } - /** - * Does the realm require verifying the caller? - * - * @return - */ - @JsonIgnore - public boolean isVerifyCaller() - { - if (getRealmAccess() != null && getRealmAccess().getVerifyCaller() != null) return getRealmAccess().getVerifyCaller().booleanValue(); - return false; - } + /** + * Does the realm require verifying the caller? + * + * @return + */ + @JsonIgnore + public boolean isVerifyCaller() { + if (getRealmAccess() != null && getRealmAccess().getVerifyCaller() != null) + return getRealmAccess().getVerifyCaller().booleanValue(); + return false; + } - /** - * Does the resource override the requirement of verifying the caller? - * - * @param resource - * @return - */ - @JsonIgnore - public boolean isVerifyCaller(String resource) - { - Access access = getResourceAccess(resource); - if (access != null && access.getVerifyCaller() != null) return access.getVerifyCaller().booleanValue(); - return false; - } + /** + * Does the resource override the requirement of verifying the caller? + * + * @param resource + * @return + */ + @JsonIgnore + public boolean isVerifyCaller(String resource) { + Access access = getResourceAccess(resource); + if (access != null && access.getVerifyCaller() != null) return access.getVerifyCaller().booleanValue(); + return false; + } - @JsonIgnore - public Access getResourceAccess(String resource) - { - return resourceAccess.get(resource); - } + @JsonIgnore + public Access getResourceAccess(String resource) { + return resourceAccess.get(resource); + } - public Access addAccess(String service) - { - Access token = new Access(); - resourceAccess.put(service, token); - return token; - } + public Access addAccess(String service) { + Access token = new Access(); + resourceAccess.put(service, token); + return token; + } - @Override - public SkeletonKeyToken id(String id) - { - return (SkeletonKeyToken)super.id(id); - } + @Override + public SkeletonKeyToken id(String id) { + return (SkeletonKeyToken) super.id(id); + } - @Override - public SkeletonKeyToken expiration(long expiration) - { - return (SkeletonKeyToken)super.expiration(expiration); - } + @Override + public SkeletonKeyToken expiration(long expiration) { + return (SkeletonKeyToken) super.expiration(expiration); + } - @Override - public SkeletonKeyToken notBefore(long notBefore) - { - return (SkeletonKeyToken)super.notBefore(notBefore); - } + @Override + public SkeletonKeyToken notBefore(long notBefore) { + return (SkeletonKeyToken) super.notBefore(notBefore); + } - @Override - public SkeletonKeyToken issuedAt(long issuedAt) - { - return (SkeletonKeyToken)super.issuedAt(issuedAt); - } + @Override + public SkeletonKeyToken issuedAt(long issuedAt) { + return (SkeletonKeyToken) super.issuedAt(issuedAt); + } - @Override - public SkeletonKeyToken issuer(String issuer) - { - return (SkeletonKeyToken)super.issuer(issuer); - } + @Override + public SkeletonKeyToken issuer(String issuer) { + return (SkeletonKeyToken) super.issuer(issuer); + } - @Override - public SkeletonKeyToken audience(String audience) - { - return (SkeletonKeyToken)super.audience(audience); - } + @Override + public SkeletonKeyToken audience(String audience) { + return (SkeletonKeyToken) super.audience(audience); + } - @Override - public SkeletonKeyToken principal(String principal) - { - return (SkeletonKeyToken)super.principal(principal); - } + @Override + public SkeletonKeyToken principal(String principal) { + return (SkeletonKeyToken) super.principal(principal); + } - @Override - public SkeletonKeyToken type(String type) - { - return (SkeletonKeyToken)super.type(type); - } + @Override + public SkeletonKeyToken type(String type) { + return (SkeletonKeyToken) super.type(type); + } - public Access getRealmAccess() - { - return realmAccess; - } + public Access getRealmAccess() { + return realmAccess; + } - public void setRealmAccess(Access realmAccess) - { - this.realmAccess = realmAccess; - } + public void setRealmAccess(Access realmAccess) { + this.realmAccess = realmAccess; + } - public Set getTrustedCertificates() - { - return trustedCertificates; - } + public Set getTrustedCertificates() { + return trustedCertificates; + } - public void setTrustedCertificates(Set trustedCertificates) - { - this.trustedCertificates = trustedCertificates; - } + public void setTrustedCertificates(Set trustedCertificates) { + this.trustedCertificates = trustedCertificates; + } - /** - * OAuth client the token was issued for. - * - * @return - */ - public String getIssuedFor() - { - return issuedFor; - } + /** + * OAuth client the token was issued for. + * + * @return + */ + public String getIssuedFor() { + return issuedFor; + } - public SkeletonKeyToken issuedFor(String issuedFor) - { - this.issuedFor = issuedFor; - return this; - } + public SkeletonKeyToken issuedFor(String issuedFor) { + this.issuedFor = issuedFor; + return this; + } } diff --git a/core/src/main/java/org/keycloak/representations/idm/PublishedRealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/PublishedRealmRepresentation.java index 11050e964a..dfd08ad99d 100755 --- a/core/src/main/java/org/keycloak/representations/idm/PublishedRealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/PublishedRealmRepresentation.java @@ -13,137 +13,123 @@ import java.security.PublicKey; * @author Bill Burke * @version $Revision: 1 $ */ -public class PublishedRealmRepresentation -{ - protected String realm; - protected String self; +public class PublishedRealmRepresentation { + protected String realm; + protected String self; - @JsonProperty("public_key") - protected String publicKeyPem; + @JsonProperty("public_key") + protected String publicKeyPem; - @JsonProperty("authorization") - protected String authorizationUrl; + @JsonProperty("authorization") + protected String authorizationUrl; - @JsonProperty("codes") - protected String codeUrl; + @JsonProperty("codes") + protected String codeUrl; - @JsonProperty("grants") - protected String grantUrl; + @JsonProperty("grants") + protected String grantUrl; - @JsonProperty("identity-grants") - protected String identityGrantUrl; + @JsonProperty("identity-grants") + protected String identityGrantUrl; - @JsonIgnore - protected volatile transient PublicKey publicKey; + @JsonProperty("admin-role") + protected String adminRole; + + @JsonIgnore + protected volatile transient PublicKey publicKey; + + public String getAdminRole() { + return adminRole; + } + + public void setAdminRole(String adminRole) { + this.adminRole = adminRole; + } + + public String getRealm() { + return realm; + } + + public void setRealm(String realm) { + this.realm = realm; + } + + public String getSelf() { + return self; + } + + public void setSelf(String self) { + this.self = self; + } + + public String getPublicKeyPem() { + return publicKeyPem; + } + + public void setPublicKeyPem(String publicKeyPem) { + this.publicKeyPem = publicKeyPem; + this.publicKey = null; + } - public String getRealm() - { - return realm; - } + @JsonIgnore + public PublicKey getPublicKey() { + if (publicKey != null) return publicKey; + if (publicKeyPem != null) { + try { + publicKey = PemUtils.decodePublicKey(publicKeyPem); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + return publicKey; + } - public void setRealm(String realm) - { - this.realm = realm; - } - - public String getSelf() - { - return self; - } - - public void setSelf(String self) - { - this.self = self; - } - - public String getPublicKeyPem() - { - return publicKeyPem; - } - - public void setPublicKeyPem(String publicKeyPem) - { - this.publicKeyPem = publicKeyPem; - this.publicKey = null; - } - - - @JsonIgnore - public PublicKey getPublicKey() - { - if (publicKey != null) return publicKey; - if (publicKeyPem != null) - { - try - { - publicKey = PemUtils.decodePublicKey(publicKeyPem); - } - catch (Exception e) - { + @JsonIgnore + public void setPublicKey(PublicKey publicKey) { + this.publicKey = publicKey; + StringWriter writer = new StringWriter(); + PEMWriter pemWriter = new PEMWriter(writer); + try { + pemWriter.writeObject(publicKey); + pemWriter.flush(); + } catch (IOException e) { throw new RuntimeException(e); - } - } - return publicKey; - } - - @JsonIgnore - public void setPublicKey(PublicKey publicKey) - { - this.publicKey = publicKey; - StringWriter writer = new StringWriter(); - PEMWriter pemWriter = new PEMWriter(writer); - try - { - pemWriter.writeObject(publicKey); - pemWriter.flush(); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - String s = writer.toString(); - this.publicKeyPem = PemUtils.removeBeginEnd(s); - } + } + String s = writer.toString(); + this.publicKeyPem = PemUtils.removeBeginEnd(s); + } - public String getAuthorizationUrl() - { - return authorizationUrl; - } + public String getAuthorizationUrl() { + return authorizationUrl; + } - public void setAuthorizationUrl(String authorizationUrl) - { - this.authorizationUrl = authorizationUrl; - } + public void setAuthorizationUrl(String authorizationUrl) { + this.authorizationUrl = authorizationUrl; + } - public String getCodeUrl() - { - return codeUrl; - } + public String getCodeUrl() { + return codeUrl; + } - public void setCodeUrl(String codeUrl) - { - this.codeUrl = codeUrl; - } + public void setCodeUrl(String codeUrl) { + this.codeUrl = codeUrl; + } - public String getGrantUrl() - { - return grantUrl; - } + public String getGrantUrl() { + return grantUrl; + } - public void setGrantUrl(String grantUrl) - { - this.grantUrl = grantUrl; - } + public void setGrantUrl(String grantUrl) { + this.grantUrl = grantUrl; + } - public String getIdentityGrantUrl() - { - return identityGrantUrl; - } + public String getIdentityGrantUrl() { + return identityGrantUrl; + } - public void setIdentityGrantUrl(String identityGrantUrl) - { - this.identityGrantUrl = identityGrantUrl; - } + public void setIdentityGrantUrl(String identityGrantUrl) { + this.identityGrantUrl = identityGrantUrl; + } } diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index 166447cbdd..25e0b06dae 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -8,176 +8,147 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class RealmRepresentation -{ - protected String self; // link - protected String realm; - protected long tokenLifespan; - protected long accessCodeLifespan; - protected boolean enabled; - protected boolean sslNotRequired; - protected boolean cookieLoginAllowed; - protected Set roles; - protected List requiredCredentials; - protected List users; - protected List roleMappings; - protected List scopeMappings; - protected List resources; +public class RealmRepresentation { + protected String self; // link + protected String realm; + protected long tokenLifespan; + protected long accessCodeLifespan; + protected boolean enabled; + protected boolean sslNotRequired; + protected boolean cookieLoginAllowed; + protected Set roles; + protected List requiredCredentials; + protected List users; + protected List roleMappings; + protected List scopeMappings; + protected List resources; - public String getSelf() - { - return self; - } + public String getSelf() { + return self; + } - public void setSelf(String self) - { - this.self = self; - } + public void setSelf(String self) { + this.self = self; + } - public String getRealm() - { - return realm; - } + public String getRealm() { + return realm; + } - public void setRealm(String realm) - { - this.realm = realm; - } + public void setRealm(String realm) { + this.realm = realm; + } - public List getUsers() - { - return users; - } + public List getUsers() { + return users; + } - public List getResources() - { - return resources; - } + public List getResources() { + return resources; + } - public ResourceRepresentation resource(String name) - { - ResourceRepresentation resource = new ResourceRepresentation(); - if (resources == null) resources = new ArrayList(); - resources.add(resource); - resource.setName(name); - return resource; - } + public ResourceRepresentation resource(String name) { + ResourceRepresentation resource = new ResourceRepresentation(); + if (resources == null) resources = new ArrayList(); + resources.add(resource); + resource.setName(name); + return resource; + } - public void setUsers(List users) - { - this.users = users; - } + public void setUsers(List users) { + this.users = users; + } - public UserRepresentation user(String username) - { - UserRepresentation user = new UserRepresentation(); - user.setUsername(username); - if (users == null) users = new ArrayList(); - users.add(user); - return user; - } + public UserRepresentation user(String username) { + UserRepresentation user = new UserRepresentation(); + user.setUsername(username); + if (users == null) users = new ArrayList(); + users.add(user); + return user; + } - public void setResources(List resources) - { - this.resources = resources; - } + public void setResources(List resources) { + this.resources = resources; + } - public boolean isEnabled() - { - return enabled; - } + public boolean isEnabled() { + return enabled; + } - public void setEnabled(boolean enabled) - { - this.enabled = enabled; - } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } - public boolean isSslNotRequired() - { - return sslNotRequired; - } + public boolean isSslNotRequired() { + return sslNotRequired; + } - public void setSslNotRequired(boolean sslNotRequired) - { - this.sslNotRequired = sslNotRequired; - } + public void setSslNotRequired(boolean sslNotRequired) { + this.sslNotRequired = sslNotRequired; + } - public boolean isCookieLoginAllowed() - { - return cookieLoginAllowed; - } + public boolean isCookieLoginAllowed() { + return cookieLoginAllowed; + } - public void setCookieLoginAllowed(boolean cookieLoginAllowed) - { - this.cookieLoginAllowed = cookieLoginAllowed; - } + public void setCookieLoginAllowed(boolean cookieLoginAllowed) { + this.cookieLoginAllowed = cookieLoginAllowed; + } - public long getTokenLifespan() - { - return tokenLifespan; - } + public long getTokenLifespan() { + return tokenLifespan; + } - public void setTokenLifespan(long tokenLifespan) - { - this.tokenLifespan = tokenLifespan; - } + public void setTokenLifespan(long tokenLifespan) { + this.tokenLifespan = tokenLifespan; + } - public List getRoleMappings() - { - return roleMappings; - } + public List getRoleMappings() { + return roleMappings; + } - public RoleMappingRepresentation roleMapping(String username) - { - RoleMappingRepresentation mapping = new RoleMappingRepresentation(); - mapping.setUsername(username); - if (roleMappings == null) roleMappings = new ArrayList(); - roleMappings.add(mapping); - return mapping; - } + public RoleMappingRepresentation roleMapping(String username) { + RoleMappingRepresentation mapping = new RoleMappingRepresentation(); + mapping.setUsername(username); + if (roleMappings == null) roleMappings = new ArrayList(); + roleMappings.add(mapping); + return mapping; + } - public List getScopeMappings() - { - return scopeMappings; - } + public List getScopeMappings() { + return scopeMappings; + } - public ScopeMappingRepresentation scopeMapping(String username) - { - ScopeMappingRepresentation mapping = new ScopeMappingRepresentation(); - mapping.setUsername(username); - if (scopeMappings == null) scopeMappings = new ArrayList(); - scopeMappings.add(mapping); - return mapping; - } + public ScopeMappingRepresentation scopeMapping(String username) { + ScopeMappingRepresentation mapping = new ScopeMappingRepresentation(); + mapping.setUsername(username); + if (scopeMappings == null) scopeMappings = new ArrayList(); + scopeMappings.add(mapping); + return mapping; + } - public List getRequiredCredentials() - { - return requiredCredentials; - } + public List getRequiredCredentials() { + return requiredCredentials; + } - public void setRequiredCredentials(List requiredCredentials) - { - this.requiredCredentials = requiredCredentials; - } + public void setRequiredCredentials(List requiredCredentials) { + this.requiredCredentials = requiredCredentials; + } - public long getAccessCodeLifespan() - { - return accessCodeLifespan; - } + public long getAccessCodeLifespan() { + return accessCodeLifespan; + } - public void setAccessCodeLifespan(long accessCodeLifespan) - { - this.accessCodeLifespan = accessCodeLifespan; - } + public void setAccessCodeLifespan(long accessCodeLifespan) { + this.accessCodeLifespan = accessCodeLifespan; + } - public Set getRoles() - { - return roles; - } + public Set getRoles() { + return roles; + } - public void setRoles(Set roles) - { - this.roles = roles; - } + public void setRoles(Set roles) { + this.roles = roles; + } } diff --git a/core/src/main/java/org/keycloak/representations/idm/RequiredCredentialRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RequiredCredentialRepresentation.java index 763e29ca80..7a9eaecb13 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RequiredCredentialRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RequiredCredentialRepresentation.java @@ -4,43 +4,36 @@ package org.keycloak.representations.idm; * @author Bill Burke * @version $Revision: 1 $ */ -public class RequiredCredentialRepresentation -{ - public static final String PASSWORD = "Password"; - public static final String TOTP = "TOTP"; - public static final String CLIENT_CERT = "CLIENT_CERT"; - public static final String CALLER_PRINCIPAL = "CALLER_PRINCIPAL"; - protected String type; - protected boolean input; - protected boolean secret; +public class RequiredCredentialRepresentation { + public static final String PASSWORD = "Password"; + public static final String TOTP = "TOTP"; + public static final String CLIENT_CERT = "CLIENT_CERT"; + public static final String CALLER_PRINCIPAL = "CALLER_PRINCIPAL"; + protected String type; + protected boolean input; + protected boolean secret; - public String getType() - { - return type; - } + public String getType() { + return type; + } - public void setType(String type) - { - this.type = type; - } + public void setType(String type) { + this.type = type; + } - public boolean isInput() - { - return input; - } + public boolean isInput() { + return input; + } - public void setInput(boolean input) - { - this.input = input; - } + public void setInput(boolean input) { + this.input = input; + } - public boolean isSecret() - { - return secret; - } + public boolean isSecret() { + return secret; + } - public void setSecret(boolean secret) - { - this.secret = secret; - } + public void setSecret(boolean secret) { + this.secret = secret; + } } 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 d3d2c5f1d8..529ed35a29 100755 --- a/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java @@ -6,92 +6,78 @@ import java.util.List; import java.util.Set; /** -* @author Bill Burke -* @version $Revision: 1 $ -*/ -public class ResourceRepresentation -{ - protected String self; // link - protected String name; - protected boolean surrogateAuthRequired; - protected Set roles; - protected List roleMappings; - protected List scopeMappings; + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class ResourceRepresentation { + protected String self; // link + protected String name; + protected boolean surrogateAuthRequired; + protected Set roles; + protected List roleMappings; + protected List scopeMappings; - public String getSelf() - { - return self; - } + public String getSelf() { + return self; + } - public void setSelf(String self) - { - this.self = self; - } + public void setSelf(String self) { + this.self = self; + } - public String getName() - { - return name; - } + public String getName() { + return name; + } - public void setName(String name) - { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public boolean isSurrogateAuthRequired() - { - return surrogateAuthRequired; - } + public boolean isSurrogateAuthRequired() { + return surrogateAuthRequired; + } - public void setSurrogateAuthRequired(boolean surrogateAuthRequired) - { - this.surrogateAuthRequired = surrogateAuthRequired; - } + public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { + this.surrogateAuthRequired = surrogateAuthRequired; + } - public Set getRoles() - { - return roles; - } + public Set getRoles() { + return roles; + } - public void setRoles(Set roles) - { - this.roles = roles; - } + public void setRoles(Set roles) { + this.roles = roles; + } - public ResourceRepresentation role(String role) - { - if (this.roles == null) this.roles = new HashSet(); - this.roles.add(role); - return this; - } + public ResourceRepresentation role(String role) { + if (this.roles == null) this.roles = new HashSet(); + this.roles.add(role); + return this; + } - public List getRoleMappings() - { - return roleMappings; - } + public List getRoleMappings() { + return roleMappings; + } - public RoleMappingRepresentation roleMapping(String username) - { - RoleMappingRepresentation mapping = new RoleMappingRepresentation(); - mapping.setUsername(username); - if (roleMappings == null) roleMappings = new ArrayList(); - roleMappings.add(mapping); - return mapping; - } + public RoleMappingRepresentation roleMapping(String username) { + RoleMappingRepresentation mapping = new RoleMappingRepresentation(); + mapping.setUsername(username); + if (roleMappings == null) roleMappings = new ArrayList(); + roleMappings.add(mapping); + return mapping; + } - public List getScopeMappings() - { - return scopeMappings; - } + public List getScopeMappings() { + return scopeMappings; + } - public ScopeMappingRepresentation scopeMapping(String username) - { - ScopeMappingRepresentation mapping = new ScopeMappingRepresentation(); - mapping.setUsername(username); - if (scopeMappings == null) scopeMappings = new ArrayList(); - scopeMappings.add(mapping); - return mapping; - } + public ScopeMappingRepresentation scopeMapping(String username) { + ScopeMappingRepresentation mapping = new ScopeMappingRepresentation(); + mapping.setUsername(username); + if (scopeMappings == null) scopeMappings = new ArrayList(); + scopeMappings.add(mapping); + return mapping; + } } diff --git a/core/src/main/java/org/keycloak/representations/idm/RoleMappingRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RoleMappingRepresentation.java index aca2206581..dea66d0fa8 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RoleMappingRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RoleMappingRepresentation.java @@ -4,52 +4,42 @@ import java.util.HashSet; import java.util.Set; /** - * - * * @author Bill Burke * @version $Revision: 1 $ */ -public class RoleMappingRepresentation -{ - protected String self; // link - protected String username; - protected Set roles; +public class RoleMappingRepresentation { + protected String self; // link + protected String username; + protected Set roles; - public String getSelf() - { - return self; - } + public String getSelf() { + return self; + } - public void setSelf(String self) - { - this.self = self; - } + public void setSelf(String self) { + this.self = self; + } - public String getUsername() - { - return username; - } + public String getUsername() { + return username; + } - public void setUsername(String username) - { - this.username = username; - } + public void setUsername(String username) { + this.username = username; + } - public Set getRoles() - { - return roles; - } + public Set getRoles() { + return roles; + } - public void setRoles(Set roles) - { - this.roles = roles; - } + public void setRoles(Set roles) { + this.roles = roles; + } - public RoleMappingRepresentation role(String role) - { - if (this.roles == null) this.roles = new HashSet(); - this.roles.add(role); - return this; - } + public RoleMappingRepresentation role(String role) { + if (this.roles == null) this.roles = new HashSet(); + this.roles.add(role); + return this; + } } diff --git a/core/src/main/java/org/keycloak/representations/idm/ScopeMappingRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ScopeMappingRepresentation.java index b86e2e2239..b65196f3b3 100755 --- a/core/src/main/java/org/keycloak/representations/idm/ScopeMappingRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/ScopeMappingRepresentation.java @@ -4,52 +4,42 @@ import java.util.HashSet; import java.util.Set; /** - * - * * @author Bill Burke * @version $Revision: 1 $ */ -public class ScopeMappingRepresentation -{ - protected String self; // link - protected String username; - protected Set roles; +public class ScopeMappingRepresentation { + protected String self; // link + protected String username; + protected Set roles; - public String getSelf() - { - return self; - } + public String getSelf() { + return self; + } - public void setSelf(String self) - { - this.self = self; - } + public void setSelf(String self) { + this.self = self; + } - public String getUsername() - { - return username; - } + public String getUsername() { + return username; + } - public void setUsername(String username) - { - this.username = username; - } + public void setUsername(String username) { + this.username = username; + } - public Set getRoles() - { - return roles; - } + public Set getRoles() { + return roles; + } - public void setRoles(Set roles) - { - this.roles = roles; - } + public void setRoles(Set roles) { + this.roles = roles; + } - public ScopeMappingRepresentation role(String role) - { - if (this.roles == null) this.roles = new HashSet(); - this.roles.add(role); - return this; - } + public ScopeMappingRepresentation role(String role) { + if (this.roles == null) this.roles = new HashSet(); + this.roles.add(role); + return this; + } } 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 4bd0de41e1..96d2b72d43 100755 --- a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java @@ -6,119 +6,99 @@ import java.util.List; import java.util.Map; /** -* @author Bill Burke -* @version $Revision: 1 $ -*/ -public class UserRepresentation -{ - public static class Credential - { - protected String type; - protected String value; - protected boolean hashed; + * @author Bill Burke + * @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 String getType() { + return type; + } - public void setType(String type) - { - this.type = type; - } + public void setType(String type) { + this.type = type; + } - public String getValue() - { - return value; - } + public String getValue() { + return value; + } - public void setValue(String value) - { - this.value = value; - } + public void setValue(String value) { + this.value = value; + } - public boolean isHashed() - { - return hashed; - } + public boolean isHashed() { + return hashed; + } - public void setHashed(boolean hashed) - { - this.hashed = hashed; - } - } + public void setHashed(boolean hashed) { + this.hashed = hashed; + } + } - protected String self; // link - protected String username; - protected boolean enabled; - protected Map attributes; - protected List credentials; + protected String self; // link + protected String username; + protected boolean enabled; + protected Map attributes; + protected List credentials; - public String getSelf() - { - return self; - } + public String getSelf() { + return self; + } - public void setSelf(String self) - { - this.self = self; - } + public void setSelf(String self) { + this.self = self; + } - public String getUsername() - { - return username; - } + public String getUsername() { + return username; + } - public void setUsername(String username) - { - this.username = username; - } + public void setUsername(String username) { + this.username = username; + } - public Map getAttributes() - { - return attributes; - } + public Map getAttributes() { + return attributes; + } - public void setAttributes(Map attributes) - { - this.attributes = attributes; - } + public void setAttributes(Map attributes) { + this.attributes = attributes; + } - public List getCredentials() - { - return credentials; - } + public List getCredentials() { + return credentials; + } - public void setCredentials(List credentials) - { - this.credentials = credentials; - } + public void setCredentials(List credentials) { + this.credentials = credentials; + } - public UserRepresentation attribute(String name, String value) - { - if (this.attributes == null) attributes = new HashMap(); - attributes.put(name, value); - return this; - } + public UserRepresentation attribute(String name, String value) { + if (this.attributes == null) attributes = new HashMap(); + attributes.put(name, value); + return this; + } - public UserRepresentation credential(String type, String value, boolean hashed) - { - if (this.credentials == null) credentials = new ArrayList(); - Credential cred = new Credential(); - cred.setType(type); - cred.setValue(value); - cred.setHashed(hashed); - credentials.add( cred); - return this; - } + public UserRepresentation credential(String type, String value, boolean hashed) { + if (this.credentials == null) credentials = new ArrayList(); + Credential cred = new Credential(); + cred.setType(type); + cred.setValue(value); + cred.setHashed(hashed); + credentials.add(cred); + return this; + } - public boolean isEnabled() - { - return enabled; - } + public boolean isEnabled() { + return enabled; + } - public void setEnabled(boolean enabled) - { - this.enabled = enabled; - } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } } diff --git a/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java b/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java index 27d4372106..3ba72240d2 100755 --- a/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java +++ b/core/src/main/java/org/keycloak/servlet/ServletOAuthClient.java @@ -1,8 +1,8 @@ package org.keycloak.servlet; import org.jboss.resteasy.plugins.server.servlet.ServletUtil; -import org.keycloak.AbstractOAuthClient; import org.jboss.resteasy.spi.ResteasyUriInfo; +import org.keycloak.AbstractOAuthClient; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -17,111 +17,100 @@ import java.net.URI; * @author Bill Burke * @version $Revision: 1 $ */ -public class ServletOAuthClient extends AbstractOAuthClient -{ - /** - * Start the process of obtaining an access token by redirecting the browser - * to the authentication server - * - * - * - * @param relativePath path relative to context root you want auth server to redirect back to - * @param request - * @param response - * @throws IOException - */ - public void redirectRelative(String relativePath, HttpServletRequest request, HttpServletResponse response) throws IOException - { - ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null); - String redirect = uriInfo.getBaseUriBuilder().path(relativePath).toTemplate(); - redirect(redirect, request, response); - } +public class ServletOAuthClient extends AbstractOAuthClient { + /** + * Start the process of obtaining an access token by redirecting the browser + * to the authentication server + * + * @param relativePath path relative to context root you want auth server to redirect back to + * @param request + * @param response + * @throws IOException + */ + public void redirectRelative(String relativePath, HttpServletRequest request, HttpServletResponse response) throws IOException { + ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null); + String redirect = uriInfo.getBaseUriBuilder().path(relativePath).toTemplate(); + redirect(redirect, request, response); + } - /** - * Start the process of obtaining an access token by redirecting the browser - * to the authentication server - * - * @param redirectUri full URI you want auth server to redirect back to - * @param request - * @param response - * @throws IOException - */ - public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException - { - String state = getStateCode(); + /** + * Start the process of obtaining an access token by redirecting the browser + * to the authentication server + * + * @param redirectUri full URI you want auth server to redirect back to + * @param request + * @param response + * @throws IOException + */ + public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException { + String state = getStateCode(); - URI url = UriBuilder.fromUri(authUrl) - .queryParam("client_id", clientId) - .queryParam("redirect_uri", redirectUri) - .queryParam("state", state) - .build(); - String cookiePath = request.getContextPath(); - if (cookiePath.equals("")) cookiePath = "/"; + URI url = UriBuilder.fromUri(authUrl) + .queryParam("client_id", clientId) + .queryParam("redirect_uri", redirectUri) + .queryParam("state", state) + .build(); + String cookiePath = request.getContextPath(); + if (cookiePath.equals("")) cookiePath = "/"; - Cookie cookie = new Cookie(stateCookieName, state); - cookie.setSecure(true); - cookie.setPath(cookiePath); - response.addCookie(cookie); - response.sendRedirect(url.toString()); - } + Cookie cookie = new Cookie(stateCookieName, state); + cookie.setSecure(true); + cookie.setPath(cookiePath); + response.addCookie(cookie); + response.sendRedirect(url.toString()); + } - protected String getCookieValue(String name, HttpServletRequest request) - { - if (request.getCookies() == null) return null; + protected String getCookieValue(String name, HttpServletRequest request) { + if (request.getCookies() == null) return null; - for (Cookie cookie : request.getCookies()) - { - if (cookie.getName().equals(name)) return cookie.getValue(); - } - return null; - } + for (Cookie cookie : request.getCookies()) { + if (cookie.getName().equals(name)) return cookie.getValue(); + } + return null; + } - protected String getCode(HttpServletRequest request) - { - String query = request.getQueryString(); - if (query == null) return null; - String[] params = query.split("&"); - for (String param : params) - { - int eq = param.indexOf('='); - if (eq == -1) continue; - String name = param.substring(0, eq); - if (!name.equals("code")) continue; - return param.substring(eq + 1); - } - return null; - } + protected String getCode(HttpServletRequest request) { + String query = request.getQueryString(); + if (query == null) return null; + String[] params = query.split("&"); + for (String param : params) { + int eq = param.indexOf('='); + if (eq == -1) continue; + String name = param.substring(0, eq); + if (!name.equals("code")) continue; + return param.substring(eq + 1); + } + return null; + } - /** - * Obtain the code parameter from the url after being redirected back from the auth-server. Then - * do an authenticated request back to the auth-server to turn the access code into an access token. - * - * @param request - * @return - * @throws BadRequestException - * @throws InternalServerErrorException - */ - public String getBearerToken(HttpServletRequest request) throws BadRequestException, InternalServerErrorException - { - String error = request.getParameter("error"); - if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error)); - String redirectUri = request.getRequestURL().append("?").append(request.getQueryString()).toString(); - String stateCookie = getCookieValue(stateCookieName, request); - if (stateCookie == null) throw new BadRequestException(new Exception("state cookie not set")); - // we can call get parameter as this should be a redirect - String state = request.getParameter("state"); - String code = request.getParameter("code"); + /** + * Obtain the code parameter from the url after being redirected back from the auth-server. Then + * do an authenticated request back to the auth-server to turn the access code into an access token. + * + * @param request + * @return + * @throws BadRequestException + * @throws InternalServerErrorException + */ + public String getBearerToken(HttpServletRequest request) throws BadRequestException, InternalServerErrorException { + String error = request.getParameter("error"); + if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error)); + String redirectUri = request.getRequestURL().append("?").append(request.getQueryString()).toString(); + String stateCookie = getCookieValue(stateCookieName, request); + if (stateCookie == null) throw new BadRequestException(new Exception("state cookie not set")); + // we can call get parameter as this should be a redirect + String state = request.getParameter("state"); + String code = request.getParameter("code"); - if (state == null) throw new BadRequestException(new Exception("state parameter was null")); - if (!state.equals(stateCookie)) - { - throw new BadRequestException(new Exception("state parameter invalid")); - } - if (code == null) throw new BadRequestException(new Exception("code parameter was null")); - return resolveBearerToken(redirectUri, code); - } + if (state == null) throw new BadRequestException(new Exception("state parameter was null")); + if (!state.equals(stateCookie)) { + throw new BadRequestException(new Exception("state parameter invalid")); + } + if (code == null) throw new BadRequestException(new Exception("code parameter was null")); + return resolveBearerToken(redirectUri, code); + } } diff --git a/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml index e551128261..8caa96f6a0 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml +++ b/examples/as7-eap-demo/server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -2,9 +2,6 @@ - diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/Actions.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/Actions.java index 65c9ddbc9d..13189fc21b 100755 --- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/Actions.java +++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/Actions.java @@ -4,11 +4,10 @@ package org.keycloak.adapters.as7; * @author Bill Burke * @version $Revision: 1 $ */ -public interface Actions -{ - public static final String J_OAUTH_ADMIN_FORCED_LOGOUT = "j_oauth_admin_forced_logout"; - public static final String J_OAUTH_LOGOUT = "j_oauth_logout"; - public static final String J_OAUTH_RESOLVE_ACCESS_CODE = "j_oauth_resolve_access_code"; - public static final String J_OAUTH_REMOTE_LOGOUT = "j_oauth_remote_logout"; - public static final String J_OAUTH_TOKEN_GRANT = "j_oauth_token_grant"; +public interface Actions { + public static final String J_OAUTH_ADMIN_FORCED_LOGOUT = "j_oauth_admin_forced_logout"; + public static final String J_OAUTH_LOGOUT = "j_oauth_logout"; + public static final String J_OAUTH_RESOLVE_ACCESS_CODE = "j_oauth_resolve_access_code"; + public static final String J_OAUTH_REMOTE_LOGOUT = "j_oauth_remote_logout"; + public static final String J_OAUTH_TOKEN_GRANT = "j_oauth_token_grant"; } 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 2f7e95cc91..2fc961d18b 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 @@ -10,10 +10,10 @@ import org.apache.catalina.connector.Response; import org.apache.catalina.core.StandardContext; import org.apache.catalina.deploy.LoginConfig; import org.jboss.logging.Logger; +import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.ResourceMetadata; import org.keycloak.adapters.as7.config.ManagedResourceConfig; import org.keycloak.adapters.as7.config.ManagedResourceConfigLoader; -import org.jboss.resteasy.spi.ResteasyProviderFactory; import javax.security.auth.login.LoginException; import javax.servlet.ServletException; @@ -27,61 +27,49 @@ import java.io.IOException; * @author Bill Burke * @version $Revision: 1 $ */ -public class BearerTokenAuthenticatorValve extends AuthenticatorBase implements LifecycleListener -{ - private static final Logger log = Logger.getLogger(BearerTokenAuthenticatorValve.class); - protected ManagedResourceConfig remoteSkeletonKeyConfig; - protected ResourceMetadata resourceMetadata; +public class BearerTokenAuthenticatorValve extends AuthenticatorBase implements LifecycleListener { + private static final Logger log = Logger.getLogger(BearerTokenAuthenticatorValve.class); + protected ManagedResourceConfig remoteSkeletonKeyConfig; + protected ResourceMetadata resourceMetadata; - @Override - public void start() throws LifecycleException - { - super.start(); - StandardContext standardContext = (StandardContext)context; - standardContext.addLifecycleListener(this); - } + @Override + public void start() throws LifecycleException { + super.start(); + StandardContext standardContext = (StandardContext) context; + standardContext.addLifecycleListener(this); + } - @Override - public void lifecycleEvent(LifecycleEvent event) - { - if (event.getType() == Lifecycle.AFTER_START_EVENT) init(); - } + @Override + public void lifecycleEvent(LifecycleEvent event) { + if (event.getType() == Lifecycle.AFTER_START_EVENT) init(); + } - protected void init() - { - ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context); - resourceMetadata = managedResourceConfigLoader.getResourceMetadata(); - remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig(); - } + protected void init() { + ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context); + resourceMetadata = managedResourceConfigLoader.getResourceMetadata(); + remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig(); + managedResourceConfigLoader.init(false); + } - @Override - public void invoke(Request request, Response response) throws IOException, ServletException - { - try - { - super.invoke(request, response); - } - finally - { - ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession - } - } + @Override + public void invoke(Request request, Response response) throws IOException, ServletException { + try { + super.invoke(request, response); + } finally { + ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession + } + } - @Override - protected boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException - { - try - { - CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, !remoteSkeletonKeyConfig.isCancelPropagation(), true); - if (bearer.login(request, response)) - { - return true; - } - return false; - } - catch (LoginException e) - { - } - return false; - } + @Override + protected boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException { + try { + CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, !remoteSkeletonKeyConfig.isCancelPropagation(), true); + if (bearer.login(request, response)) { + return true; + } + return false; + } catch (LoginException e) { + } + return false; + } } 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 7d14c1d307..835296b97e 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 @@ -2,13 +2,13 @@ package org.keycloak.adapters.as7; import org.apache.catalina.connector.Request; import org.jboss.logging.Logger; +import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.RSATokenVerifier; import org.keycloak.ResourceMetadata; import org.keycloak.SkeletonKeyPrincipal; import org.keycloak.SkeletonKeySession; import org.keycloak.VerificationException; import org.keycloak.representations.SkeletonKeyToken; -import org.jboss.resteasy.spi.ResteasyProviderFactory; import javax.security.auth.login.LoginException; import javax.servlet.http.HttpServletResponse; @@ -21,143 +21,116 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class CatalinaBearerTokenAuthenticator -{ - protected ResourceMetadata resourceMetadata; - protected boolean challenge; - protected Logger log = Logger.getLogger(CatalinaBearerTokenAuthenticator.class); - protected String tokenString; - protected SkeletonKeyToken token; - private Principal principal; - protected boolean propagateToken; +public class CatalinaBearerTokenAuthenticator { + protected ResourceMetadata resourceMetadata; + protected boolean challenge; + protected Logger log = Logger.getLogger(CatalinaBearerTokenAuthenticator.class); + protected String tokenString; + protected SkeletonKeyToken token; + private Principal principal; + protected boolean propagateToken; - public CatalinaBearerTokenAuthenticator(ResourceMetadata resourceMetadata, boolean propagateToken, boolean challenge) - { - this.resourceMetadata = resourceMetadata; - this.challenge = challenge; - this.propagateToken = propagateToken; - } + public CatalinaBearerTokenAuthenticator(ResourceMetadata resourceMetadata, boolean propagateToken, boolean challenge) { + this.resourceMetadata = resourceMetadata; + this.challenge = challenge; + this.propagateToken = propagateToken; + } - public ResourceMetadata getResourceMetadata() - { - return resourceMetadata; - } + public ResourceMetadata getResourceMetadata() { + return resourceMetadata; + } - public String getTokenString() - { - return tokenString; - } + public String getTokenString() { + return tokenString; + } - public SkeletonKeyToken getToken() - { - return token; - } + public SkeletonKeyToken getToken() { + return token; + } - public Principal getPrincipal() - { - return principal; - } + public Principal getPrincipal() { + return principal; + } - public boolean login(Request request, HttpServletResponse response) throws LoginException, IOException - { - String authHeader = request.getHeader("Authorization"); - if (authHeader == null) - { - if (challenge) - { - challengeResponse(response, null, null); - return false; - } - else - { - return false; - } - } + public boolean login(Request request, HttpServletResponse response) throws LoginException, IOException { + String authHeader = request.getHeader("Authorization"); + if (authHeader == null) { + if (challenge) { + challengeResponse(response, null, null); + return false; + } else { + return false; + } + } - String[] split = authHeader.trim().split("\\s+"); - if (split == null || split.length != 2) challengeResponse(response, null, null); - if (!split[0].equalsIgnoreCase("Bearer")) challengeResponse(response, null, null); + String[] split = authHeader.trim().split("\\s+"); + if (split == null || split.length != 2) challengeResponse(response, null, null); + if (!split[0].equalsIgnoreCase("Bearer")) challengeResponse(response, null, null); - tokenString = split[1]; + tokenString = split[1]; - try - { - token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata); - } - catch (VerificationException e) - { - log.error("Failed to verify token", e); - challengeResponse(response, "invalid_token", e.getMessage()); - } - boolean verifyCaller = false; - Set roles = null; - if (resourceMetadata.getResourceName() != null) - { - SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName()); - if (access != null) roles = access.getRoles(); - verifyCaller = token.isVerifyCaller(resourceMetadata.getResourceName()); - } - else - { - verifyCaller = token.isVerifyCaller(); - SkeletonKeyToken.Access access = token.getRealmAccess(); - if (access != null) roles = access.getRoles(); - } - String surrogate = null; - if (verifyCaller) - { - if (token.getTrustedCertificates() == null || token.getTrustedCertificates().size() == 0) - { - response.sendError(400); - throw new LoginException("No trusted certificates in token"); - } - // for now, we just make sure JBoss Web did two-way SSL - // assume JBoss Web verifies the client cert - X509Certificate[] chain = request.getCertificateChain(); - if (chain == null || chain.length == 0) - { - response.sendError(400); - throw new LoginException("No certificates provided by jboss web to verify the caller"); - } - surrogate = chain[0].getSubjectX500Principal().getName(); - } - SkeletonKeyPrincipal skeletonKeyPrincipal = new SkeletonKeyPrincipal(token.getPrincipal(), surrogate); - principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skeletonKeyPrincipal, roles); - request.setUserPrincipal(principal); - request.setAuthType("OAUTH_BEARER"); - if (propagateToken) - { - SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata); - request.setAttribute(SkeletonKeySession.class.getName(), skSession); - ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); - } + try { + token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata); + } catch (VerificationException e) { + log.error("Failed to verify token", e); + challengeResponse(response, "invalid_token", e.getMessage()); + } + boolean verifyCaller = false; + Set roles = null; + if (resourceMetadata.getResourceName() != null) { + SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName()); + if (access != null) roles = access.getRoles(); + verifyCaller = token.isVerifyCaller(resourceMetadata.getResourceName()); + } else { + verifyCaller = token.isVerifyCaller(); + SkeletonKeyToken.Access access = token.getRealmAccess(); + if (access != null) roles = access.getRoles(); + } + String surrogate = null; + if (verifyCaller) { + if (token.getTrustedCertificates() == null || token.getTrustedCertificates().size() == 0) { + response.sendError(400); + throw new LoginException("No trusted certificates in token"); + } + // for now, we just make sure JBoss Web did two-way SSL + // assume JBoss Web verifies the client cert + X509Certificate[] chain = request.getCertificateChain(); + if (chain == null || chain.length == 0) { + response.sendError(400); + throw new LoginException("No certificates provided by jboss web to verify the caller"); + } + surrogate = chain[0].getSubjectX500Principal().getName(); + } + SkeletonKeyPrincipal skeletonKeyPrincipal = new SkeletonKeyPrincipal(token.getPrincipal(), surrogate); + principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skeletonKeyPrincipal, roles); + request.setUserPrincipal(principal); + request.setAuthType("OAUTH_BEARER"); + if (propagateToken) { + SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata); + request.setAttribute(SkeletonKeySession.class.getName(), skSession); + ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); + } - return true; - } + return true; + } - protected void challengeResponse(HttpServletResponse response, String error, String description) throws LoginException - { - StringBuilder header = new StringBuilder("Bearer realm=\""); - header.append(resourceMetadata.getRealm()).append("\""); - if (error != null) - { - header.append(", error=\"").append(error).append("\""); - } - if (description != null) - { - header.append(", error_description=\"").append(description).append("\""); - } - response.setHeader("WWW-Authenticate", header.toString()); - try - { - response.sendError(401); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - throw new LoginException("Challenged"); - } + protected void challengeResponse(HttpServletResponse response, String error, String description) throws LoginException { + StringBuilder header = new StringBuilder("Bearer realm=\""); + header.append(resourceMetadata.getRealm()).append("\""); + if (error != null) { + header.append(", error=\"").append(error).append("\""); + } + if (description != null) { + header.append(", error_description=\"").append(description).append("\""); + } + response.setHeader("WWW-Authenticate", header.toString()); + try { + response.sendError(401); + } catch (IOException e) { + throw new RuntimeException(e); + } + throw new LoginException("Challenged"); + } } diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java index bf783bd295..b939d19f69 100755 --- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java +++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java @@ -24,115 +24,105 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class CatalinaSecurityContextHelper -{ - public GenericPrincipal createPrincipal(Realm realm, Principal identity, Collection roleSet) - { - Subject subject = new Subject(); - String credentials = ""; - Set principals = subject.getPrincipals(); - principals.add(identity); - Group[] roleSets = getRoleSets(roleSet); - for(int g = 0; g < roleSets.length; g ++) - { - Group group = roleSets[g]; - String name = group.getName(); - Group subjectGroup = createGroup(name, principals); - if( subjectGroup instanceof NestableGroup) - { - /* A NestableGroup only allows Groups to be added to it so we - need to add a SimpleGroup to subjectRoles to contain the roles - */ - SimpleGroup tmp = new SimpleGroup("Roles"); - subjectGroup.addMember(tmp); - subjectGroup = tmp; - } - // Copy the group members to the Subject group - Enumeration members = group.members(); - while( members.hasMoreElements() ) - { - Principal role = (Principal) members.nextElement(); - subjectGroup.addMember(role); - } - } - // add the CallerPrincipal group if none has been added in getRoleSets - Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP); - callerGroup.addMember(identity); - principals.add(callerGroup); - SecurityContext sc = SecurityContextAssociation.getSecurityContext(); - Principal userPrincipal = getPrincipal(subject); - sc.getUtil().createSubjectInfo(userPrincipal, credentials, subject); - List rolesAsStringList = new ArrayList(); - rolesAsStringList.addAll(roleSet); - return new JBossGenericPrincipal(realm, userPrincipal.getName(), null, rolesAsStringList, - userPrincipal, null, credentials, null, subject); - - } - /** - * Get the Principal given the authenticated Subject. Currently the first principal that is not of type {@code Group} is - * considered or the single principal inside the CallerPrincipal group. - * - * @param subject - * @return the authenticated principal - */ - protected Principal getPrincipal(Subject subject) { - Principal principal = null; - Principal callerPrincipal = null; - if (subject != null) { - Set principals = subject.getPrincipals(); - if (principals != null && !principals.isEmpty()) { - for (Principal p : principals) { - if (!(p instanceof Group) && principal == null) { - principal = p; - } - if (p instanceof Group) { - Group g = Group.class.cast(p); - if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) { - Enumeration e = g.members(); - if (e.hasMoreElements()) - callerPrincipal = e.nextElement(); - } - } +public class CatalinaSecurityContextHelper { + public GenericPrincipal createPrincipal(Realm realm, Principal identity, Collection roleSet) { + Subject subject = new Subject(); + String credentials = ""; + Set principals = subject.getPrincipals(); + principals.add(identity); + Group[] roleSets = getRoleSets(roleSet); + for (int g = 0; g < roleSets.length; g++) { + Group group = roleSets[g]; + String name = group.getName(); + Group subjectGroup = createGroup(name, principals); + if (subjectGroup instanceof NestableGroup) { + /* A NestableGroup only allows Groups to be added to it so we + need to add a SimpleGroup to subjectRoles to contain the roles + */ + SimpleGroup tmp = new SimpleGroup("Roles"); + subjectGroup.addMember(tmp); + subjectGroup = tmp; } - } - } - return callerPrincipal == null ? principal : callerPrincipal; - } + // Copy the group members to the Subject group + Enumeration members = group.members(); + while (members.hasMoreElements()) { + Principal role = (Principal) members.nextElement(); + subjectGroup.addMember(role); + } + } + // add the CallerPrincipal group if none has been added in getRoleSets + Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP); + callerGroup.addMember(identity); + principals.add(callerGroup); + SecurityContext sc = SecurityContextAssociation.getSecurityContext(); + Principal userPrincipal = getPrincipal(subject); + sc.getUtil().createSubjectInfo(userPrincipal, credentials, subject); + List rolesAsStringList = new ArrayList(); + rolesAsStringList.addAll(roleSet); + return new JBossGenericPrincipal(realm, userPrincipal.getName(), null, rolesAsStringList, + userPrincipal, null, credentials, null, subject); - protected Group createGroup(String name, Set principals) - { - Group roles = null; - Iterator iter = principals.iterator(); - while( iter.hasNext() ) - { - Object next = iter.next(); - if( (next instanceof Group) == false ) - continue; - Group grp = (Group) next; - if( grp.getName().equals(name) ) - { - roles = grp; - break; - } - } - // If we did not find a group create one - if( roles == null ) - { - roles = new SimpleGroup(name); - principals.add(roles); - } - return roles; - } + } - protected Group[] getRoleSets(Collection roleSet) - { - SimpleGroup roles = new SimpleGroup("Roles"); - Group[] roleSets = {roles}; - for (String role : roleSet) - { - roles.addMember(new SimplePrincipal(role)); - } - return roleSets; - } + /** + * Get the Principal given the authenticated Subject. Currently the first principal that is not of type {@code Group} is + * considered or the single principal inside the CallerPrincipal group. + * + * @param subject + * @return the authenticated principal + */ + protected Principal getPrincipal(Subject subject) { + Principal principal = null; + Principal callerPrincipal = null; + if (subject != null) { + Set principals = subject.getPrincipals(); + if (principals != null && !principals.isEmpty()) { + for (Principal p : principals) { + if (!(p instanceof Group) && principal == null) { + principal = p; + } + if (p instanceof Group) { + Group g = Group.class.cast(p); + if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) { + Enumeration e = g.members(); + if (e.hasMoreElements()) + callerPrincipal = e.nextElement(); + } + } + } + } + } + return callerPrincipal == null ? principal : callerPrincipal; + } + + protected Group createGroup(String name, Set principals) { + Group roles = null; + Iterator iter = principals.iterator(); + while (iter.hasNext()) { + Object next = iter.next(); + if ((next instanceof Group) == false) + continue; + Group grp = (Group) next; + if (grp.getName().equals(name)) { + roles = grp; + break; + } + } + // If we did not find a group create one + if (roles == null) { + roles = new SimpleGroup(name); + principals.add(roles); + } + return roles; + } + + protected Group[] getRoleSets(Collection roleSet) { + SimpleGroup roles = new SimpleGroup("Roles"); + Group[] roleSets = {roles}; + for (String role : roleSet) { + roles.addMember(new SimplePrincipal(role)); + } + return roleSets; + } } 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 abc1dca240..1b04c9adac 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 @@ -25,6 +25,9 @@ import org.jboss.resteasy.jose.jws.crypto.RSAProvider; import org.jboss.resteasy.jwt.JsonSerialization; import org.jboss.resteasy.plugins.providers.RegisterBuiltin; import org.jboss.resteasy.plugins.server.servlet.ServletUtil; +import org.jboss.resteasy.spi.ResteasyProviderFactory; +import org.jboss.resteasy.spi.ResteasyUriInfo; +import org.jboss.resteasy.util.BasicAuthHelper; import org.keycloak.EnvUtil; import org.keycloak.PemUtils; import org.keycloak.ResourceMetadata; @@ -33,9 +36,6 @@ import org.keycloak.adapters.as7.config.AuthServerConfig; import org.keycloak.adapters.as7.config.ManagedResourceConfig; import org.keycloak.representations.AccessTokenResponse; import org.keycloak.representations.SkeletonKeyToken; -import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.jboss.resteasy.spi.ResteasyUriInfo; -import org.jboss.resteasy.util.BasicAuthHelper; import javax.security.auth.login.LoginException; import javax.servlet.RequestDispatcher; @@ -79,972 +79,801 @@ import java.util.concurrent.atomic.AtomicLong; * @author Bill Burke * @version $Revision: 1 $ */ -public class OAuthAuthenticationServerValve extends FormAuthenticator implements LifecycleListener -{ +public class OAuthAuthenticationServerValve extends FormAuthenticator implements LifecycleListener { - public static class AccessCode - { - protected String id = UUID.randomUUID().toString() + System.currentTimeMillis(); - protected long expiration; - protected SkeletonKeyToken token; - protected String client; - protected boolean sso; - protected String redirect; + public static class AccessCode { + protected String id = UUID.randomUUID().toString() + System.currentTimeMillis(); + protected long expiration; + protected SkeletonKeyToken token; + protected String client; + protected boolean sso; + protected String redirect; - public boolean isExpired() - { - return expiration != 0 && (System.currentTimeMillis() / 1000) > expiration; - } + public boolean isExpired() { + return expiration != 0 && (System.currentTimeMillis() / 1000) > expiration; + } - public String getId() - { - return id; - } + public String getId() { + return id; + } - public long getExpiration() - { - return expiration; - } + public long getExpiration() { + return expiration; + } - public void setExpiration(long expiration) - { - this.expiration = expiration; - } + public void setExpiration(long expiration) { + this.expiration = expiration; + } - public SkeletonKeyToken getToken() - { - return token; - } + public SkeletonKeyToken getToken() { + return token; + } - public void setToken(SkeletonKeyToken token) - { - this.token = token; - } + public void setToken(SkeletonKeyToken token) { + this.token = token; + } - public String getClient() - { - return client; - } + public String getClient() { + return client; + } - public void setClient(String client) - { - this.client = client; - } + public void setClient(String client) { + this.client = client; + } - public boolean isSso() - { - return sso; - } + public boolean isSso() { + return sso; + } - public void setSso(boolean sso) - { - this.sso = sso; - } + public void setSso(boolean sso) { + this.sso = sso; + } - public String getRedirect() - { - return redirect; - } + public String getRedirect() { + return redirect; + } - public void setRedirect(String redirect) - { - this.redirect = redirect; - } - } + public void setRedirect(String redirect) { + this.redirect = redirect; + } + } - protected ConcurrentHashMap accessCodeMap = new ConcurrentHashMap(); - private static final Logger log = Logger.getLogger(OAuthAuthenticationServerValve.class); + protected ConcurrentHashMap accessCodeMap = new ConcurrentHashMap(); + private static final Logger log = Logger.getLogger(OAuthAuthenticationServerValve.class); - private static AtomicLong counter = new AtomicLong(1); + private static AtomicLong counter = new AtomicLong(1); - private static String generateId() - { - return counter.getAndIncrement() + "." + UUID.randomUUID().toString(); - } + private static String generateId() { + return counter.getAndIncrement() + "." + UUID.randomUUID().toString(); + } - protected AuthServerConfig skeletonKeyConfig; - protected PrivateKey realmPrivateKey; - protected PublicKey realmPublicKey; - protected String realmPublicKeyPem; - protected ResteasyProviderFactory providers; - protected ResourceMetadata resourceMetadata; - protected UserSessionManagement userSessionManagement = new UserSessionManagement(); - protected ObjectMapper mapper; - protected ObjectWriter accessTokenResponseWriter; - protected ObjectWriter mapWriter; + protected AuthServerConfig skeletonKeyConfig; + protected PrivateKey realmPrivateKey; + protected PublicKey realmPublicKey; + protected String realmPublicKeyPem; + protected ResteasyProviderFactory providers; + protected ResourceMetadata resourceMetadata; + protected UserSessionManagement userSessionManagement = new UserSessionManagement(); + protected ObjectMapper mapper; + protected ObjectWriter accessTokenResponseWriter; + protected ObjectWriter mapWriter; - private static KeyStore loadKeyStore(String filename, String password) throws Exception - { - KeyStore trustStore = KeyStore.getInstance(KeyStore - .getDefaultType()); - File truststoreFile = new File(filename); - FileInputStream trustStream = new FileInputStream(truststoreFile); - trustStore.load(trustStream, password.toCharArray()); - trustStream.close(); - return trustStore; - } + private static KeyStore loadKeyStore(String filename, String password) throws Exception { + KeyStore trustStore = KeyStore.getInstance(KeyStore + .getDefaultType()); + File truststoreFile = new File(filename); + FileInputStream trustStream = new FileInputStream(truststoreFile); + trustStore.load(trustStream, password.toCharArray()); + trustStream.close(); + return trustStore; + } - @Override - public void start() throws LifecycleException - { - super.start(); - StandardContext standardContext = (StandardContext) context; - standardContext.addLifecycleListener(this); - } + @Override + public void start() throws LifecycleException { + super.start(); + StandardContext standardContext = (StandardContext) context; + standardContext.addLifecycleListener(this); + } - @Override - public void lifecycleEvent(LifecycleEvent event) - { - if (event.getType() == Lifecycle.AFTER_START_EVENT) init(); - } + @Override + public void lifecycleEvent(LifecycleEvent event) { + if (event.getType() == Lifecycle.AFTER_START_EVENT) init(); + } - protected void init() - { - mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); - accessTokenResponseWriter = mapper.writerWithType(AccessTokenResponse.class); - mapWriter = mapper.writerWithType(mapper.getTypeFactory().constructMapType(Map.class, String.class, String.class)); + protected void init() { + mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); + accessTokenResponseWriter = mapper.writerWithType(AccessTokenResponse.class); + mapWriter = mapper.writerWithType(mapper.getTypeFactory().constructMapType(Map.class, String.class, String.class)); - InputStream is = null; - String path = context.getServletContext().getInitParameter("skeleton.key.config.file"); - if (path == null) - { - is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json"); - } - else - { - try - { - is = new FileInputStream(path); - } - catch (FileNotFoundException e) - { - throw new RuntimeException(e); - } - } - try - { - skeletonKeyConfig = mapper.readValue(is, AuthServerConfig.class); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - if (skeletonKeyConfig.getLoginRole() == null) - { - throw new RuntimeException("You must define the login-role in your config file"); - } - if (skeletonKeyConfig.getClientRole() == null) - { - throw new RuntimeException("You must define the oauth-client-role in your config file"); - } - if (skeletonKeyConfig.getRealmPrivateKey() != null) - { - try - { - realmPrivateKey = PemUtils.decodePrivateKey(skeletonKeyConfig.getRealmPrivateKey()); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - if (skeletonKeyConfig.getRealmPublicKey() != null) - { - try - { - realmPublicKey = PemUtils.decodePublicKey(skeletonKeyConfig.getRealmPublicKey()); - realmPublicKeyPem = skeletonKeyConfig.getRealmPublicKey(); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - if (skeletonKeyConfig.getRealmKeyStore() != null) - { - if (skeletonKeyConfig.getRealmKeyAlias() == null) throw new RuntimeException("Must define realm-key-alias"); - String keystorePath = EnvUtil.replace(skeletonKeyConfig.getRealmKeyStore()); - try - { - KeyStore ks = loadKeyStore(keystorePath, skeletonKeyConfig.getRealmKeystorePassword()); - if (realmPrivateKey == null) - { - realmPrivateKey = (PrivateKey) ks.getKey(skeletonKeyConfig.getRealmKeyAlias(), skeletonKeyConfig.getRealmPrivateKeyPassword().toCharArray()); + InputStream is = null; + String path = context.getServletContext().getInitParameter("skeleton.key.config.file"); + if (path == null) { + is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json"); + } else { + try { + is = new FileInputStream(path); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); } - if (realmPublicKey == null) - { - Certificate cert = ks.getCertificate(skeletonKeyConfig.getRealmKeyAlias()); - realmPublicKey = cert.getPublicKey(); - } - } - catch (Exception e) - { + } + try { + skeletonKeyConfig = mapper.readValue(is, AuthServerConfig.class); + } catch (IOException e) { throw new RuntimeException(e); - } - } - if (realmPublicKey == null) throw new RuntimeException("You have not declared a keystore or public key"); - if (realmPrivateKey == null) throw new RuntimeException("You have not declared a keystore or private key"); - if (realmPublicKeyPem == null) - { - StringWriter sw = new StringWriter(); - PEMWriter writer = new PEMWriter(sw); - try - { - writer.writeObject(realmPublicKey); - writer.flush(); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - realmPublicKeyPem = sw.toString(); - realmPublicKeyPem = PemUtils.removeBeginEnd(realmPublicKeyPem); - } - providers = new ResteasyProviderFactory(); - ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(OAuthAuthenticationServerValve.class.getClassLoader()); - try - { - ResteasyProviderFactory.getInstance(); // initialize builtins - RegisterBuiltin.register(providers); - } - finally - { - Thread.currentThread().setContextClassLoader(old); - } - resourceMetadata = new ResourceMetadata(); - resourceMetadata.setRealm(skeletonKeyConfig.getRealm()); - resourceMetadata.setRealmKey(realmPublicKey); - String truststore = skeletonKeyConfig.getTruststore(); - if (truststore != null) - { - truststore = EnvUtil.replace(truststore); - String truststorePassword = skeletonKeyConfig.getTruststorePassword(); - KeyStore trust = null; - try - { - trust = loadKeyStore(truststore, truststorePassword); - } - catch (Exception e) - { - throw new RuntimeException("Failed to load truststore", e); - } - resourceMetadata.setTruststore(trust); - } - String clientKeystore = skeletonKeyConfig.getClientKeystore(); - String clientKeyPassword = null; - if (clientKeystore != null) - { - clientKeystore = EnvUtil.replace(clientKeystore); - String clientKeystorePassword = skeletonKeyConfig.getClientKeystorePassword(); - KeyStore serverKS = null; - try - { - serverKS = loadKeyStore(clientKeystore, clientKeystorePassword); - } - catch (Exception e) - { - throw new RuntimeException("Failed to load keystore", e); - } - resourceMetadata.setClientKeystore(serverKS); - clientKeyPassword = skeletonKeyConfig.getClientKeyPassword(); - resourceMetadata.setClientKeyPassword(clientKeyPassword); - } - } - - @Override - public void invoke(Request request, Response response) throws IOException, ServletException - { - try - { - String contextPath = request.getContextPath(); - String requestURI = request.getDecodedRequestURI(); - log.debug("--- invoke: " + requestURI); - if (request.getMethod().equalsIgnoreCase("GET") - && context.getLoginConfig().getLoginPage().equals(request.getRequestPathMB().toString())) - { - if (handleLoginPage(request, response)) return; - } - else if (request.getMethod().equalsIgnoreCase("GET") - && requestURI.endsWith(Actions.J_OAUTH_LOGOUT)) - { - logoutCurrentUser(request, response); - return; - } - else if (request.getMethod().equalsIgnoreCase("POST") - && requestURI.endsWith(Actions.J_OAUTH_ADMIN_FORCED_LOGOUT)) - { - adminLogout(request, response); - return; - } - else if (request.getMethod().equalsIgnoreCase("POST") - && requestURI.startsWith(contextPath) && - requestURI.endsWith(Constants.FORM_ACTION) - && request.getParameter("client_id") != null) - { - handleOAuth(request, response); - return; - } - else if (request.getMethod().equalsIgnoreCase("POST") - && requestURI.endsWith(Actions.J_OAUTH_TOKEN_GRANT)) - { - tokenGrant(request, response); - return; - } - else if (request.getMethod().equalsIgnoreCase("POST") - && requestURI.startsWith(contextPath) && - requestURI.endsWith(Actions.J_OAUTH_RESOLVE_ACCESS_CODE)) - { - resolveAccessCode(request, response); - return; - } - else if (request.getMethod().equalsIgnoreCase("GET") - && requestURI.startsWith(contextPath) && - requestURI.endsWith("j_oauth_realm_info.html")) - { - publishRealmInfoHtml(request, response); - return; - } - // propagate the skeleton key token string? - if (!skeletonKeyConfig.isCancelPropagation()) - { - if (request.getAttribute(SkeletonKeySession.class.getName()) == null && request.getSessionInternal() != null) - { - SkeletonKeySession skSession = (SkeletonKeySession) request.getSessionInternal().getNote(SkeletonKeySession.class.getName()); - if (skSession != null) - { - request.setAttribute(SkeletonKeySession.class.getName(), skSession); - ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); - } + } + if (skeletonKeyConfig.getLoginRole() == null) { + throw new RuntimeException("You must define the login-role in your config file"); + } + if (skeletonKeyConfig.getClientRole() == null) { + throw new RuntimeException("You must define the oauth-client-role in your config file"); + } + if (skeletonKeyConfig.getRealmPrivateKey() != null) { + try { + realmPrivateKey = PemUtils.decodePrivateKey(skeletonKeyConfig.getRealmPrivateKey()); + } catch (Exception e) { + throw new RuntimeException(e); } - } - request.setAttribute("OAUTH_FORM_ACTION", "j_security_check"); - super.invoke(request, response); - } - finally - { - ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession - } - } + } + if (skeletonKeyConfig.getRealmPublicKey() != null) { + try { + realmPublicKey = PemUtils.decodePublicKey(skeletonKeyConfig.getRealmPublicKey()); + realmPublicKeyPem = skeletonKeyConfig.getRealmPublicKey(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + if (skeletonKeyConfig.getRealmKeyStore() != null) { + if (skeletonKeyConfig.getRealmKeyAlias() == null) throw new RuntimeException("Must define realm-key-alias"); + String keystorePath = EnvUtil.replace(skeletonKeyConfig.getRealmKeyStore()); + try { + KeyStore ks = loadKeyStore(keystorePath, skeletonKeyConfig.getRealmKeystorePassword()); + if (realmPrivateKey == null) { + realmPrivateKey = (PrivateKey) ks.getKey(skeletonKeyConfig.getRealmKeyAlias(), skeletonKeyConfig.getRealmPrivateKeyPassword().toCharArray()); + } + if (realmPublicKey == null) { + Certificate cert = ks.getCertificate(skeletonKeyConfig.getRealmKeyAlias()); + realmPublicKey = cert.getPublicKey(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + if (realmPublicKey == null) throw new RuntimeException("You have not declared a keystore or public key"); + if (realmPrivateKey == null) throw new RuntimeException("You have not declared a keystore or private key"); + if (realmPublicKeyPem == null) { + StringWriter sw = new StringWriter(); + PEMWriter writer = new PEMWriter(sw); + try { + writer.writeObject(realmPublicKey); + writer.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } + realmPublicKeyPem = sw.toString(); + realmPublicKeyPem = PemUtils.removeBeginEnd(realmPublicKeyPem); + } + providers = new ResteasyProviderFactory(); + ClassLoader old = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(OAuthAuthenticationServerValve.class.getClassLoader()); + try { + ResteasyProviderFactory.getInstance(); // initialize builtins + RegisterBuiltin.register(providers); + } finally { + Thread.currentThread().setContextClassLoader(old); + } + resourceMetadata = new ResourceMetadata(); + resourceMetadata.setRealm(skeletonKeyConfig.getRealm()); + resourceMetadata.setRealmKey(realmPublicKey); + String truststore = skeletonKeyConfig.getTruststore(); + if (truststore != null) { + truststore = EnvUtil.replace(truststore); + String truststorePassword = skeletonKeyConfig.getTruststorePassword(); + KeyStore trust = null; + try { + trust = loadKeyStore(truststore, truststorePassword); + } catch (Exception e) { + throw new RuntimeException("Failed to load truststore", e); + } + resourceMetadata.setTruststore(trust); + } + String clientKeystore = skeletonKeyConfig.getClientKeystore(); + String clientKeyPassword = null; + if (clientKeystore != null) { + clientKeystore = EnvUtil.replace(clientKeystore); + String clientKeystorePassword = skeletonKeyConfig.getClientKeystorePassword(); + KeyStore serverKS = null; + try { + serverKS = loadKeyStore(clientKeystore, clientKeystorePassword); + } catch (Exception e) { + throw new RuntimeException("Failed to load keystore", e); + } + resourceMetadata.setClientKeystore(serverKS); + clientKeyPassword = skeletonKeyConfig.getClientKeyPassword(); + resourceMetadata.setClientKeyPassword(clientKeyPassword); + } + } - protected boolean handleLoginPage(Request request, Response response) throws IOException, ServletException - { - String client_id = request.getParameter("client_id"); - // if this is not an OAUTH redirect, just return and let the default flow happen - if (client_id == null) return false; + @Override + public void invoke(Request request, Response response) throws IOException, ServletException { + try { + String contextPath = request.getContextPath(); + String requestURI = request.getDecodedRequestURI(); + log.debug("--- invoke: " + requestURI); + if (request.getMethod().equalsIgnoreCase("GET") + && context.getLoginConfig().getLoginPage().equals(request.getRequestPathMB().toString())) { + if (handleLoginPage(request, response)) return; + } else if (request.getMethod().equalsIgnoreCase("GET") + && requestURI.endsWith(Actions.J_OAUTH_LOGOUT)) { + logoutCurrentUser(request, response); + return; + } else if (request.getMethod().equalsIgnoreCase("POST") + && requestURI.endsWith(Actions.J_OAUTH_ADMIN_FORCED_LOGOUT)) { + adminLogout(request, response); + return; + } else if (request.getMethod().equalsIgnoreCase("POST") + && requestURI.startsWith(contextPath) && + requestURI.endsWith(Constants.FORM_ACTION) + && request.getParameter("client_id") != null) { + handleOAuth(request, response); + return; + } else if (request.getMethod().equalsIgnoreCase("POST") + && requestURI.endsWith(Actions.J_OAUTH_TOKEN_GRANT)) { + tokenGrant(request, response); + return; + } else if (request.getMethod().equalsIgnoreCase("POST") + && requestURI.startsWith(contextPath) && + requestURI.endsWith(Actions.J_OAUTH_RESOLVE_ACCESS_CODE)) { + resolveAccessCode(request, response); + return; + } else if (request.getMethod().equalsIgnoreCase("GET") + && requestURI.startsWith(contextPath) && + requestURI.endsWith("j_oauth_realm_info.html")) { + publishRealmInfoHtml(request, response); + return; + } + // propagate the skeleton key token string? + if (!skeletonKeyConfig.isCancelPropagation()) { + if (request.getAttribute(SkeletonKeySession.class.getName()) == null && request.getSessionInternal() != null) { + SkeletonKeySession skSession = (SkeletonKeySession) request.getSessionInternal().getNote(SkeletonKeySession.class.getName()); + if (skSession != null) { + request.setAttribute(SkeletonKeySession.class.getName(), skSession); + ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); + } + } + } + request.setAttribute("OAUTH_FORM_ACTION", "j_security_check"); + super.invoke(request, response); + } finally { + ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession + } + } - String redirect_uri = request.getParameter("redirect_uri"); - String state = request.getParameter("state"); + protected boolean handleLoginPage(Request request, Response response) throws IOException, ServletException { + String client_id = request.getParameter("client_id"); + // if this is not an OAUTH redirect, just return and let the default flow happen + if (client_id == null) return false; - if (redirect_uri == null) - { - response.sendError(400, "No oauth redirect query parameter set"); - return true; - } - // only bypass authentication if our session is authenticated, - // the login query parameter is on request URL, - // and we have configured the login-role - else if (!skeletonKeyConfig.isSsoDisabled() - && request.getSessionInternal() != null - && request.getSessionInternal().getPrincipal() != null - && request.getParameter("login") != null) - { - log.debug("We're ALREADY LOGGED IN!!!"); - GenericPrincipal gp = (GenericPrincipal) request.getSessionInternal().getPrincipal(); - redirectAccessCode(true, response, redirect_uri, client_id, state, gp); - } - else - { - UriBuilder builder = UriBuilder.fromUri("j_security_check") - .queryParam("redirect_uri", redirect_uri) - .queryParam("client_id", client_id); - if (state != null) builder.queryParam("state", state); - String loginAction = builder.build().toString(); - request.setAttribute("OAUTH_FORM_ACTION", loginAction); - getNext().invoke(request, response); - } - return true; - } + String redirect_uri = request.getParameter("redirect_uri"); + String state = request.getParameter("state"); - protected GenericPrincipal checkLoggedIn(Request request, HttpServletResponse response) - { - if (request.getPrincipal() != null) - { - return (GenericPrincipal) request.getPrincipal(); - } - else if (request.getSessionInternal() != null && request.getSessionInternal().getPrincipal() != null) - { - return (GenericPrincipal) request.getSessionInternal().getPrincipal(); - } - return null; - } + if (redirect_uri == null) { + response.sendError(400, "No oauth redirect query parameter set"); + return true; + } + // only bypass authentication if our session is authenticated, + // the login query parameter is on request URL, + // and we have configured the login-role + else if (!skeletonKeyConfig.isSsoDisabled() + && request.getSessionInternal() != null + && request.getSessionInternal().getPrincipal() != null + && request.getParameter("login") != null) { + log.debug("We're ALREADY LOGGED IN!!!"); + GenericPrincipal gp = (GenericPrincipal) request.getSessionInternal().getPrincipal(); + redirectAccessCode(true, response, redirect_uri, client_id, state, gp); + } else { + UriBuilder builder = UriBuilder.fromUri("j_security_check") + .queryParam("redirect_uri", redirect_uri) + .queryParam("client_id", client_id); + if (state != null) builder.queryParam("state", state); + String loginAction = builder.build().toString(); + request.setAttribute("OAUTH_FORM_ACTION", loginAction); + getNext().invoke(request, response); + } + return true; + } + + protected GenericPrincipal checkLoggedIn(Request request, HttpServletResponse response) { + if (request.getPrincipal() != null) { + return (GenericPrincipal) request.getPrincipal(); + } else if (request.getSessionInternal() != null && request.getSessionInternal().getPrincipal() != null) { + return (GenericPrincipal) request.getSessionInternal().getPrincipal(); + } + return null; + } - protected void adminLogout(Request request, HttpServletResponse response) throws IOException - { - log.debug("<< adminLogout"); - GenericPrincipal gp = checkLoggedIn(request, response); - if (gp == null) - { - if (bearer(request, response, false)) - { - gp = (GenericPrincipal) request.getPrincipal(); - } - else - { + protected void adminLogout(Request request, HttpServletResponse response) throws IOException { + log.debug("<< adminLogout"); + GenericPrincipal gp = checkLoggedIn(request, response); + if (gp == null) { + if (bearer(request, response, false)) { + gp = (GenericPrincipal) request.getPrincipal(); + } else { + response.sendError(403); + return; + } + } + if (!gp.hasRole(skeletonKeyConfig.getAdminRole())) { response.sendError(403); return; - } - } - if (!gp.hasRole(skeletonKeyConfig.getAdminRole())) - { - response.sendError(403); - return; - } - String logoutUser = request.getParameter("user"); - if (logoutUser != null) - { - userSessionManagement.logout(logoutUser); - logoutResources(logoutUser, gp.getName()); - } - else - { - userSessionManagement.logoutAllBut(gp.getName()); - logoutResources(null, gp.getName()); - } - String forwardTo = request.getParameter("forward"); - if (forwardTo == null) - { - response.setStatus(204); - return; - } - RequestDispatcher disp = - context.getServletContext().getRequestDispatcher(forwardTo); - try - { - disp.forward(request.getRequest(), response); - } - catch (Throwable t) - { - request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "failed to forward"); - } + } + String logoutUser = request.getParameter("user"); + if (logoutUser != null) { + userSessionManagement.logout(logoutUser); + logoutResources(logoutUser, gp.getName()); + } else { + userSessionManagement.logoutAllBut(gp.getName()); + logoutResources(null, gp.getName()); + } + String forwardTo = request.getParameter("forward"); + if (forwardTo == null) { + response.setStatus(204); + return; + } + RequestDispatcher disp = + context.getServletContext().getRequestDispatcher(forwardTo); + try { + disp.forward(request.getRequest(), response); + } catch (Throwable t) { + request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "failed to forward"); + } - } + } - protected void logoutCurrentUser(Request request, HttpServletResponse response) throws IOException - { - if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null) - { - redirectToWelcomePage(request, response); - return; - } - GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal(); - String username = principal.getName(); - String admin = username; - userSessionManagement.logout(username); - request.setUserPrincipal(null); - request.setAuthType(null); - // logout user on all declared authenticated resources - logoutResources(username, admin); - redirectToWelcomePage(request, response); - } + protected void logoutCurrentUser(Request request, HttpServletResponse response) throws IOException { + if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null) { + redirectToWelcomePage(request, response); + return; + } + GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal(); + String username = principal.getName(); + String admin = username; + userSessionManagement.logout(username); + request.setUserPrincipal(null); + request.setAuthType(null); + // logout user on all declared authenticated resources + logoutResources(username, admin); + redirectToWelcomePage(request, response); + } - protected void logoutResources(String username, String admin) - { - if (skeletonKeyConfig.getResources().size() != 0) - { - SkeletonKeyToken token = new SkeletonKeyToken(); - token.id(generateId()); - token.principal(admin); - token.audience(skeletonKeyConfig.getRealm()); - SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access(); - realmAccess.addRole(skeletonKeyConfig.getAdminRole()); - token.setRealmAccess(realmAccess); - String tokenString = buildTokenString(realmPrivateKey, token); - ResteasyClient client = new ResteasyClientBuilder() - .providerFactory(providers) - .hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY) - .trustStore(resourceMetadata.getTruststore()) - .keyStore(resourceMetadata.getClientKeystore(), resourceMetadata.getClientKeyPassword()) - .build(); - try - { - for (String resource : skeletonKeyConfig.getResources()) - { - try - { - log.debug("logging out: " + resource); - WebTarget target = client.target(resource).path(Actions.J_OAUTH_REMOTE_LOGOUT); - if (username != null) target = target.queryParam("user", username); - javax.ws.rs.core.Response response = target.request() - .header("Authorization", "Bearer " + tokenString) - .put(null); - if (response.getStatus() != 204) log.error("Failed to log out"); - response.close(); - } - catch (Exception ignored) - { - log.error("Failed to log out", ignored); - } + protected void logoutResources(String username, String admin) { + if (skeletonKeyConfig.getResources().size() != 0) { + SkeletonKeyToken token = new SkeletonKeyToken(); + token.id(generateId()); + token.principal(admin); + token.audience(skeletonKeyConfig.getRealm()); + SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access(); + realmAccess.addRole(skeletonKeyConfig.getAdminRole()); + token.setRealmAccess(realmAccess); + String tokenString = buildTokenString(realmPrivateKey, token); + ResteasyClient client = new ResteasyClientBuilder() + .providerFactory(providers) + .hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY) + .trustStore(resourceMetadata.getTruststore()) + .keyStore(resourceMetadata.getClientKeystore(), resourceMetadata.getClientKeyPassword()) + .build(); + try { + for (String resource : skeletonKeyConfig.getResources()) { + try { + log.debug("logging out: " + resource); + WebTarget target = client.target(resource).path(Actions.J_OAUTH_REMOTE_LOGOUT); + if (username != null) target = target.queryParam("user", username); + javax.ws.rs.core.Response response = target.request() + .header("Authorization", "Bearer " + tokenString) + .put(null); + if (response.getStatus() != 204) log.error("Failed to log out"); + response.close(); + } catch (Exception ignored) { + log.error("Failed to log out", ignored); + } + } + } finally { + client.close(); } - } - finally - { - client.close(); - } - } - } + } + } - protected void redirectToWelcomePage(Request request, HttpServletResponse response) throws IOException - { - ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null); - String[] welcomes = context.findWelcomeFiles(); - if (welcomes.length > 0) - { - UriBuilder welcome = uriInfo.getBaseUriBuilder().path(welcomes[0]); - response.sendRedirect(welcome.toTemplate()); - } - else - { - response.setStatus(204); - } - } + protected void redirectToWelcomePage(Request request, HttpServletResponse response) throws IOException { + ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null); + String[] welcomes = context.findWelcomeFiles(); + if (welcomes.length > 0) { + UriBuilder welcome = uriInfo.getBaseUriBuilder().path(welcomes[0]); + response.sendRedirect(welcome.toTemplate()); + } else { + response.setStatus(204); + } + } - protected void publishRealmInfoHtml(Request request, HttpServletResponse response) throws IOException - { - ManagedResourceConfig rep = getRealmRepresentation(request); - StringWriter writer; - String json; + protected void publishRealmInfoHtml(Request request, HttpServletResponse response) throws IOException { + ManagedResourceConfig rep = getRealmRepresentation(request); + StringWriter writer; + String json; - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); - mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT); + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); + mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT); - StringBuffer html = new StringBuffer(); - html.append(""); - html.append("

Realm: ").append(rep.getRealm()).append("

"); + StringBuffer html = new StringBuffer(); + html.append(""); + html.append("

Realm: ").append(rep.getRealm()).append("

"); - ManagedResourceConfig bearer = new ManagedResourceConfig(); - bearer.setRealm(rep.getRealm()); - bearer.setRealmKey(rep.getRealmKey()); - writer = new StringWriter(); - mapper.writeValue(writer, bearer); - json = writer.toString(); + ManagedResourceConfig bearer = new ManagedResourceConfig(); + bearer.setRealm(rep.getRealm()); + bearer.setRealmKey(rep.getRealmKey()); + writer = new StringWriter(); + mapper.writeValue(writer, bearer); + json = writer.toString(); - html.append("

BearerTokenAuthValve Json Config

"); - html.append("
"); + html.append("

BearerTokenAuthValve Json Config

"); + html.append("
"); - html.append("
"); + html.append("
"); - writer = new StringWriter(); - rep.getClientCredentials().put("password", "REQUIRED"); - rep.setClientId("REQUIRED"); - rep.setTruststore("REQUIRED"); - rep.setTruststorePassword("REQUIRED"); - mapper.writeValue(writer, rep); - json = writer.toString(); - html.append("

OAuthManagedResourceValve Json Config

"); - html.append("
"); + writer = new StringWriter(); + rep.getClientCredentials().put("password", "REQUIRED"); + rep.setClientId("REQUIRED"); + rep.setTruststore("REQUIRED"); + rep.setTruststorePassword("REQUIRED"); + mapper.writeValue(writer, rep); + json = writer.toString(); + html.append("

OAuthManagedResourceValve Json Config

"); + html.append("
"); - html.append(""); + html.append(""); - response.setStatus(200); - response.setContentType("text/html"); - response.getOutputStream().println(html.toString()); - response.getOutputStream().flush(); + response.setStatus(200); + response.setContentType("text/html"); + response.getOutputStream().println(html.toString()); + response.getOutputStream().flush(); - } + } - protected ManagedResourceConfig getRealmRepresentation(Request request) - { - ManagedResourceConfig rep = new ManagedResourceConfig(); - ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null); - UriBuilder authUrl = uriInfo.getBaseUriBuilder().path(context.getLoginConfig().getLoginPage()); - UriBuilder codeUrl = uriInfo.getBaseUriBuilder().path(Actions.J_OAUTH_RESOLVE_ACCESS_CODE); - rep.setRealm(skeletonKeyConfig.getRealm()); - rep.setRealmKey(realmPublicKeyPem); - rep.setAuthUrl(authUrl.toTemplate()); - rep.setCodeUrl(codeUrl.toTemplate()); - rep.setAdminRole(skeletonKeyConfig.getAdminRole()); - return rep; - } + protected ManagedResourceConfig getRealmRepresentation(Request request) { + ManagedResourceConfig rep = new ManagedResourceConfig(); + ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null); + UriBuilder authUrl = uriInfo.getBaseUriBuilder().path(context.getLoginConfig().getLoginPage()); + UriBuilder codeUrl = uriInfo.getBaseUriBuilder().path(Actions.J_OAUTH_RESOLVE_ACCESS_CODE); + rep.setRealm(skeletonKeyConfig.getRealm()); + rep.setRealmKey(realmPublicKeyPem); + rep.setAuthUrl(authUrl.toTemplate()); + rep.setCodeUrl(codeUrl.toTemplate()); + rep.setAdminRole(skeletonKeyConfig.getAdminRole()); + return rep; + } - public boolean bearer(Request request, HttpServletResponse response, boolean propagate) throws IOException - { - if (request.getHeader("Authorization") != null) - { - CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, true, false); - try - { - if (bearer.login(request, response)) - { - return true; + public boolean bearer(Request request, HttpServletResponse response, boolean propagate) throws IOException { + if (request.getHeader("Authorization") != null) { + CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, true, false); + try { + if (bearer.login(request, response)) { + return true; + } + } catch (LoginException e) { } - } - catch (LoginException e) - { - } - } - return false; - } + } + return false; + } - @Override - protected void register(Request request, HttpServletResponse response, Principal principal, String authType, String username, String password) - { - super.register(request, response, principal, authType, username, password); - log.debug("authenticate userSessionManage.login(): " + principal.getName()); - userSessionManagement.login(request.getSessionInternal(), principal.getName()); - if (!skeletonKeyConfig.isCancelPropagation()) - { - GenericPrincipal gp = (GenericPrincipal) request.getPrincipal(); - if (gp != null) - { - SkeletonKeyToken token = buildToken(gp); - String stringToken = buildTokenString(realmPrivateKey, token); - SkeletonKeySession skSession = new SkeletonKeySession(stringToken, resourceMetadata); - request.setAttribute(SkeletonKeySession.class.getName(), skSession); - ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); - request.getSessionInternal(true).setNote(SkeletonKeySession.class.getName(), skSession); - } - } - } - - @Override - public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException - { - if (bearer(request, response, true)) - { - return true; - } - return super.authenticate(request, response, config); - } - - - protected void resolveAccessCode(Request request, Response response) throws IOException - { - if (!request.isSecure()) - { - response.sendError(400); - return; - } - // always verify code and remove access code from map before authenticating user - // if user authentication fails, we want the code to be removed irreguardless just in case we're under attack - String code = request.getParameter("code"); - JWSInput input = new JWSInput(code, providers); - boolean verifiedCode = false; - try - { - verifiedCode = RSAProvider.verify(input, realmPublicKey); - } - catch (Exception ignored) - { - log.error("Failed to verify signature", ignored); - } - if (!verifiedCode) - { - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Unable to verify code signature"); - response.sendError(400); - response.setContentType("application/json"); - mapWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - return; - } - String key = input.readContent(String.class); - AccessCode accessCode = accessCodeMap.remove(key); - String redirect = request.getParameter("redirect_uri"); - - GenericPrincipal gp = basicAuth(request, response); - if (gp == null) - { - log.error("Failed to authenticate client_id"); - return; - } - if (accessCode == null) - { - log.error("No access code: " + code); - response.sendError(400); - return; - } - if (accessCode.isExpired()) - { - log.debug("Access code expired"); - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Code is expired"); - response.setStatus(400); - response.setContentType("application/json"); - mapWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - return; - } - if (!accessCode.getToken().isActive()) - { - log.debug("token not active"); - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Token expired"); - response.setStatus(400); - response.setContentType("application/json"); - mapWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - return; - } - if (!gp.getName().equals(accessCode.getClient())) - { - log.debug("not equal client"); - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Auth error"); - response.setStatus(400); - response.setContentType("application/json"); - mapWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - return; - } - if (!accessCode.getRedirect().equals(redirect)) - { - log.debug("not equal redirect"); - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Auth error"); - response.setStatus(400); - response.setContentType("application/json"); - mapWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - return; - } - if (accessCode.isSso() && !gp.hasRole(skeletonKeyConfig.getLoginRole())) - { - // we did not authenticate user on an access code request because a session was already established - // but, the client_id does not have permission to bypass this on a simple grant. We want - // to always ask for credentials from a simple oath request - - log.debug("does not have login permission"); - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Auth error"); - response.setStatus(400); - response.setContentType("application/json"); - mapWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - return; - } - else if (!gp.hasRole(skeletonKeyConfig.getClientRole()) && !gp.hasRole(skeletonKeyConfig.getLoginRole())) - { - log.debug("does not have login or client role permission for access token request"); - Map res = new HashMap(); - res.put("error", "invalid_grant"); - res.put("error_description", "Auth error"); - response.setStatus(400); - response.setContentType("application/json"); - mapWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - return; - - } - String wildcard = skeletonKeyConfig.getWildcardRole() == null ? "*" : skeletonKeyConfig.getWildcardRole(); - Set codeRoles = accessCode.getToken().getRealmAccess().getRoles(); - if (codeRoles != null && - (codeRoles.contains(skeletonKeyConfig.getClientRole()) || codeRoles.contains(skeletonKeyConfig.getLoginRole()))) - { - // we store roles a oauth client is granted in the user role mapping, remove those roles as we don't want those clients with those - // permissions if they are logging in. - Set newRoles = new HashSet(); - if (codeRoles.contains(skeletonKeyConfig.getClientRole())) newRoles.add(skeletonKeyConfig.getClientRole()); - if (codeRoles.contains(skeletonKeyConfig.getLoginRole())) newRoles.add(skeletonKeyConfig.getLoginRole()); - if (codeRoles.contains(wildcard)) newRoles.add(wildcard); - codeRoles.clear(); - codeRoles.addAll(newRoles); - } - - // is we have a login role, then we don't need to filter out roles, just grant all the roles the user has - // Also, if the client has the "wildcard" role, then we don't need to filter out roles - if (codeRoles != null - && !gp.hasRole(wildcard) - && !gp.hasRole(skeletonKeyConfig.getLoginRole())) - { - Set clientAllowed = new HashSet(); - for (String role : gp.getRoles()) - { - clientAllowed.add(role); - } - Set newRoles = new HashSet(); - newRoles.addAll(codeRoles); - for (String role : newRoles) - { - if (!clientAllowed.contains(role)) - { - codeRoles.remove(role); + @Override + protected void register(Request request, HttpServletResponse response, Principal principal, String authType, String username, String password) { + super.register(request, response, principal, authType, username, password); + log.debug("authenticate userSessionManage.login(): " + principal.getName()); + userSessionManagement.login(request.getSessionInternal(), principal.getName()); + if (!skeletonKeyConfig.isCancelPropagation()) { + GenericPrincipal gp = (GenericPrincipal) request.getPrincipal(); + if (gp != null) { + SkeletonKeyToken token = buildToken(gp); + String stringToken = buildTokenString(realmPrivateKey, token); + SkeletonKeySession skSession = new SkeletonKeySession(stringToken, resourceMetadata); + request.setAttribute(SkeletonKeySession.class.getName(), skSession); + ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); + request.getSessionInternal(true).setNote(SkeletonKeySession.class.getName(), skSession); } - } - } - AccessTokenResponse res = accessTokenResponse(realmPrivateKey, accessCode.getToken()); - response.setStatus(200); - response.setContentType("application/json"); - accessTokenResponseWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - } + } + } - protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token) - { - String encodedToken = buildTokenString(privateKey, token); - - AccessTokenResponse res = new AccessTokenResponse(); - res.setToken(encodedToken); - res.setTokenType("bearer"); - if (token.getExpiration() != 0) - { - long time = token.getExpiration() - (System.currentTimeMillis() / 1000); - res.setExpiresIn(time); - } - return res; - } - - protected String buildTokenString(PrivateKey privateKey, SkeletonKeyToken token) - { - byte[] tokenBytes = null; - try - { - tokenBytes = JsonSerialization.toByteArray(token, false); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - return new JWSBuilder() - .content(tokenBytes) - .rsa256(privateKey); - } + @Override + public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException { + if (bearer(request, response, true)) { + return true; + } + return super.authenticate(request, response, config); + } - protected void handleOAuth(Request request, Response response) throws IOException - { - log.debug("<--- Begin oauthAuthenticate"); - String redirect_uri = request.getParameter("redirect_uri"); - String client_id = request.getParameter("client_id"); - String state = request.getParameter("state"); - String username = request.getParameter(Constants.FORM_USERNAME); - String password = request.getParameter(Constants.FORM_PASSWORD); - Principal principal = context.getRealm().authenticate(username, password); - if (principal == null) - { - UriBuilder builder = UriBuilder.fromUri(redirect_uri).queryParam("error", "unauthorized_client"); - if (state != null) builder.queryParam("state", state); - response.sendRedirect(builder.toTemplate()); - return; - } - GenericPrincipal gp = (GenericPrincipal) principal; - register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); - userSessionManagement.login(request.getSessionInternal(), username); - redirectAccessCode(false, response, redirect_uri, client_id, state, gp); + protected void resolveAccessCode(Request request, Response response) throws IOException { + if (!request.isSecure()) { + response.sendError(400); + return; + } + // always verify code and remove access code from map before authenticating user + // if user authentication fails, we want the code to be removed irreguardless just in case we're under attack + String code = request.getParameter("code"); + JWSInput input = new JWSInput(code, providers); + boolean verifiedCode = false; + try { + verifiedCode = RSAProvider.verify(input, realmPublicKey); + } catch (Exception ignored) { + log.error("Failed to verify signature", ignored); + } + if (!verifiedCode) { + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Unable to verify code signature"); + response.sendError(400); + response.setContentType("application/json"); + mapWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + return; + } + String key = input.readContent(String.class); + AccessCode accessCode = accessCodeMap.remove(key); + String redirect = request.getParameter("redirect_uri"); - return; - } + GenericPrincipal gp = basicAuth(request, response); + if (gp == null) { + log.error("Failed to authenticate client_id"); + return; + } + if (accessCode == null) { + log.error("No access code: " + code); + response.sendError(400); + return; + } + if (accessCode.isExpired()) { + log.debug("Access code expired"); + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Code is expired"); + response.setStatus(400); + response.setContentType("application/json"); + mapWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + return; + } + if (!accessCode.getToken().isActive()) { + log.debug("token not active"); + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Token expired"); + response.setStatus(400); + response.setContentType("application/json"); + mapWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + return; + } + if (!gp.getName().equals(accessCode.getClient())) { + log.debug("not equal client"); + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Auth error"); + response.setStatus(400); + response.setContentType("application/json"); + mapWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + return; + } + if (!accessCode.getRedirect().equals(redirect)) { + log.debug("not equal redirect"); + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Auth error"); + response.setStatus(400); + response.setContentType("application/json"); + mapWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + return; + } + if (accessCode.isSso() && !gp.hasRole(skeletonKeyConfig.getLoginRole())) { + // we did not authenticate user on an access code request because a session was already established + // but, the client_id does not have permission to bypass this on a simple grant. We want + // to always ask for credentials from a simple oath request - protected void tokenGrant(Request request, Response response) throws IOException - { - if (!request.isSecure()) - { - response.sendError(400); - return; - } - GenericPrincipal gp = basicAuth(request, response); - if (gp == null) return; - SkeletonKeyToken token = buildToken(gp); - AccessTokenResponse res = accessTokenResponse(realmPrivateKey, token); - response.setStatus(200); - response.setContentType("application/json"); - accessTokenResponseWriter.writeValue(response.getOutputStream(), res); - response.getOutputStream().flush(); - } + log.debug("does not have login permission"); + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Auth error"); + response.setStatus(400); + response.setContentType("application/json"); + mapWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + return; + } else if (!gp.hasRole(skeletonKeyConfig.getClientRole()) && !gp.hasRole(skeletonKeyConfig.getLoginRole())) { + log.debug("does not have login or client role permission for access token request"); + Map res = new HashMap(); + res.put("error", "invalid_grant"); + res.put("error_description", "Auth error"); + response.setStatus(400); + response.setContentType("application/json"); + mapWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + return; - protected GenericPrincipal basicAuth(Request request, Response response) throws IOException - { - String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION); - if (authHeader == null) - { - basicAuthError(response); - return null; - } - String[] creds = BasicAuthHelper.parseHeader(authHeader); - if (creds == null) - { - basicAuthError(response); - return null; - } - String username = creds[0]; - String password = creds[1]; - GenericPrincipal gp = (GenericPrincipal) context.getRealm().authenticate(username, password); - if (gp == null) - { - basicAuthError(response); - return null; - } - return gp; - } + } + String wildcard = skeletonKeyConfig.getWildcardRole() == null ? "*" : skeletonKeyConfig.getWildcardRole(); + Set codeRoles = accessCode.getToken().getRealmAccess().getRoles(); + if (codeRoles != null && + (codeRoles.contains(skeletonKeyConfig.getClientRole()) || codeRoles.contains(skeletonKeyConfig.getLoginRole()))) { + // we store roles a oauth client is granted in the user role mapping, remove those roles as we don't want those clients with those + // permissions if they are logging in. + Set newRoles = new HashSet(); + if (codeRoles.contains(skeletonKeyConfig.getClientRole())) newRoles.add(skeletonKeyConfig.getClientRole()); + if (codeRoles.contains(skeletonKeyConfig.getLoginRole())) newRoles.add(skeletonKeyConfig.getLoginRole()); + if (codeRoles.contains(wildcard)) newRoles.add(wildcard); + codeRoles.clear(); + codeRoles.addAll(newRoles); + } - protected void basicAuthError(Response response) throws IOException - { - response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + context.getLoginConfig().getRealmName() + "\""); - response.sendError(401); - } + // is we have a login role, then we don't need to filter out roles, just grant all the roles the user has + // Also, if the client has the "wildcard" role, then we don't need to filter out roles + if (codeRoles != null + && !gp.hasRole(wildcard) + && !gp.hasRole(skeletonKeyConfig.getLoginRole())) { + Set clientAllowed = new HashSet(); + for (String role : gp.getRoles()) { + clientAllowed.add(role); + } + Set newRoles = new HashSet(); + newRoles.addAll(codeRoles); + for (String role : newRoles) { + if (!clientAllowed.contains(role)) { + codeRoles.remove(role); + } + } + } + AccessTokenResponse res = accessTokenResponse(realmPrivateKey, accessCode.getToken()); + response.setStatus(200); + response.setContentType("application/json"); + accessTokenResponseWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + } - protected void redirectAccessCode(boolean sso, Response response, String redirect_uri, String client_id, String state, GenericPrincipal gp) throws IOException - { - SkeletonKeyToken token = buildToken(gp); - AccessCode code = new AccessCode(); - code.setToken(token); - code.setClient(client_id); - code.setSso(sso); - code.setRedirect(redirect_uri); - int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 300 : skeletonKeyConfig.getAccessCodeLifetime(); - code.setExpiration((System.currentTimeMillis() / 1000) + expiration); - accessCodeMap.put(code.getId(), code); - log.debug("--- sign access code"); - String accessCode = null; - try - { - accessCode = new JWSBuilder().content(code.getId().getBytes("UTF-8")).rsa256(realmPrivateKey); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException(e); - } - log.debug("--- build redirect"); - UriBuilder redirectUri = UriBuilder.fromUri(redirect_uri).queryParam("code", accessCode); - if (state != null) redirectUri.queryParam("state", state); - response.sendRedirect(redirectUri.toTemplate()); - log.debug("<--- end oauthAuthenticate"); - } + protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token) { + String encodedToken = buildTokenString(privateKey, token); - protected SkeletonKeyToken buildToken(GenericPrincipal gp) - { - SkeletonKeyToken token = new SkeletonKeyToken(); - token.id(generateId()); - token.principal(gp.getName()); - token.audience(skeletonKeyConfig.getRealm()); - int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 3600 : skeletonKeyConfig.getAccessCodeLifetime(); - if (skeletonKeyConfig.getTokenLifetime() > 0) - { - token.expiration((System.currentTimeMillis() / 1000) + expiration); - } - SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access(); - for (String role : gp.getRoles()) - { - realmAccess.addRole(role); - } - token.setRealmAccess(realmAccess); - return token; - } + AccessTokenResponse res = new AccessTokenResponse(); + res.setToken(encodedToken); + res.setTokenType("bearer"); + if (token.getExpiration() != 0) { + long time = token.getExpiration() - (System.currentTimeMillis() / 1000); + res.setExpiresIn(time); + } + return res; + } + + protected String buildTokenString(PrivateKey privateKey, SkeletonKeyToken token) { + byte[] tokenBytes = null; + try { + tokenBytes = JsonSerialization.toByteArray(token, false); + } catch (Exception e) { + throw new RuntimeException(e); + } + return new JWSBuilder() + .content(tokenBytes) + .rsa256(privateKey); + } + + + protected void handleOAuth(Request request, Response response) throws IOException { + log.debug("<--- Begin oauthAuthenticate"); + String redirect_uri = request.getParameter("redirect_uri"); + String client_id = request.getParameter("client_id"); + String state = request.getParameter("state"); + String username = request.getParameter(Constants.FORM_USERNAME); + String password = request.getParameter(Constants.FORM_PASSWORD); + Principal principal = context.getRealm().authenticate(username, password); + if (principal == null) { + UriBuilder builder = UriBuilder.fromUri(redirect_uri).queryParam("error", "unauthorized_client"); + if (state != null) builder.queryParam("state", state); + response.sendRedirect(builder.toTemplate()); + return; + } + GenericPrincipal gp = (GenericPrincipal) principal; + register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); + userSessionManagement.login(request.getSessionInternal(), username); + redirectAccessCode(false, response, redirect_uri, client_id, state, gp); + + return; + } + + protected void tokenGrant(Request request, Response response) throws IOException { + if (!request.isSecure()) { + response.sendError(400); + return; + } + GenericPrincipal gp = basicAuth(request, response); + if (gp == null) return; + SkeletonKeyToken token = buildToken(gp); + AccessTokenResponse res = accessTokenResponse(realmPrivateKey, token); + response.setStatus(200); + response.setContentType("application/json"); + accessTokenResponseWriter.writeValue(response.getOutputStream(), res); + response.getOutputStream().flush(); + } + + protected GenericPrincipal basicAuth(Request request, Response response) throws IOException { + String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION); + if (authHeader == null) { + basicAuthError(response); + return null; + } + String[] creds = BasicAuthHelper.parseHeader(authHeader); + if (creds == null) { + basicAuthError(response); + return null; + } + String username = creds[0]; + String password = creds[1]; + GenericPrincipal gp = (GenericPrincipal) context.getRealm().authenticate(username, password); + if (gp == null) { + basicAuthError(response); + return null; + } + return gp; + } + + protected void basicAuthError(Response response) throws IOException { + response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + context.getLoginConfig().getRealmName() + "\""); + response.sendError(401); + } + + protected void redirectAccessCode(boolean sso, Response response, String redirect_uri, String client_id, String state, GenericPrincipal gp) throws IOException { + SkeletonKeyToken token = buildToken(gp); + AccessCode code = new AccessCode(); + code.setToken(token); + code.setClient(client_id); + code.setSso(sso); + code.setRedirect(redirect_uri); + int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 300 : skeletonKeyConfig.getAccessCodeLifetime(); + code.setExpiration((System.currentTimeMillis() / 1000) + expiration); + accessCodeMap.put(code.getId(), code); + log.debug("--- sign access code"); + String accessCode = null; + try { + accessCode = new JWSBuilder().content(code.getId().getBytes("UTF-8")).rsa256(realmPrivateKey); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + log.debug("--- build redirect"); + UriBuilder redirectUri = UriBuilder.fromUri(redirect_uri).queryParam("code", accessCode); + if (state != null) redirectUri.queryParam("state", state); + response.sendRedirect(redirectUri.toTemplate()); + log.debug("<--- end oauthAuthenticate"); + } + + protected SkeletonKeyToken buildToken(GenericPrincipal gp) { + SkeletonKeyToken token = new SkeletonKeyToken(); + token.id(generateId()); + token.principal(gp.getName()); + token.audience(skeletonKeyConfig.getRealm()); + int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 3600 : skeletonKeyConfig.getAccessCodeLifetime(); + if (skeletonKeyConfig.getTokenLifetime() > 0) { + token.expiration((System.currentTimeMillis() / 1000) + expiration); + } + SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access(); + for (String role : gp.getRoles()) { + realmAccess.addRole(role); + } + token.setRealmAccess(realmAccess); + return token; + } } 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 772607c550..77922a28ef 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 @@ -16,6 +16,7 @@ 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.spi.ResteasyProviderFactory; import org.keycloak.RealmConfiguration; import org.keycloak.ResourceMetadata; import org.keycloak.SkeletonKeyPrincipal; @@ -23,7 +24,6 @@ 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.jboss.resteasy.spi.ResteasyProviderFactory; import javax.security.auth.login.LoginException; import javax.servlet.ServletException; @@ -42,262 +42,192 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class OAuthManagedResourceValve extends FormAuthenticator implements LifecycleListener -{ - protected RealmConfiguration realmConfiguration; - private static final Logger log = Logger.getLogger(OAuthManagedResourceValve.class); - protected UserSessionManagement userSessionManagement = new UserSessionManagement(); - protected ManagedResourceConfig remoteSkeletonKeyConfig; - protected ResourceMetadata resourceMetadata; +public class OAuthManagedResourceValve extends FormAuthenticator implements LifecycleListener { + protected RealmConfiguration realmConfiguration; + private static final Logger log = Logger.getLogger(OAuthManagedResourceValve.class); + protected UserSessionManagement userSessionManagement = new UserSessionManagement(); + protected ManagedResourceConfig remoteSkeletonKeyConfig; + protected ResourceMetadata resourceMetadata; - @Override - public void start() throws LifecycleException - { - super.start(); - StandardContext standardContext = (StandardContext) context; - standardContext.addLifecycleListener(this); - } + @Override + public void start() throws LifecycleException { + super.start(); + StandardContext standardContext = (StandardContext) context; + standardContext.addLifecycleListener(this); + } - @Override - public void lifecycleEvent(LifecycleEvent event) - { - if (event.getType() == Lifecycle.AFTER_START_EVENT) init(); - } + @Override + public void lifecycleEvent(LifecycleEvent event) { + if (event.getType() == Lifecycle.AFTER_START_EVENT) init(); + } - protected void init() - { - ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context); - 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) - { - throw new RuntimeException("You must specify auth-url"); - } - String tokenUrl = remoteSkeletonKeyConfig.getCodeUrl(); - if (tokenUrl == null) - { - throw new RuntimeException("You mut specify code-url"); - } - realmConfiguration.setMetadata(resourceMetadata); - realmConfiguration.setClientId(client_id); + protected void init() { + ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context); + 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) { + throw new RuntimeException("You must specify auth-url"); + } + String tokenUrl = remoteSkeletonKeyConfig.getCodeUrl(); + if (tokenUrl == null) { + throw new RuntimeException("You mut specify code-url"); + } + realmConfiguration.setMetadata(resourceMetadata); + realmConfiguration.setClientId(client_id); - for (Map.Entry entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getClientCredentials().entrySet()) - { - realmConfiguration.getCredentials().param(entry.getKey(), entry.getValue()); - } - int size = 10; - if (managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getConnectionPoolSize() > 0) - size = managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getConnectionPoolSize(); - ResteasyClientBuilder.HostnameVerificationPolicy policy = ResteasyClientBuilder.HostnameVerificationPolicy.WILDCARD; - if (managedResourceConfigLoader.getRemoteSkeletonKeyConfig().isAllowAnyHostname()) - policy = ResteasyClientBuilder.HostnameVerificationPolicy.ANY; - ResteasyProviderFactory providerFactory = new ResteasyProviderFactory(); - ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(OAuthManagedResourceValve.class.getClassLoader()); - try - { - ResteasyProviderFactory.getInstance(); // initialize builtins - RegisterBuiltin.register(providerFactory); - } - finally - { - Thread.currentThread().setContextClassLoader(old); - } - ResteasyClient client = new ResteasyClientBuilder() - .providerFactory(providerFactory) - .connectionPoolSize(size) - .hostnameVerification(policy) - .trustStore(resourceMetadata.getTruststore()) - .keyStore(resourceMetadata.getClientKeystore(), resourceMetadata.getClientKeyPassword()) - .build(); - realmConfiguration.setClient(client); - realmConfiguration.setAuthUrl(UriBuilder.fromUri(authUrl).queryParam("client_id", client_id)); - realmConfiguration.setCodeUrl(client.target(tokenUrl)); - } + for (Map.Entry entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getClientCredentials().entrySet()) { + realmConfiguration.getCredentials().param(entry.getKey(), entry.getValue()); + } - @Override - 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); - return; - } - super.invoke(request, response); - } - finally - { - ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession - } - } + ResteasyClient client = managedResourceConfigLoader.getClient(); - @Override - public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException - { - try - { - if (bearer(false, request, response)) return true; - else if (checkLoggedIn(request, response)) - { - if (request.getSessionInternal().getNote(Constants.FORM_REQUEST_NOTE) != null) - { - if (restoreRequest(request, request.getSessionInternal())) - { - log.debug("restoreRequest"); - return (true); - } - else - { - log.debug("Restore of original request failed"); - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return (false); - } + realmConfiguration.setClient(client); + realmConfiguration.setAuthUrl(UriBuilder.fromUri(authUrl).queryParam("client_id", client_id)); + realmConfiguration.setCodeUrl(client.target(tokenUrl)); + } + + @Override + 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); + return; } - else - { - return true; + super.invoke(request, response); + } finally { + ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession + } + } + + @Override + public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException { + try { + if (bearer(false, request, response)) return true; + else if (checkLoggedIn(request, response)) { + if (request.getSessionInternal().getNote(Constants.FORM_REQUEST_NOTE) != null) { + if (restoreRequest(request, request.getSessionInternal())) { + log.debug("restoreRequest"); + return (true); + } else { + log.debug("Restore of original request failed"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return (false); + } + } else { + return true; + } } - } - // initiate or continue oauth2 protocol - oauth(request, response); - } - catch (LoginException e) - { - } - return false; - } + // initiate or continue oauth2 protocol + oauth(request, response); + } catch (LoginException e) { + } + return false; + } - protected void remoteLogout(Request request, HttpServletResponse response) throws IOException - { - try - { - log.debug("->> remoteLogout: "); - if (!bearer(true, request, response)) - { - log.debug("remoteLogout: bearer auth failed"); + protected void remoteLogout(Request request, HttpServletResponse response) throws IOException { + try { + log.debug("->> remoteLogout: "); + if (!bearer(true, request, response)) { + log.debug("remoteLogout: bearer auth failed"); + return; + } + GenericPrincipal gp = (GenericPrincipal) request.getPrincipal(); + if (!gp.hasRole(remoteSkeletonKeyConfig.getAdminRole())) { + log.debug("remoteLogout: role failure"); + response.sendError(403); + return; + } + String user = request.getParameter("user"); + if (user != null) { + userSessionManagement.logout(user); + } else { + userSessionManagement.logoutAll(); + } + } catch (Exception e) { + log.error("failed to logout", e); + } + response.setStatus(204); + } + + protected boolean bearer(boolean challenge, Request request, HttpServletResponse response) throws LoginException, IOException { + CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(realmConfiguration.getMetadata(), !remoteSkeletonKeyConfig.isCancelPropagation(), challenge); + if (bearer.login(request, response)) { + return true; + } + return false; + } + + protected boolean checkLoggedIn(Request request, HttpServletResponse response) { + if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null) + return false; + log.debug("remote logged in already"); + GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal(); + request.setUserPrincipal(principal); + request.setAuthType("OAUTH"); + Session session = request.getSessionInternal(); + if (session != null && !remoteSkeletonKeyConfig.isCancelPropagation()) { + SkeletonKeySession skSession = (SkeletonKeySession) session.getNote(SkeletonKeySession.class.getName()); + if (skSession != null) { + request.setAttribute(SkeletonKeySession.class.getName(), skSession); + ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); + + } + } + return true; + } + + /** + * This method always set the HTTP response, so do not continue after invoking + */ + protected void oauth(Request request, HttpServletResponse response) throws IOException { + ServletOAuthLogin oauth = new ServletOAuthLogin(realmConfiguration, request, response, request.getConnector().getRedirectPort()); + String code = oauth.getCode(); + if (code == null) { + String error = oauth.getError(); + if (error != null) { + response.sendError(400, "OAuth " + error); + return; + } else { + saveRequest(request, request.getSessionInternal(true)); + oauth.loginRedirect(); + } return; - } - GenericPrincipal gp = (GenericPrincipal) request.getPrincipal(); - if (!gp.hasRole(remoteSkeletonKeyConfig.getAdminRole())) - { - log.debug("remoteLogout: role failure"); - response.sendError(403); - return; - } - String user = request.getParameter("user"); - if (user != null) - { - userSessionManagement.logout(user); - } - else - { - userSessionManagement.logoutAll(); - } - } - catch (Exception e) - { - log.error("failed to logout", e); - } - response.setStatus(204); - } + } else { + if (!oauth.resolveCode(code)) return; - protected boolean bearer(boolean challenge, Request request, HttpServletResponse response) throws LoginException, IOException - { - CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(realmConfiguration.getMetadata(), !remoteSkeletonKeyConfig.isCancelPropagation(), challenge); - if (bearer.login(request, response)) - { - return true; - } - return false; - } + SkeletonKeyToken token = oauth.getToken(); + Set roles = null; + if (resourceMetadata.getResourceName() != null) { + SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName()); + if (access != null) roles = access.getRoles(); + } else { + SkeletonKeyToken.Access access = token.getRealmAccess(); + if (access != null) roles = access.getRoles(); + } + SkeletonKeyPrincipal skp = new SkeletonKeyPrincipal(token.getPrincipal(), null); + GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(context.getRealm(), skp, roles); + Session session = request.getSessionInternal(true); + session.setPrincipal(principal); + session.setAuthType("OAUTH"); + if (!remoteSkeletonKeyConfig.isCancelPropagation()) { + SkeletonKeySession skSession = new SkeletonKeySession(oauth.getTokenString(), realmConfiguration.getMetadata()); + session.setNote(SkeletonKeySession.class.getName(), skSession); + } - protected boolean checkLoggedIn(Request request, HttpServletResponse response) - { - if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null) - return false; - log.debug("remote logged in already"); - GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal(); - request.setUserPrincipal(principal); - request.setAuthType("OAUTH"); - Session session = request.getSessionInternal(); - if (session != null && !remoteSkeletonKeyConfig.isCancelPropagation()) - { - SkeletonKeySession skSession = (SkeletonKeySession) session.getNote(SkeletonKeySession.class.getName()); - if (skSession != null) - { - request.setAttribute(SkeletonKeySession.class.getName(), skSession); - ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); - - } - } - return true; - } - - /** - * This method always set the HTTP response, so do not continue after invoking - */ - protected void oauth(Request request, HttpServletResponse response) throws IOException - { - ServletOAuthLogin oauth = new ServletOAuthLogin(realmConfiguration, request, response, request.getConnector().getRedirectPort()); - String code = oauth.getCode(); - if (code == null) - { - String error = oauth.getError(); - if (error != null) - { - response.sendError(400, "OAuth " + error); - return; - } - else - { - saveRequest(request, request.getSessionInternal(true)); - oauth.loginRedirect(); - } - return; - } - else - { - if (!oauth.resolveCode(code)) return; - - SkeletonKeyToken token = oauth.getToken(); - Set roles = null; - if (resourceMetadata.getResourceName() != null) - { - SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName()); - if (access != null) roles = access.getRoles(); - } - else - { - SkeletonKeyToken.Access access = token.getRealmAccess(); - if (access != null) roles = access.getRoles(); - } - SkeletonKeyPrincipal skp = new SkeletonKeyPrincipal(token.getPrincipal(), null); - GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(context.getRealm(), skp, roles); - Session session = request.getSessionInternal(true); - session.setPrincipal(principal); - session.setAuthType("OAUTH"); - if (!remoteSkeletonKeyConfig.isCancelPropagation()) - { - SkeletonKeySession skSession = new SkeletonKeySession(oauth.getTokenString(), realmConfiguration.getMetadata()); - session.setNote(SkeletonKeySession.class.getName(), skSession); - } - - String username = token.getPrincipal(); - log.debug("userSessionManage.login: " + username); - userSessionManagement.login(session, username); - } - } + String username = token.getPrincipal(); + log.debug("userSessionManage.login: " + username); + userSessionManagement.login(session, username); + } + } } 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 4a7d8c19b5..e3db0e34c7 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,12 +1,12 @@ 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; import org.keycloak.representations.AccessTokenResponse; import org.keycloak.representations.SkeletonKeyToken; -import org.jboss.resteasy.util.BasicAuthHelper; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -21,300 +21,254 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; /** - * * @author Bill Burke * @version $Revision: 1 $ */ -public class ServletOAuthLogin -{ - private static final Logger log = Logger.getLogger(ServletOAuthLogin.class); - protected HttpServletRequest request; - protected HttpServletResponse response; - protected boolean codePresent; - protected RealmConfiguration realmInfo; - protected int redirectPort; - protected String tokenString; - protected SkeletonKeyToken token; +public class ServletOAuthLogin { + private static final Logger log = Logger.getLogger(ServletOAuthLogin.class); + protected HttpServletRequest request; + protected HttpServletResponse response; + protected boolean codePresent; + protected RealmConfiguration realmInfo; + protected int redirectPort; + protected String tokenString; + protected SkeletonKeyToken token; - public ServletOAuthLogin(RealmConfiguration realmInfo, HttpServletRequest request, HttpServletResponse response, int redirectPort) - { - this.request = request; - this.response = response; - this.realmInfo = realmInfo; - this.redirectPort = redirectPort; - } + public ServletOAuthLogin(RealmConfiguration realmInfo, HttpServletRequest request, HttpServletResponse response, int redirectPort) { + this.request = request; + this.response = response; + this.realmInfo = realmInfo; + this.redirectPort = redirectPort; + } - public String getTokenString() - { - return tokenString; - } + public String getTokenString() { + return tokenString; + } - public SkeletonKeyToken getToken() - { - return token; - } + public SkeletonKeyToken getToken() { + return token; + } - public RealmConfiguration getRealmInfo() - { - return realmInfo; - } + public RealmConfiguration getRealmInfo() { + return realmInfo; + } - protected String getDefaultCookiePath() - { - String path = request.getContextPath(); - if ("".equals(path) || path == null) path = "/"; - return path; - } + protected String getDefaultCookiePath() { + String path = request.getContextPath(); + if ("".equals(path) || path == null) path = "/"; + return path; + } - protected String getRequestUrl() - { - return request.getRequestURL().toString(); - } + protected String getRequestUrl() { + return request.getRequestURL().toString(); + } - protected boolean isRequestSecure() - { - return request.isSecure(); - } + protected boolean isRequestSecure() { + return request.isSecure(); + } - protected void sendError(int code) - { - try - { - response.sendError(code); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } + protected void sendError(int code) { + try { + response.sendError(code); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - protected void sendRedirect(String url) - { - try - { - response.sendRedirect(url); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } + protected void sendRedirect(String url) { + try { + response.sendRedirect(url); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - protected Cookie getCookie(String cookieName) - { - if (request.getCookies() == null) return null; - for (Cookie cookie : request.getCookies()) - { - if (cookie.getName().equals(cookieName)) - { - return cookie; - } - } - return null; - } + protected Cookie getCookie(String cookieName) { + if (request.getCookies() == null) return null; + for (Cookie cookie : request.getCookies()) { + if (cookie.getName().equals(cookieName)) { + return cookie; + } + } + return null; + } - protected String getCookieValue(String cookieName) - { - Cookie cookie = getCookie(cookieName); - if (cookie == null) return null; - return cookie.getValue(); - } + protected String getCookieValue(String cookieName) { + Cookie cookie = getCookie(cookieName); + if (cookie == null) return null; + return cookie.getValue(); + } - protected String getQueryParamValue(String paramName) - { - String query = request.getQueryString(); - if (query == null) return null; - String[] params = query.split("&"); - for (String param : params) - { - int eq = param.indexOf('='); - if (eq == -1) continue; - String name = param.substring(0, eq); - if (!name.equals(paramName)) continue; - return param.substring(eq + 1); - } - return null; - } + protected String getQueryParamValue(String paramName) { + String query = request.getQueryString(); + if (query == null) return null; + String[] params = query.split("&"); + for (String param : params) { + int eq = param.indexOf('='); + if (eq == -1) continue; + String name = param.substring(0, eq); + if (!name.equals(paramName)) continue; + return param.substring(eq + 1); + } + return null; + } - public String getError() - { - return getQueryParamValue("error"); - } + public String getError() { + return getQueryParamValue("error"); + } - public String getCode() - { - return getQueryParamValue("code"); - } + public String getCode() { + return getQueryParamValue("code"); + } - protected void setCookie(String name, String value, String domain, String path, boolean secure) - { - Cookie cookie = new Cookie(name, value); - if (domain != null) cookie.setDomain(domain); - if (path != null) cookie.setPath(path); - if (secure) cookie.setSecure(true); - response.addCookie(cookie); - } + protected void setCookie(String name, String value, String domain, String path, boolean secure) { + Cookie cookie = new Cookie(name, value); + if (domain != null) cookie.setDomain(domain); + if (path != null) cookie.setPath(path); + if (secure) cookie.setSecure(true); + response.addCookie(cookie); + } - protected String getRedirectUri(String state) - { - String url = getRequestUrl(); - if (!isRequestSecure() && realmInfo.isSslRequired()) - { - int port = redirectPort; - if (port < 0) - { - // disabled? - return null; - } - UriBuilder secureUrl = UriBuilder.fromUri(url).scheme("https").port(-1); - if (port != 443) secureUrl.port(port); - url = secureUrl.build().toString(); - } - return realmInfo.getAuthUrl().clone() - .queryParam("client_id", realmInfo.getClientId()) - .queryParam("redirect_uri", url) - .queryParam("state", state) - .queryParam("login", "true") - .build().toString(); - } + protected String getRedirectUri(String state) { + String url = getRequestUrl(); + if (!isRequestSecure() && realmInfo.isSslRequired()) { + int port = redirectPort; + if (port < 0) { + // disabled? + return null; + } + UriBuilder secureUrl = UriBuilder.fromUri(url).scheme("https").port(-1); + if (port != 443) secureUrl.port(port); + url = secureUrl.build().toString(); + } + return realmInfo.getAuthUrl().clone() + .queryParam("client_id", realmInfo.getClientId()) + .queryParam("redirect_uri", url) + .queryParam("state", state) + .queryParam("login", "true") + .build().toString(); + } - protected static final AtomicLong counter = new AtomicLong(); + protected static final AtomicLong counter = new AtomicLong(); - protected String getStateCode() - { - return counter.getAndIncrement() + "/" + UUID.randomUUID().toString(); - } + protected String getStateCode() { + return counter.getAndIncrement() + "/" + UUID.randomUUID().toString(); + } - public void loginRedirect() - { - String state = getStateCode(); - String redirect = getRedirectUri(state); - if (redirect == null) - { - sendError(Response.Status.FORBIDDEN.getStatusCode()); - return; - } - setCookie(realmInfo.getStateCookieName(), state, null, getDefaultCookiePath(), realmInfo.isSslRequired()); - sendRedirect(redirect); - } + public void loginRedirect() { + String state = getStateCode(); + String redirect = getRedirectUri(state); + if (redirect == null) { + sendError(Response.Status.FORBIDDEN.getStatusCode()); + return; + } + setCookie(realmInfo.getStateCookieName(), state, null, getDefaultCookiePath(), realmInfo.isSslRequired()); + sendRedirect(redirect); + } - public boolean checkStateCookie() - { - Cookie stateCookie = getCookie(realmInfo.getStateCookieName()); + public boolean checkStateCookie() { + Cookie stateCookie = getCookie(realmInfo.getStateCookieName()); - if (stateCookie == null) - { - sendError(400); - log.warn("No state cookie"); - return false; - } - // reset the cookie - Cookie reset = new Cookie(stateCookie.getName(), stateCookie.getValue()); - reset.setPath(stateCookie.getPath()); - reset.setMaxAge(0); - response.addCookie(reset); + if (stateCookie == null) { + sendError(400); + log.warn("No state cookie"); + return false; + } + // reset the cookie + Cookie reset = new Cookie(stateCookie.getName(), stateCookie.getValue()); + reset.setPath(stateCookie.getPath()); + reset.setMaxAge(0); + response.addCookie(reset); - String stateCookieValue = getCookieValue(realmInfo.getStateCookieName()); - // its ok to call request.getParameter() because this should be a redirect - String state = request.getParameter("state"); - if (state == null) - { - sendError(400); - log.warn("state parameter was null"); - return false; - } - if (!state.equals(stateCookieValue)) - { - sendError(400); - log.warn("state parameter invalid"); - log.warn("cookie: " + stateCookieValue); - log.warn("queryParam: " + state); - return false; - } - return true; + String stateCookieValue = getCookieValue(realmInfo.getStateCookieName()); + // its ok to call request.getParameter() because this should be a redirect + String state = request.getParameter("state"); + if (state == null) { + sendError(400); + log.warn("state parameter was null"); + return false; + } + if (!state.equals(stateCookieValue)) { + sendError(400); + log.warn("state parameter invalid"); + log.warn("cookie: " + stateCookieValue); + log.warn("queryParam: " + state); + return false; + } + return true; - } + } - /** - * Start or continue the oauth login process. - * - * if code query parameter is not present, then browser is redirected to authUrl. The redirect URL will be - * the URL of the current request. - * - * If code query parameter is present, then an access token is obtained by invoking a secure request to the codeUrl. - * If the access token is obtained, the browser is again redirected to the current request URL, but any OAuth - * protocol specific query parameters are removed. - * - * @return true if an access token was obtained - */ - public boolean resolveCode(String code) - { - // abort if not HTTPS - if (realmInfo.isSslRequired() && !isRequestSecure()) - { - log.error("SSL is required"); - sendError(Response.Status.FORBIDDEN.getStatusCode()); - return false; - } - - if (!checkStateCookie()) return false; - - String client_id = realmInfo.getClientId(); - String password = realmInfo.getCredentials().asMap().getFirst("password"); - String authHeader = BasicAuthHelper.createHeader(client_id, password); - String redirectUri = stripOauthParametersFromRedirect(); - Form form = new Form(); - form.param("grant_type", "authorization_code") - .param("code", code) - .param("redirect_uri", redirectUri); - - Response res = realmInfo.getCodeUrl().request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(form)); - AccessTokenResponse tokenResponse; - try - { - if (res.getStatus() != 200) - { - log.error("failed to turn code into token"); + /** + * Start or continue the oauth login process. + *

+ * if code query parameter is not present, then browser is redirected to authUrl. The redirect URL will be + * the URL of the current request. + *

+ * If code query parameter is present, then an access token is obtained by invoking a secure request to the codeUrl. + * If the access token is obtained, the browser is again redirected to the current request URL, but any OAuth + * protocol specific query parameters are removed. + * + * @return true if an access token was obtained + */ + public boolean resolveCode(String code) { + // abort if not HTTPS + if (realmInfo.isSslRequired() && !isRequestSecure()) { + log.error("SSL is required"); sendError(Response.Status.FORBIDDEN.getStatusCode()); return false; - } - log.debug("media type: " + res.getMediaType()); - log.debug("Content-Type header: " + res.getHeaderString("Content-Type")); - tokenResponse = res.readEntity(AccessTokenResponse.class); - } - finally - { - res.close(); - } + } - tokenString = tokenResponse.getToken(); - try - { - token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata()); - log.debug("Verification succeeded!"); - } - catch (VerificationException e) - { - log.error("failed verification of token"); - sendError(Response.Status.FORBIDDEN.getStatusCode()); - return false; - } - // redirect to URL without oauth query parameters - sendRedirect(redirectUri); - return true; - } + if (!checkStateCookie()) return false; - /** - * strip out unwanted query parameters and redirect so bookmarks don't retain oauth protocol bits - */ - protected String stripOauthParametersFromRedirect() - { - StringBuffer buf = request.getRequestURL().append("?").append(request.getQueryString()); - UriBuilder builder = UriBuilder.fromUri(buf.toString()) - .replaceQueryParam("code", null) - .replaceQueryParam("state", null); - return builder.build().toString(); - } + String client_id = realmInfo.getClientId(); + String password = realmInfo.getCredentials().asMap().getFirst("password"); + String authHeader = BasicAuthHelper.createHeader(client_id, password); + String redirectUri = stripOauthParametersFromRedirect(); + Form form = new Form(); + form.param("grant_type", "authorization_code") + .param("code", code) + .param("redirect_uri", redirectUri); + + Response res = realmInfo.getCodeUrl().request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(form)); + AccessTokenResponse tokenResponse; + try { + if (res.getStatus() != 200) { + log.error("failed to turn code into token"); + sendError(Response.Status.FORBIDDEN.getStatusCode()); + return false; + } + log.debug("media type: " + res.getMediaType()); + log.debug("Content-Type header: " + res.getHeaderString("Content-Type")); + tokenResponse = res.readEntity(AccessTokenResponse.class); + } finally { + res.close(); + } + + tokenString = tokenResponse.getToken(); + try { + token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata()); + log.debug("Verification succeeded!"); + } catch (VerificationException e) { + log.error("failed verification of token"); + sendError(Response.Status.FORBIDDEN.getStatusCode()); + return false; + } + // redirect to URL without oauth query parameters + sendRedirect(redirectUri); + return true; + } + + /** + * strip out unwanted query parameters and redirect so bookmarks don't retain oauth protocol bits + */ + protected String stripOauthParametersFromRedirect() { + StringBuffer buf = request.getRequestURL().append("?").append(request.getQueryString()); + UriBuilder builder = UriBuilder.fromUri(buf.toString()) + .replaceQueryParam("code", null) + .replaceQueryParam("state", null); + return builder.build().toString(); + } } diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/UserSessionManagement.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/UserSessionManagement.java index 081df776c6..0d18f1ac35 100755 --- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/UserSessionManagement.java +++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/UserSessionManagement.java @@ -18,94 +18,80 @@ import java.util.concurrent.ConcurrentHashMap; * @author Bill Burke * @version $Revision: 1 $ */ -public class UserSessionManagement implements SessionListener -{ - private static final Logger log = Logger.getLogger(UserSessionManagement.class); - protected ConcurrentHashMap> userSessionMap = new ConcurrentHashMap>(); +public class UserSessionManagement implements SessionListener { + private static final Logger log = Logger.getLogger(UserSessionManagement.class); + protected ConcurrentHashMap> userSessionMap = new ConcurrentHashMap>(); - protected void login(Session session, String username) - { - Map map = userSessionMap.get(username); - if (map == null) - { - final Map value = new HashMap(); - map = userSessionMap.putIfAbsent(username, value); - if (map == null) - { - map = value; - } - } - synchronized (map) - { - map.put(session.getId(), session); - } - session.addSessionListener(this); - } + protected void login(Session session, String username) { + Map map = userSessionMap.get(username); + if (map == null) { + final Map value = new HashMap(); + map = userSessionMap.putIfAbsent(username, value); + if (map == null) { + map = value; + } + } + synchronized (map) { + map.put(session.getId(), session); + } + session.addSessionListener(this); + } - public void logoutAll() - { - List users = new ArrayList(); - users.addAll(userSessionMap.keySet()); - for (String user : users) logout(user); - } + public void logoutAll() { + List users = new ArrayList(); + users.addAll(userSessionMap.keySet()); + for (String user : users) logout(user); + } - public void logoutAllBut(String but) - { - List users = new ArrayList(); - users.addAll(userSessionMap.keySet()); - for (String user : users) - { - if (!but.equals(user)) logout(user); - } - } + public void logoutAllBut(String but) { + List users = new ArrayList(); + users.addAll(userSessionMap.keySet()); + for (String user : users) { + if (!but.equals(user)) logout(user); + } + } - public void logout(String user) - { - log.debug("logoutUser: " + user); - Map map = userSessionMap.remove(user); - if (map == null) - { - log.debug("no session for user: " + user); - return; - } - log.debug("found session for user"); - synchronized (map) - { - for (Session session : map.values()) - { - log.debug("invalidating session for user: " + user); - session.setPrincipal(null); - session.setAuthType(null); - session.getSession().invalidate(); - } - } + public void logout(String user) { + log.debug("logoutUser: " + user); + Map map = userSessionMap.remove(user); + if (map == null) { + log.debug("no session for user: " + user); + return; + } + log.debug("found session for user"); + synchronized (map) { + for (Session session : map.values()) { + log.debug("invalidating session for user: " + user); + session.setPrincipal(null); + session.setAuthType(null); + session.getSession().invalidate(); + } + } - } + } - public void sessionEvent(SessionEvent event) - { - // We only care about session destroyed events - if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType()) - && (!Session.SESSION_PASSIVATED_EVENT.equals(event.getType()))) - return; + public void sessionEvent(SessionEvent event) { + // We only care about session destroyed events + if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType()) + && (!Session.SESSION_PASSIVATED_EVENT.equals(event.getType()))) + return; - // Look up the single session id associated with this session (if any) - Session session = event.getSession(); - GenericPrincipal principal = (GenericPrincipal) session.getPrincipal(); - if (principal == null) return; - session.setPrincipal(null); - session.setAuthType(null); + // Look up the single session id associated with this session (if any) + Session session = event.getSession(); + GenericPrincipal principal = (GenericPrincipal) session.getPrincipal(); + if (principal == null) return; + session.setPrincipal(null); + session.setAuthType(null); - String username = principal.getUserPrincipal().getName(); - Map map = userSessionMap.get(username); - if (map == null) return; - synchronized (map) - { - map.remove(session.getId()); - if (map.isEmpty()) userSessionMap.remove(username); - } + String username = principal.getUserPrincipal().getName(); + Map map = userSessionMap.get(username); + if (map == null) return; + synchronized (map) { + map.remove(session.getId()); + if (map.isEmpty()) userSessionMap.remove(username); + } - } + } } diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/AuthServerConfig.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/AuthServerConfig.java index 73372e3c83..ab8f38793a 100755 --- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/AuthServerConfig.java +++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/AuthServerConfig.java @@ -9,271 +9,229 @@ import java.util.List; * @author Bill Burke * @version $Revision: 1 $ */ -public class AuthServerConfig -{ - @JsonProperty("realm") - protected String realm; +public class AuthServerConfig { + @JsonProperty("realm") + protected String realm; - @JsonProperty("realm-private-key") - protected String realmPrivateKey; + @JsonProperty("realm-private-key") + protected String realmPrivateKey; - @JsonProperty("realm-public-key") - protected String realmPublicKey; + @JsonProperty("realm-public-key") + protected String realmPublicKey; - @JsonProperty("realm-keystore") - protected String realmKeyStore; + @JsonProperty("realm-keystore") + protected String realmKeyStore; - @JsonProperty("realm-keystore-password") - protected String realmKeystorePassword; + @JsonProperty("realm-keystore-password") + protected String realmKeystorePassword; - @JsonProperty("realm-key-alias") - protected String realmKeyAlias; + @JsonProperty("realm-key-alias") + protected String realmKeyAlias; - @JsonProperty("realm-private-key-password") - protected String realmPrivateKeyPassword; + @JsonProperty("realm-private-key-password") + protected String realmPrivateKeyPassword; - @JsonProperty("access-code-lifetime") - protected int accessCodeLifetime; + @JsonProperty("access-code-lifetime") + protected int accessCodeLifetime; - @JsonProperty("token-lifetime") - protected int tokenLifetime; + @JsonProperty("token-lifetime") + protected int tokenLifetime; - @JsonProperty("admin-role") - protected String adminRole; + @JsonProperty("admin-role") + protected String adminRole; - @JsonProperty("login-role") - protected String loginRole; + @JsonProperty("login-role") + protected String loginRole; - @JsonProperty("oauth-client-role") - protected String clientRole; + @JsonProperty("oauth-client-role") + protected String clientRole; - @JsonProperty("wildcard-role") - protected String wildcardRole; + @JsonProperty("wildcard-role") + protected String wildcardRole; - @JsonProperty("cancel-propagation") - protected boolean cancelPropagation; + @JsonProperty("cancel-propagation") + protected boolean cancelPropagation; - @JsonProperty("sso-disabled") - protected boolean ssoDisabled; + @JsonProperty("sso-disabled") + protected boolean ssoDisabled; - // these properties are optional and used to provide connection metadata when the server wants to make - // remote SSL connections + // these properties are optional and used to provide connection metadata when the server wants to make + // remote SSL connections - protected String truststore; - @JsonProperty("truststore-password") - protected String truststorePassword; - @JsonProperty("client-keystore") - protected String clientKeystore; - @JsonProperty("client-keystore-password") - protected String clientKeystorePassword; - @JsonProperty("client-key-password") - protected String clientKeyPassword; + protected String truststore; + @JsonProperty("truststore-password") + protected String truststorePassword; + @JsonProperty("client-keystore") + protected String clientKeystore; + @JsonProperty("client-keystore-password") + protected String clientKeystorePassword; + @JsonProperty("client-key-password") + protected String clientKeyPassword; - protected List resources = new ArrayList(); + protected List resources = new ArrayList(); - public String getRealm() - { - return realm; - } + public String getRealm() { + return realm; + } - public void setRealm(String realm) - { - this.realm = realm; - } + public void setRealm(String realm) { + this.realm = realm; + } - public String getRealmPrivateKey() - { - return realmPrivateKey; - } + public String getRealmPrivateKey() { + return realmPrivateKey; + } - public void setRealmPrivateKey(String realmPrivateKey) - { - this.realmPrivateKey = realmPrivateKey; - } + public void setRealmPrivateKey(String realmPrivateKey) { + this.realmPrivateKey = realmPrivateKey; + } - public String getRealmPublicKey() - { - return realmPublicKey; - } + public String getRealmPublicKey() { + return realmPublicKey; + } - public void setRealmPublicKey(String realmPublicKey) - { - this.realmPublicKey = realmPublicKey; - } + public void setRealmPublicKey(String realmPublicKey) { + this.realmPublicKey = realmPublicKey; + } - public int getAccessCodeLifetime() - { - return accessCodeLifetime; - } + public int getAccessCodeLifetime() { + return accessCodeLifetime; + } - public void setAccessCodeLifetime(int accessCodeLifetime) - { - this.accessCodeLifetime = accessCodeLifetime; - } + public void setAccessCodeLifetime(int accessCodeLifetime) { + this.accessCodeLifetime = accessCodeLifetime; + } - public String getTruststore() - { - return truststore; - } + public String getTruststore() { + return truststore; + } - public void setTruststore(String truststore) - { - this.truststore = truststore; - } + public void setTruststore(String truststore) { + this.truststore = truststore; + } - public String getTruststorePassword() - { - return truststorePassword; - } + public String getTruststorePassword() { + return truststorePassword; + } - public void setTruststorePassword(String truststorePassword) - { - this.truststorePassword = truststorePassword; - } + public void setTruststorePassword(String truststorePassword) { + this.truststorePassword = truststorePassword; + } - public String getClientKeystore() - { - return clientKeystore; - } + public String getClientKeystore() { + return clientKeystore; + } - public void setClientKeystore(String clientKeystore) - { - this.clientKeystore = clientKeystore; - } + public void setClientKeystore(String clientKeystore) { + this.clientKeystore = clientKeystore; + } - public String getClientKeystorePassword() - { - return clientKeystorePassword; - } + public String getClientKeystorePassword() { + return clientKeystorePassword; + } - public void setClientKeystorePassword(String clientKeystorePassword) - { - this.clientKeystorePassword = clientKeystorePassword; - } + public void setClientKeystorePassword(String clientKeystorePassword) { + this.clientKeystorePassword = clientKeystorePassword; + } - public String getClientKeyPassword() - { - return clientKeyPassword; - } + public String getClientKeyPassword() { + return clientKeyPassword; + } - public void setClientKeyPassword(String clientKeyPassword) - { - this.clientKeyPassword = clientKeyPassword; - } + public void setClientKeyPassword(String clientKeyPassword) { + this.clientKeyPassword = clientKeyPassword; + } - public boolean isCancelPropagation() - { - return cancelPropagation; - } + public boolean isCancelPropagation() { + return cancelPropagation; + } - public void setCancelPropagation(boolean cancelPropagation) - { - this.cancelPropagation = cancelPropagation; - } + public void setCancelPropagation(boolean cancelPropagation) { + this.cancelPropagation = cancelPropagation; + } - public boolean isSsoDisabled() - { - return ssoDisabled; - } + public boolean isSsoDisabled() { + return ssoDisabled; + } - public void setSsoDisabled(boolean ssoDisabled) - { - this.ssoDisabled = ssoDisabled; - } + public void setSsoDisabled(boolean ssoDisabled) { + this.ssoDisabled = ssoDisabled; + } - public List getResources() - { - return resources; - } + public List getResources() { + return resources; + } - public String getAdminRole() - { - return adminRole; - } + public String getAdminRole() { + return adminRole; + } - public void setAdminRole(String adminRole) - { - this.adminRole = adminRole; - } + public void setAdminRole(String adminRole) { + this.adminRole = adminRole; + } - public String getLoginRole() - { - return loginRole; - } + public String getLoginRole() { + return loginRole; + } - public void setLoginRole(String loginRole) - { - this.loginRole = loginRole; - } + public void setLoginRole(String loginRole) { + this.loginRole = loginRole; + } - public String getClientRole() - { - return clientRole; - } + public String getClientRole() { + return clientRole; + } - public void setClientRole(String clientRole) - { - this.clientRole = clientRole; - } + public void setClientRole(String clientRole) { + this.clientRole = clientRole; + } - public String getWildcardRole() - { - return wildcardRole; - } + public String getWildcardRole() { + return wildcardRole; + } - public void setWildcardRole(String wildcardRole) - { - this.wildcardRole = wildcardRole; - } + public void setWildcardRole(String wildcardRole) { + this.wildcardRole = wildcardRole; + } - public String getRealmKeyStore() - { - return realmKeyStore; - } + public String getRealmKeyStore() { + return realmKeyStore; + } - public void setRealmKeyStore(String realmKeyStore) - { - this.realmKeyStore = realmKeyStore; - } + public void setRealmKeyStore(String realmKeyStore) { + this.realmKeyStore = realmKeyStore; + } - public String getRealmKeystorePassword() - { - return realmKeystorePassword; - } + public String getRealmKeystorePassword() { + return realmKeystorePassword; + } - public void setRealmKeystorePassword(String realmKeystorePassword) - { - this.realmKeystorePassword = realmKeystorePassword; - } + public void setRealmKeystorePassword(String realmKeystorePassword) { + this.realmKeystorePassword = realmKeystorePassword; + } - public String getRealmKeyAlias() - { - return realmKeyAlias; - } + public String getRealmKeyAlias() { + return realmKeyAlias; + } - public void setRealmKeyAlias(String realmKeyAlias) - { - this.realmKeyAlias = realmKeyAlias; - } + public void setRealmKeyAlias(String realmKeyAlias) { + this.realmKeyAlias = realmKeyAlias; + } - public String getRealmPrivateKeyPassword() - { - return realmPrivateKeyPassword; - } + public String getRealmPrivateKeyPassword() { + return realmPrivateKeyPassword; + } - public void setRealmPrivateKeyPassword(String realmPrivateKeyPassword) - { - this.realmPrivateKeyPassword = realmPrivateKeyPassword; - } + public void setRealmPrivateKeyPassword(String realmPrivateKeyPassword) { + this.realmPrivateKeyPassword = realmPrivateKeyPassword; + } - public int getTokenLifetime() - { - return tokenLifetime; - } + public int getTokenLifetime() { + return tokenLifetime; + } - public void setTokenLifetime(int tokenLifetime) - { - this.tokenLifetime = tokenLifetime; - } + public void setTokenLifetime(int tokenLifetime) { + this.tokenLifetime = tokenLifetime; + } } 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 e1bef4bbec..140a69252c 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 @@ -10,204 +10,183 @@ import java.util.Map; * @author Bill Burke * @version $Revision: 1 $ */ -@JsonPropertyOrder({"realm", "resource", "realm-public-key", "admin-role", "auth-url", "code-url", "truststore", "truststore-password", "client-id", "client-credentials"}) -public class ManagedResourceConfig -{ - @JsonProperty("realm") - protected String realm; - @JsonProperty("resource") - protected String resource; +@JsonPropertyOrder({"realm-url", "realm", "resource", "realm-public-key", "admin-role", "auth-url", "code-url", "allow-any-hostname", "disable-trust-manager", "truststore", "truststore-password", "client-id", "client-credentials"}) +public class ManagedResourceConfig { + @JsonProperty("realm-url") + protected String realmUrl; + @JsonProperty("realm") + protected String realm; + @JsonProperty("resource") + protected String resource; + @JsonProperty("realm-public-key") + protected String realmKey; + @JsonProperty("admin-role") + protected String adminRole; + @JsonProperty("auth-url") + protected String authUrl; + @JsonProperty("code-url") + protected String codeUrl; - @JsonProperty("realm-public-key") - protected String realmKey; + @JsonProperty("allow-any-hostname") + protected boolean allowAnyHostname; + @JsonProperty("disable-trust-manager") + protected boolean disableTrustManager; + @JsonProperty("truststore") + 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 clientCredentials = new HashMap(); + @JsonProperty("connection-pool-size") + protected int connectionPoolSize; + @JsonProperty("cancel-propagation") + protected boolean cancelPropagation; - @JsonProperty("admin-role") - protected String adminRole; + public String getRealmUrl() { + return realmUrl; + } - @JsonProperty("auth-url") - protected String authUrl; - @JsonProperty("code-url") - protected String codeUrl; + public void setRealmUrl(String realmUrl) { + this.realmUrl = realmUrl; + } - @JsonProperty("allow-any-hostname") - protected boolean allowAnyHostname; + public String getRealm() { + return realm; + } - @JsonProperty("truststore") - protected String truststore; + public void setRealm(String realm) { + this.realm = realm; + } - @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; + public String getResource() { + return resource; + } - @JsonProperty("client-credentials") - protected Map clientCredentials = new HashMap(); + public void setResource(String resource) { + this.resource = resource; + } - @JsonProperty("connection-pool-size") - protected int connectionPoolSize; + public String getRealmKey() { + return realmKey; + } - @JsonProperty("cancel-propagation") - protected boolean cancelPropagation; + public void setRealmKey(String realmKey) { + this.realmKey = realmKey; + } + public String getAuthUrl() { + return authUrl; + } - public String getRealm() - { - return realm; - } + public void setAuthUrl(String authUrl) { + this.authUrl = authUrl; + } - public void setRealm(String realm) - { - this.realm = realm; - } + public String getCodeUrl() { + return codeUrl; + } - public String getResource() - { - return resource; - } + public void setCodeUrl(String codeUrl) { + this.codeUrl = codeUrl; + } - public void setResource(String resource) - { - this.resource = resource; - } + public boolean isAllowAnyHostname() { + return allowAnyHostname; + } - public String getRealmKey() - { - return realmKey; - } + public void setAllowAnyHostname(boolean allowAnyHostname) { + this.allowAnyHostname = allowAnyHostname; + } - public void setRealmKey(String realmKey) - { - this.realmKey = realmKey; - } + public boolean isDisableTrustManager() { + return disableTrustManager; + } - public String getAuthUrl() - { - return authUrl; - } + public void setDisableTrustManager(boolean disableTrustManager) { + this.disableTrustManager = disableTrustManager; + } - public void setAuthUrl(String authUrl) - { - this.authUrl = authUrl; - } + public String getTruststore() { + return truststore; + } - public String getCodeUrl() - { - return codeUrl; - } + public void setTruststore(String truststore) { + this.truststore = truststore; + } - public void setCodeUrl(String codeUrl) - { - this.codeUrl = codeUrl; - } + public String getTruststorePassword() { + return truststorePassword; + } - public boolean isAllowAnyHostname() - { - return allowAnyHostname; - } + public void setTruststorePassword(String truststorePassword) { + this.truststorePassword = truststorePassword; + } - public void setAllowAnyHostname(boolean allowAnyHostname) - { - this.allowAnyHostname = allowAnyHostname; - } + public String getClientId() { + return clientId; + } - public String getTruststore() - { - return truststore; - } + public void setClientId(String clientId) { + this.clientId = clientId; + } - public void setTruststore(String truststore) - { - this.truststore = truststore; - } + public Map getClientCredentials() { + return clientCredentials; + } - public String getTruststorePassword() - { - return truststorePassword; - } + public String getClientKeystore() { + return clientKeystore; + } - public void setTruststorePassword(String truststorePassword) - { - this.truststorePassword = truststorePassword; - } + public void setClientKeystore(String clientKeystore) { + this.clientKeystore = clientKeystore; + } - public String getClientId() - { - return clientId; - } + public String getClientKeystorePassword() { + return clientKeystorePassword; + } - public void setClientId(String clientId) - { - this.clientId = clientId; - } + public void setClientKeystorePassword(String clientKeystorePassword) { + this.clientKeystorePassword = clientKeystorePassword; + } - public Map getClientCredentials() - { - return clientCredentials; - } + public String getClientKeyPassword() { + return clientKeyPassword; + } - public String getClientKeystore() - { - return clientKeystore; - } + public void setClientKeyPassword(String clientKeyPassword) { + this.clientKeyPassword = clientKeyPassword; + } - public void setClientKeystore(String clientKeystore) - { - this.clientKeystore = clientKeystore; - } + public int getConnectionPoolSize() { + return connectionPoolSize; + } - public String getClientKeystorePassword() - { - return clientKeystorePassword; - } + public void setConnectionPoolSize(int connectionPoolSize) { + this.connectionPoolSize = connectionPoolSize; + } - public void setClientKeystorePassword(String clientKeystorePassword) - { - this.clientKeystorePassword = clientKeystorePassword; - } + public boolean isCancelPropagation() { + return cancelPropagation; + } - public String getClientKeyPassword() - { - return clientKeyPassword; - } + public void setCancelPropagation(boolean cancelPropagation) { + this.cancelPropagation = cancelPropagation; + } - public void setClientKeyPassword(String clientKeyPassword) - { - this.clientKeyPassword = clientKeyPassword; - } + public String getAdminRole() { + return adminRole; + } - public int getConnectionPoolSize() - { - return connectionPoolSize; - } - - public void setConnectionPoolSize(int connectionPoolSize) - { - this.connectionPoolSize = connectionPoolSize; - } - - public boolean isCancelPropagation() - { - return cancelPropagation; - } - - public void setCancelPropagation(boolean cancelPropagation) - { - this.cancelPropagation = cancelPropagation; - } - - public String getAdminRole() - { - return adminRole; - } - - public void setAdminRole(String adminRole) - { - this.adminRole = adminRole; - } + public void setAdminRole(String adminRole) { + this.adminRole = adminRole; + } } 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 75339d1054..d40dd88781 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 @@ -4,10 +4,16 @@ import org.apache.catalina.Context; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonSerialize; 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.spi.ResteasyProviderFactory; import org.keycloak.EnvUtil; import org.keycloak.PemUtils; import org.keycloak.ResourceMetadata; +import org.keycloak.representations.idm.PublishedRealmRepresentation; +import javax.ws.rs.client.WebTarget; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -16,124 +22,166 @@ import java.io.InputStream; import java.security.KeyStore; import java.security.PublicKey; -public class ManagedResourceConfigLoader -{ - static final Logger log = Logger.getLogger(ManagedResourceConfigLoader.class); - protected ManagedResourceConfig remoteSkeletonKeyConfig; - protected ResourceMetadata resourceMetadata; +public class ManagedResourceConfigLoader { + static final Logger log = Logger.getLogger(ManagedResourceConfigLoader.class); + protected ManagedResourceConfig remoteSkeletonKeyConfig; + protected ResourceMetadata resourceMetadata; + protected KeyStore clientCertKeystore; + protected KeyStore truststore; + protected ResteasyClient client; - public ManagedResourceConfigLoader(Context context) - { - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); - InputStream is = null; - String path = context.getServletContext().getInitParameter("skeleton.key.config.file"); - if (path == null) - { - is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json"); - } - else - { - try - { - is = new FileInputStream(path); - } - catch (FileNotFoundException e) - { + public ManagedResourceConfigLoader(Context context) { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); + InputStream is = null; + String path = context.getServletContext().getInitParameter("keycloak.config.file"); + if (path == null) { + is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json"); + } else { + try { + is = new FileInputStream(path); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + remoteSkeletonKeyConfig = null; + try { + remoteSkeletonKeyConfig = mapper.readValue(is, ManagedResourceConfig.class); + } catch (IOException e) { throw new RuntimeException(e); - } - } - remoteSkeletonKeyConfig = null; - try - { - remoteSkeletonKeyConfig = mapper.readValue(is, ManagedResourceConfig.class); - } - catch (IOException e) - { - throw new RuntimeException(e); - } + } + } - String name = remoteSkeletonKeyConfig.getResource(); - String realm = remoteSkeletonKeyConfig.getRealm(); - if (realm == null) throw new RuntimeException("Must set 'realm' in config"); - - String realmKeyPem = remoteSkeletonKeyConfig.getRealmKey(); - if (realmKeyPem == null) - { - throw new IllegalArgumentException("You must set the realm-public-key"); - } - - PublicKey realmKey = null; - try - { - realmKey = PemUtils.decodePublicKey(realmKeyPem); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - resourceMetadata = new ResourceMetadata(); - resourceMetadata.setRealm(realm); - resourceMetadata.setResourceName(name); - resourceMetadata.setRealmKey(realmKey); + public void init(boolean setupClient) { - String truststore = remoteSkeletonKeyConfig.getTruststore(); - if (truststore != null) - { - truststore = EnvUtil.replace(truststore); - String truststorePassword = remoteSkeletonKeyConfig.getTruststorePassword(); - KeyStore trust = null; - try - { - trust = loadKeyStore(truststore, truststorePassword); - } - catch (Exception e) - { - throw new RuntimeException("Failed to load truststore", e); - } - resourceMetadata.setTruststore(trust); - } - String clientKeystore = remoteSkeletonKeyConfig.getClientKeystore(); - String clientKeyPassword = null; - if (clientKeystore != null) - { - clientKeystore = EnvUtil.replace(clientKeystore); - String clientKeystorePassword = remoteSkeletonKeyConfig.getClientKeystorePassword(); - KeyStore serverKS = null; - try - { - serverKS = loadKeyStore(clientKeystore, clientKeystorePassword); - } - catch (Exception e) - { - throw new RuntimeException("Failed to load keystore", e); - } - resourceMetadata.setClientKeystore(serverKS); - clientKeyPassword = remoteSkeletonKeyConfig.getClientKeyPassword(); - resourceMetadata.setClientKeyPassword(clientKeyPassword); - } - } - public static KeyStore loadKeyStore(String filename, String password) throws Exception - { - KeyStore trustStore = KeyStore.getInstance(KeyStore - .getDefaultType()); - File truststoreFile = new File(filename); - FileInputStream trustStream = new FileInputStream(truststoreFile); - trustStore.load(trustStream, password.toCharArray()); - trustStream.close(); - return trustStore; - } + String truststorePath = remoteSkeletonKeyConfig.getTruststore(); + if (truststorePath != null) { + truststorePath = EnvUtil.replace(truststorePath); + String truststorePassword = remoteSkeletonKeyConfig.getTruststorePassword(); + truststorePath = null; + try { + this.truststore = loadKeyStore(truststorePath, truststorePassword); + } catch (Exception e) { + throw new RuntimeException("Failed to load truststore", e); + } + } + String clientKeystore = remoteSkeletonKeyConfig.getClientKeystore(); + String clientKeyPassword = null; + if (clientKeystore != null) { + clientKeystore = EnvUtil.replace(clientKeystore); + String clientKeystorePassword = remoteSkeletonKeyConfig.getClientKeystorePassword(); + clientCertKeystore = null; + try { + clientCertKeystore = loadKeyStore(clientKeystore, clientKeystorePassword); + } catch (Exception e) { + throw new RuntimeException("Failed to load keystore", e); + } + } - public ManagedResourceConfig getRemoteSkeletonKeyConfig() - { - return remoteSkeletonKeyConfig; - } + initClient(); - public ResourceMetadata getResourceMetadata() - { - return resourceMetadata; - } + String realm = remoteSkeletonKeyConfig.getRealm(); + if (remoteSkeletonKeyConfig.getRealmUrl() != null) { + PublishedRealmRepresentation rep = null; + try { + rep = client.target(remoteSkeletonKeyConfig.getRealmUrl()).request().get(PublishedRealmRepresentation.class); + } finally { + if (!setupClient) { + client.close(); + } + } + remoteSkeletonKeyConfig.setRealm(rep.getRealm()); + remoteSkeletonKeyConfig.setAuthUrl(rep.getAuthorizationUrl()); + remoteSkeletonKeyConfig.setCodeUrl(rep.getCodeUrl()); + remoteSkeletonKeyConfig.setRealmKey(rep.getPublicKeyPem()); + remoteSkeletonKeyConfig.setAdminRole(rep.getAdminRole()); + } + + String resource = remoteSkeletonKeyConfig.getResource(); + if (realm == null) throw new RuntimeException("Must set 'realm' in config"); + + String realmKeyPem = remoteSkeletonKeyConfig.getRealmKey(); + if (realmKeyPem == null) { + throw new IllegalArgumentException("You must set the realm-public-key"); + } + + PublicKey realmKey = null; + try { + realmKey = PemUtils.decodePublicKey(realmKeyPem); + } catch (Exception e) { + throw new RuntimeException(e); + } + + resourceMetadata = new ResourceMetadata(); + resourceMetadata.setRealm(realm); + resourceMetadata.setResourceName(resource); + resourceMetadata.setRealmKey(realmKey); + resourceMetadata.setClientKeystore(clientCertKeystore); + clientKeyPassword = remoteSkeletonKeyConfig.getClientKeyPassword(); + resourceMetadata.setClientKeyPassword(clientKeyPassword); + resourceMetadata.setTruststore(this.truststore); + + } + + protected void initClient() { + int size = 10; + if (remoteSkeletonKeyConfig.getConnectionPoolSize() > 0) + size = remoteSkeletonKeyConfig.getConnectionPoolSize(); + ResteasyClientBuilder.HostnameVerificationPolicy policy = ResteasyClientBuilder.HostnameVerificationPolicy.WILDCARD; + if (remoteSkeletonKeyConfig.isAllowAnyHostname()) + policy = ResteasyClientBuilder.HostnameVerificationPolicy.ANY; + ResteasyProviderFactory providerFactory = new ResteasyProviderFactory(); + ClassLoader old = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(ManagedResourceConfigLoader.class.getClassLoader()); + try { + ResteasyProviderFactory.getInstance(); // initialize builtins + RegisterBuiltin.register(providerFactory); + } finally { + Thread.currentThread().setContextClassLoader(old); + } + ResteasyClientBuilder builder = new ResteasyClientBuilder() + .providerFactory(providerFactory) + .connectionPoolSize(size) + .hostnameVerification(policy) + .keyStore(clientCertKeystore, remoteSkeletonKeyConfig.getClientKeyPassword()); + if (remoteSkeletonKeyConfig.isDisableTrustManager()) { + builder.disableTrustManager(); + } else { + builder.trustStore(truststore); + } + client = builder.build(); + } + + public static KeyStore loadKeyStore(String filename, String password) throws Exception { + KeyStore trustStore = KeyStore.getInstance(KeyStore + .getDefaultType()); + File truststoreFile = new File(filename); + FileInputStream trustStream = new FileInputStream(truststoreFile); + trustStore.load(trustStream, password.toCharArray()); + trustStream.close(); + return trustStore; + } + + public ManagedResourceConfig getRemoteSkeletonKeyConfig() { + return remoteSkeletonKeyConfig; + } + + public ResourceMetadata getResourceMetadata() { + return resourceMetadata; + } + + public ResteasyClient getClient() { + return client; + } + + public KeyStore getClientCertKeystore() { + return clientCertKeystore; + } + + public KeyStore getTruststore() { + return truststore; + } } \ No newline at end of file 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 7b82cebdee..0a37be3099 100755 --- a/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java @@ -19,6 +19,7 @@ import javax.ws.rs.core.UriInfo; */ public class RealmSubResource { protected static final Logger logger = Logger.getLogger(RealmSubResource.class); + public static final String ADMIN_ROLE = "$REALM-ADMIN$"; @Context protected UriInfo uriInfo; @@ -32,8 +33,13 @@ public class RealmSubResource { this.realm = realm; } + public static UriBuilder realmUrl(UriInfo uriInfo) { + UriBuilder base = uriInfo.getBaseUriBuilder() + .path(RealmsResource.class).path(RealmsResource.class, "getRealmResource"); + return base; + } + @GET - @Path("json") @Produces("application/json") public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) { return realmRep(realm, uriInfo); @@ -65,26 +71,14 @@ public class RealmSubResource { public static PublishedRealmRepresentation realmRep(RealmModel realm, UriInfo uriInfo) { PublishedRealmRepresentation rep = new PublishedRealmRepresentation(); rep.setRealm(realm.getName()); - rep.setSelf(uriInfo.getRequestUri().toString()); + rep.setSelf(realmUrl(uriInfo).build(realm.getId()).toString()); rep.setPublicKeyPem(realm.getPublicKeyPem()); + rep.setAdminRole(ADMIN_ROLE); - UriBuilder auth = uriInfo.getBaseUriBuilder(); - auth.path(RealmsResource.class).path(RealmsResource.class, "getTokenService") - .path(TokenService.class, "requestAccessCode"); - rep.setAuthorizationUrl(auth.build(realm.getId()).toString()); - - UriBuilder code = uriInfo.getBaseUriBuilder(); - code.path(RealmsResource.class).path(RealmsResource.class, "getTokenService").path(TokenService.class, "accessRequest"); - rep.setCodeUrl(code.build(realm.getId()).toString()); - - UriBuilder grant = uriInfo.getBaseUriBuilder(); - grant.path(RealmsResource.class).path(RealmsResource.class, "getTokenService").path(TokenService.class, "accessTokenGrant"); - String grantUrl = grant.build(realm.getId()).toString(); - rep.setGrantUrl(grantUrl); - - UriBuilder idGrant = uriInfo.getBaseUriBuilder(); - grant.path(RealmsResource.class).path(RealmsResource.class, "getTokenService").path(TokenService.class, "identityTokenGrant"); - String idGrantUrl = idGrant.build(realm.getId()).toString(); + rep.setAuthorizationUrl(TokenService.loginPage(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.setIdentityGrantUrl(idGrantUrl); return rep; }