commit
2e45334ee2
38 changed files with 3141 additions and 3800 deletions
|
@ -1,8 +1,8 @@
|
||||||
package org.keycloak;
|
package org.keycloak;
|
||||||
|
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||||
import org.keycloak.representations.AccessTokenResponse;
|
|
||||||
import org.jboss.resteasy.util.BasicAuthHelper;
|
import org.jboss.resteasy.util.BasicAuthHelper;
|
||||||
|
import org.keycloak.representations.AccessTokenResponse;
|
||||||
|
|
||||||
import javax.ws.rs.BadRequestException;
|
import javax.ws.rs.BadRequestException;
|
||||||
import javax.ws.rs.InternalServerErrorException;
|
import javax.ws.rs.InternalServerErrorException;
|
||||||
|
@ -20,8 +20,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class AbstractOAuthClient
|
public class AbstractOAuthClient {
|
||||||
{
|
|
||||||
protected String clientId;
|
protected String clientId;
|
||||||
protected String password;
|
protected String password;
|
||||||
protected KeyStore truststore;
|
protected KeyStore truststore;
|
||||||
|
@ -31,15 +30,12 @@ public class AbstractOAuthClient
|
||||||
protected Client client;
|
protected Client client;
|
||||||
protected final AtomicLong counter = new AtomicLong();
|
protected final AtomicLong counter = new AtomicLong();
|
||||||
|
|
||||||
protected String getStateCode()
|
protected String getStateCode() {
|
||||||
{
|
|
||||||
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
|
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start()
|
public void start() {
|
||||||
{
|
if (client == null) {
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
client = new ResteasyClientBuilder().trustStore(truststore)
|
client = new ResteasyClientBuilder().trustStore(truststore)
|
||||||
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY)
|
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY)
|
||||||
.connectionPoolSize(10)
|
.connectionPoolSize(10)
|
||||||
|
@ -47,83 +43,67 @@ public class AbstractOAuthClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop()
|
public void stop() {
|
||||||
{
|
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientId()
|
public String getClientId() {
|
||||||
{
|
|
||||||
return clientId;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientId(String clientId)
|
public void setClientId(String clientId) {
|
||||||
{
|
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPassword()
|
public String getPassword() {
|
||||||
{
|
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPassword(String password)
|
public void setPassword(String password) {
|
||||||
{
|
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyStore getTruststore()
|
public KeyStore getTruststore() {
|
||||||
{
|
|
||||||
return truststore;
|
return truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTruststore(KeyStore truststore)
|
public void setTruststore(KeyStore truststore) {
|
||||||
{
|
|
||||||
this.truststore = truststore;
|
this.truststore = truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthUrl()
|
public String getAuthUrl() {
|
||||||
{
|
|
||||||
return authUrl;
|
return authUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthUrl(String authUrl)
|
public void setAuthUrl(String authUrl) {
|
||||||
{
|
|
||||||
this.authUrl = authUrl;
|
this.authUrl = authUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCodeUrl()
|
public String getCodeUrl() {
|
||||||
{
|
|
||||||
return codeUrl;
|
return codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCodeUrl(String codeUrl)
|
public void setCodeUrl(String codeUrl) {
|
||||||
{
|
|
||||||
this.codeUrl = codeUrl;
|
this.codeUrl = codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStateCookieName()
|
public String getStateCookieName() {
|
||||||
{
|
|
||||||
return stateCookieName;
|
return stateCookieName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStateCookieName(String stateCookieName)
|
public void setStateCookieName(String stateCookieName) {
|
||||||
{
|
|
||||||
this.stateCookieName = stateCookieName;
|
this.stateCookieName = stateCookieName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Client getClient()
|
public Client getClient() {
|
||||||
{
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClient(Client client)
|
public void setClient(Client client) {
|
||||||
{
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String resolveBearerToken(String redirectUri, String code)
|
public String resolveBearerToken(String redirectUri, String code) {
|
||||||
{
|
|
||||||
redirectUri = stripOauthParametersFromRedirect(redirectUri);
|
redirectUri = stripOauthParametersFromRedirect(redirectUri);
|
||||||
String authHeader = BasicAuthHelper.createHeader(clientId, password);
|
String authHeader = BasicAuthHelper.createHeader(clientId, password);
|
||||||
Form codeForm = new Form()
|
Form codeForm = new Form()
|
||||||
|
@ -131,27 +111,20 @@ public class AbstractOAuthClient
|
||||||
.param("code", code)
|
.param("code", code)
|
||||||
.param("redirect_uri", redirectUri);
|
.param("redirect_uri", redirectUri);
|
||||||
Response res = client.target(codeUrl).request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(codeForm));
|
Response res = client.target(codeUrl).request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(codeForm));
|
||||||
try
|
try {
|
||||||
{
|
if (res.getStatus() == 400) {
|
||||||
if (res.getStatus() == 400)
|
|
||||||
{
|
|
||||||
throw new BadRequestException();
|
throw new BadRequestException();
|
||||||
}
|
} else if (res.getStatus() != 200) {
|
||||||
else if (res.getStatus() != 200)
|
|
||||||
{
|
|
||||||
throw new InternalServerErrorException(new Exception("Unknown error when getting acess token"));
|
throw new InternalServerErrorException(new Exception("Unknown error when getting acess token"));
|
||||||
}
|
}
|
||||||
AccessTokenResponse tokenResponse = res.readEntity(AccessTokenResponse.class);
|
AccessTokenResponse tokenResponse = res.readEntity(AccessTokenResponse.class);
|
||||||
return tokenResponse.getToken();
|
return tokenResponse.getToken();
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
res.close();
|
res.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String stripOauthParametersFromRedirect(String uri)
|
protected String stripOauthParametersFromRedirect(String uri) {
|
||||||
{
|
|
||||||
System.out.println("******************** redirect_uri: " + uri);
|
System.out.println("******************** redirect_uri: " + uri);
|
||||||
UriBuilder builder = UriBuilder.fromUri(uri)
|
UriBuilder builder = UriBuilder.fromUri(uri)
|
||||||
.replaceQueryParam("code", null)
|
.replaceQueryParam("code", null)
|
||||||
|
|
|
@ -8,15 +8,12 @@ import java.security.Security;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class BouncyIntegration
|
public class BouncyIntegration {
|
||||||
{
|
static {
|
||||||
static
|
|
||||||
{
|
|
||||||
if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider());
|
if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init()
|
public static void init() {
|
||||||
{
|
|
||||||
// empty, the static class does it
|
// empty, the static class does it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,16 +20,13 @@ import java.security.spec.X509EncodedKeySpec;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class DerUtils
|
public class DerUtils {
|
||||||
{
|
static {
|
||||||
static
|
|
||||||
{
|
|
||||||
BouncyIntegration.init();
|
BouncyIntegration.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PrivateKey decodePrivateKey(InputStream is)
|
public static PrivateKey decodePrivateKey(InputStream is)
|
||||||
throws Exception
|
throws Exception {
|
||||||
{
|
|
||||||
|
|
||||||
DataInputStream dis = new DataInputStream(is);
|
DataInputStream dis = new DataInputStream(is);
|
||||||
byte[] keyBytes = new byte[dis.available()];
|
byte[] keyBytes = new byte[dis.available()];
|
||||||
|
@ -42,24 +39,21 @@ public class DerUtils
|
||||||
return kf.generatePrivate(spec);
|
return kf.generatePrivate(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PublicKey decodePublicKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException
|
public static PublicKey decodePublicKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
|
||||||
{
|
|
||||||
X509EncodedKeySpec spec =
|
X509EncodedKeySpec spec =
|
||||||
new X509EncodedKeySpec(der);
|
new X509EncodedKeySpec(der);
|
||||||
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
|
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
|
||||||
return kf.generatePublic(spec);
|
return kf.generatePublic(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate decodeCertificate(InputStream is) throws Exception
|
public static X509Certificate decodeCertificate(InputStream is) throws Exception {
|
||||||
{
|
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
|
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
|
||||||
X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
|
X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
|
||||||
is.close();
|
is.close();
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException
|
public static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
|
||||||
{
|
|
||||||
PKCS8EncodedKeySpec spec =
|
PKCS8EncodedKeySpec spec =
|
||||||
new PKCS8EncodedKeySpec(der);
|
new PKCS8EncodedKeySpec(der);
|
||||||
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
|
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
|
||||||
|
|
|
@ -7,8 +7,7 @@ import java.util.regex.Pattern;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class EnvUtil
|
public class EnvUtil {
|
||||||
{
|
|
||||||
private static final Pattern p = Pattern.compile("[$][{]([^}]+)[}]");
|
private static final Pattern p = Pattern.compile("[$][{]([^}]+)[}]");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,12 +16,10 @@ public class EnvUtil
|
||||||
* @param val
|
* @param val
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String replace(String val)
|
public static String replace(String val) {
|
||||||
{
|
|
||||||
Matcher matcher = p.matcher(val);
|
Matcher matcher = p.matcher(val);
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
while (matcher.find())
|
while (matcher.find()) {
|
||||||
{
|
|
||||||
String envVar = matcher.group(1);
|
String envVar = matcher.group(1);
|
||||||
String envVal = System.getProperty(envVar);
|
String envVal = System.getProperty(envVar);
|
||||||
if (envVal == null) envVal = "NOT-SPECIFIED";
|
if (envVal == null) envVal = "NOT-SPECIFIED";
|
||||||
|
|
|
@ -16,21 +16,18 @@ import java.security.cert.X509Certificate;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class PemUtils
|
public class PemUtils {
|
||||||
{
|
static {
|
||||||
static
|
|
||||||
{
|
|
||||||
BouncyIntegration.init();
|
BouncyIntegration.init();
|
||||||
}
|
}
|
||||||
public static X509Certificate decodeCertificate(InputStream is) throws Exception
|
|
||||||
{
|
public static X509Certificate decodeCertificate(InputStream is) throws Exception {
|
||||||
byte[] der = pemToDer(is);
|
byte[] der = pemToDer(is);
|
||||||
ByteArrayInputStream bis = new ByteArrayInputStream(der);
|
ByteArrayInputStream bis = new ByteArrayInputStream(der);
|
||||||
return DerUtils.decodeCertificate(bis);
|
return DerUtils.decodeCertificate(bis);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate decodeCertificate(String cert) throws Exception
|
public static X509Certificate decodeCertificate(String cert) throws Exception {
|
||||||
{
|
|
||||||
byte[] der = pemToDer(cert);
|
byte[] der = pemToDer(cert);
|
||||||
ByteArrayInputStream bis = new ByteArrayInputStream(der);
|
ByteArrayInputStream bis = new ByteArrayInputStream(der);
|
||||||
return DerUtils.decodeCertificate(bis);
|
return DerUtils.decodeCertificate(bis);
|
||||||
|
@ -44,8 +41,7 @@ public class PemUtils
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static PublicKey decodePublicKey(String pem) throws Exception
|
public static PublicKey decodePublicKey(String pem) throws Exception {
|
||||||
{
|
|
||||||
byte[] der = pemToDer(pem);
|
byte[] der = pemToDer(pem);
|
||||||
return DerUtils.decodePublicKey(der);
|
return DerUtils.decodePublicKey(der);
|
||||||
}
|
}
|
||||||
|
@ -57,14 +53,12 @@ public class PemUtils
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static PrivateKey decodePrivateKey(String pem) throws Exception
|
public static PrivateKey decodePrivateKey(String pem) throws Exception {
|
||||||
{
|
|
||||||
byte[] der = pemToDer(pem);
|
byte[] der = pemToDer(pem);
|
||||||
return DerUtils.decodePrivateKey(der);
|
return DerUtils.decodePrivateKey(der);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PrivateKey decodePrivateKey(InputStream is) throws Exception
|
public static PrivateKey decodePrivateKey(InputStream is) throws Exception {
|
||||||
{
|
|
||||||
String pem = pemFromStream(is);
|
String pem = pemFromStream(is);
|
||||||
return decodePrivateKey(pem);
|
return decodePrivateKey(pem);
|
||||||
}
|
}
|
||||||
|
@ -76,8 +70,7 @@ public class PemUtils
|
||||||
* @return
|
* @return
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
public static byte[] pemToDer(InputStream is) throws IOException
|
public static byte[] pemToDer(InputStream is) throws IOException {
|
||||||
{
|
|
||||||
String pem = pemFromStream(is);
|
String pem = pemFromStream(is);
|
||||||
byte[] der = pemToDer(pem);
|
byte[] der = pemToDer(pem);
|
||||||
return der;
|
return der;
|
||||||
|
@ -90,14 +83,12 @@ public class PemUtils
|
||||||
* @return
|
* @return
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
public static byte[] pemToDer(String pem) throws IOException
|
public static byte[] pemToDer(String pem) throws IOException {
|
||||||
{
|
|
||||||
pem = removeBeginEnd(pem);
|
pem = removeBeginEnd(pem);
|
||||||
return Base64.decode(pem);
|
return Base64.decode(pem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String removeBeginEnd(String pem)
|
public static String removeBeginEnd(String pem) {
|
||||||
{
|
|
||||||
pem = pem.replaceAll("-----BEGIN (.*)-----", "");
|
pem = pem.replaceAll("-----BEGIN (.*)-----", "");
|
||||||
pem = pem.replaceAll("-----END (.*)----", "");
|
pem = pem.replaceAll("-----END (.*)----", "");
|
||||||
pem = pem.replaceAll("\r\n", "");
|
pem = pem.replaceAll("\r\n", "");
|
||||||
|
@ -106,8 +97,7 @@ public class PemUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String pemFromStream(InputStream is) throws IOException
|
public static String pemFromStream(InputStream is) throws IOException {
|
||||||
{
|
|
||||||
DataInputStream dis = new DataInputStream(is);
|
DataInputStream dis = new DataInputStream(is);
|
||||||
byte[] keyBytes = new byte[dis.available()];
|
byte[] keyBytes = new byte[dis.available()];
|
||||||
dis.readFully(keyBytes);
|
dis.readFully(keyBytes);
|
||||||
|
|
|
@ -12,49 +12,37 @@ import java.security.PublicKey;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class RSATokenVerifier
|
public class RSATokenVerifier {
|
||||||
{
|
public static SkeletonKeyToken verifyToken(String tokenString, ResourceMetadata metadata) throws VerificationException {
|
||||||
public static SkeletonKeyToken verifyToken(String tokenString, ResourceMetadata metadata) throws VerificationException
|
|
||||||
{
|
|
||||||
PublicKey realmKey = metadata.getRealmKey();
|
PublicKey realmKey = metadata.getRealmKey();
|
||||||
String realm = metadata.getRealm();
|
String realm = metadata.getRealm();
|
||||||
return verifyToken(tokenString, realmKey, realm);
|
return verifyToken(tokenString, realmKey, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SkeletonKeyToken verifyToken(String tokenString, PublicKey realmKey, String realm) throws VerificationException
|
public static SkeletonKeyToken verifyToken(String tokenString, PublicKey realmKey, String realm) throws VerificationException {
|
||||||
{
|
|
||||||
JWSInput input = new JWSInput(tokenString);
|
JWSInput input = new JWSInput(tokenString);
|
||||||
boolean verified = false;
|
boolean verified = false;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
verified = RSAProvider.verify(input, realmKey);
|
verified = RSAProvider.verify(input, realmKey);
|
||||||
}
|
} catch (Exception ignore) {
|
||||||
catch (Exception ignore)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!verified) throw new VerificationException("Token signature not validated");
|
if (!verified) throw new VerificationException("Token signature not validated");
|
||||||
|
|
||||||
SkeletonKeyToken token = null;
|
SkeletonKeyToken token = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
token = JsonSerialization.fromBytes(SkeletonKeyToken.class, input.getContent());
|
token = JsonSerialization.fromBytes(SkeletonKeyToken.class, input.getContent());
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new VerificationException(e);
|
throw new VerificationException(e);
|
||||||
}
|
}
|
||||||
if (!token.isActive())
|
if (!token.isActive()) {
|
||||||
{
|
|
||||||
throw new VerificationException("Token is not active.");
|
throw new VerificationException("Token is not active.");
|
||||||
}
|
}
|
||||||
String user = token.getPrincipal();
|
String user = token.getPrincipal();
|
||||||
if (user == null)
|
if (user == null) {
|
||||||
{
|
|
||||||
throw new VerificationException("Token user was null");
|
throw new VerificationException("Token user was null");
|
||||||
}
|
}
|
||||||
if (!realm.equals(token.getAudience()))
|
if (!realm.equals(token.getAudience())) {
|
||||||
{
|
|
||||||
throw new VerificationException("Token audience doesn't match domain");
|
throw new VerificationException("Token audience doesn't match domain");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,7 @@ import javax.ws.rs.core.UriBuilder;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class RealmConfiguration
|
public class RealmConfiguration {
|
||||||
{
|
|
||||||
protected ResourceMetadata metadata;
|
protected ResourceMetadata metadata;
|
||||||
protected ResteasyClient client;
|
protected ResteasyClient client;
|
||||||
protected UriBuilder authUrl;
|
protected UriBuilder authUrl;
|
||||||
|
@ -21,78 +20,63 @@ public class RealmConfiguration
|
||||||
protected boolean sslRequired = true;
|
protected boolean sslRequired = true;
|
||||||
protected String stateCookieName = "OAuth_Token_Request_State";
|
protected String stateCookieName = "OAuth_Token_Request_State";
|
||||||
|
|
||||||
public ResourceMetadata getMetadata()
|
public ResourceMetadata getMetadata() {
|
||||||
{
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMetadata(ResourceMetadata metadata)
|
public void setMetadata(ResourceMetadata metadata) {
|
||||||
{
|
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResteasyClient getClient()
|
public ResteasyClient getClient() {
|
||||||
{
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClient(ResteasyClient client)
|
public void setClient(ResteasyClient client) {
|
||||||
{
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UriBuilder getAuthUrl()
|
public UriBuilder getAuthUrl() {
|
||||||
{
|
|
||||||
return authUrl;
|
return authUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthUrl(UriBuilder authUrl)
|
public void setAuthUrl(UriBuilder authUrl) {
|
||||||
{
|
|
||||||
this.authUrl = authUrl;
|
this.authUrl = authUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientId()
|
public String getClientId() {
|
||||||
{
|
|
||||||
return clientId;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientId(String clientId)
|
public void setClientId(String clientId) {
|
||||||
{
|
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Form getCredentials()
|
public Form getCredentials() {
|
||||||
{
|
|
||||||
return credentials;
|
return credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResteasyWebTarget getCodeUrl()
|
public ResteasyWebTarget getCodeUrl() {
|
||||||
{
|
|
||||||
return codeUrl;
|
return codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCodeUrl(ResteasyWebTarget codeUrl)
|
public void setCodeUrl(ResteasyWebTarget codeUrl) {
|
||||||
{
|
|
||||||
this.codeUrl = codeUrl;
|
this.codeUrl = codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSslRequired()
|
public boolean isSslRequired() {
|
||||||
{
|
|
||||||
return sslRequired;
|
return sslRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSslRequired(boolean sslRequired)
|
public void setSslRequired(boolean sslRequired) {
|
||||||
{
|
|
||||||
this.sslRequired = sslRequired;
|
this.sslRequired = sslRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStateCookieName()
|
public String getStateCookieName() {
|
||||||
{
|
|
||||||
return stateCookieName;
|
return stateCookieName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStateCookieName(String stateCookieName)
|
public void setStateCookieName(String stateCookieName) {
|
||||||
{
|
|
||||||
this.stateCookieName = stateCookieName;
|
this.stateCookieName = stateCookieName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,7 @@ import java.security.PublicKey;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class ResourceMetadata
|
public class ResourceMetadata {
|
||||||
{
|
|
||||||
protected String resourceName;
|
protected String resourceName;
|
||||||
protected String realm;
|
protected String realm;
|
||||||
protected KeyStore clientKeystore;
|
protected KeyStore clientKeystore;
|
||||||
|
@ -16,13 +15,11 @@ public class ResourceMetadata
|
||||||
protected KeyStore truststore;
|
protected KeyStore truststore;
|
||||||
protected PublicKey realmKey;
|
protected PublicKey realmKey;
|
||||||
|
|
||||||
public String getResourceName()
|
public String getResourceName() {
|
||||||
{
|
|
||||||
return resourceName;
|
return resourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealm()
|
public String getRealm() {
|
||||||
{
|
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,18 +29,15 @@ public class ResourceMetadata
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public KeyStore getClientKeystore()
|
public KeyStore getClientKeystore() {
|
||||||
{
|
|
||||||
return clientKeystore;
|
return clientKeystore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientKeyPassword()
|
public String getClientKeyPassword() {
|
||||||
{
|
|
||||||
return clientKeyPassword;
|
return clientKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeyPassword(String clientKeyPassword)
|
public void setClientKeyPassword(String clientKeyPassword) {
|
||||||
{
|
|
||||||
this.clientKeyPassword = clientKeyPassword;
|
this.clientKeyPassword = clientKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +46,7 @@ public class ResourceMetadata
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public KeyStore getTruststore()
|
public KeyStore getTruststore() {
|
||||||
{
|
|
||||||
return truststore;
|
return truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,33 +55,27 @@ public class ResourceMetadata
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public PublicKey getRealmKey()
|
public PublicKey getRealmKey() {
|
||||||
{
|
|
||||||
return realmKey;
|
return realmKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResourceName(String resourceName)
|
public void setResourceName(String resourceName) {
|
||||||
{
|
|
||||||
this.resourceName = resourceName;
|
this.resourceName = resourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealm(String realm)
|
public void setRealm(String realm) {
|
||||||
{
|
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeystore(KeyStore clientKeystore)
|
public void setClientKeystore(KeyStore clientKeystore) {
|
||||||
{
|
|
||||||
this.clientKeystore = clientKeystore;
|
this.clientKeystore = clientKeystore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTruststore(KeyStore truststore)
|
public void setTruststore(KeyStore truststore) {
|
||||||
{
|
|
||||||
this.truststore = truststore;
|
this.truststore = truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmKey(PublicKey realmKey)
|
public void setRealmKey(PublicKey realmKey) {
|
||||||
{
|
|
||||||
this.realmKey = realmKey;
|
this.realmKey = realmKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,28 +14,23 @@ import javax.ws.rs.ext.Provider;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
@Provider
|
@Provider
|
||||||
public class SkeletonKeyContextResolver implements ContextResolver<ObjectMapper>
|
public class SkeletonKeyContextResolver implements ContextResolver<ObjectMapper> {
|
||||||
{
|
|
||||||
protected ObjectMapper mapper = new ObjectMapper();
|
protected ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
public SkeletonKeyContextResolver()
|
public SkeletonKeyContextResolver() {
|
||||||
{
|
|
||||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkeletonKeyContextResolver(boolean indent)
|
public SkeletonKeyContextResolver(boolean indent) {
|
||||||
{
|
|
||||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
||||||
if (indent)
|
if (indent) {
|
||||||
{
|
|
||||||
mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
|
mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectMapper getContext(Class<?> type)
|
public ObjectMapper getContext(Class<?> type) {
|
||||||
{
|
|
||||||
if (type.getPackage().getName().startsWith(getClass().getPackage().getName())) return mapper;
|
if (type.getPackage().getName().startsWith(getClass().getPackage().getName())) return mapper;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,31 +6,26 @@ import java.security.Principal;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class SkeletonKeyPrincipal implements Principal
|
public class SkeletonKeyPrincipal implements Principal {
|
||||||
{
|
|
||||||
protected String name;
|
protected String name;
|
||||||
protected String surrogate;
|
protected String surrogate;
|
||||||
|
|
||||||
public SkeletonKeyPrincipal(String name, String surrogate)
|
public SkeletonKeyPrincipal(String name, String surrogate) {
|
||||||
{
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.surrogate = surrogate;
|
this.surrogate = surrogate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName()
|
public String getName() {
|
||||||
{
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSurrogate()
|
public String getSurrogate() {
|
||||||
{
|
|
||||||
return surrogate;
|
return surrogate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o) {
|
||||||
{
|
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
@ -43,16 +38,14 @@ public class SkeletonKeyPrincipal implements Principal
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
int result = name.hashCode();
|
int result = name.hashCode();
|
||||||
result = 31 * result + (surrogate != null ? surrogate.hashCode() : 0);
|
result = 31 * result + (surrogate != null ? surrogate.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,28 +6,23 @@ import java.io.Serializable;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class SkeletonKeySession implements Serializable
|
public class SkeletonKeySession implements Serializable {
|
||||||
{
|
|
||||||
protected String token;
|
protected String token;
|
||||||
protected transient ResourceMetadata metadata;
|
protected transient ResourceMetadata metadata;
|
||||||
|
|
||||||
public SkeletonKeySession()
|
public SkeletonKeySession() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkeletonKeySession(String token, ResourceMetadata metadata)
|
public SkeletonKeySession(String token, ResourceMetadata metadata) {
|
||||||
{
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getToken()
|
public String getToken() {
|
||||||
{
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceMetadata getMetadata()
|
public ResourceMetadata getMetadata() {
|
||||||
{
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,24 +4,19 @@ package org.keycloak;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class VerificationException extends Exception
|
public class VerificationException extends Exception {
|
||||||
{
|
public VerificationException() {
|
||||||
public VerificationException()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VerificationException(String message)
|
public VerificationException(String message) {
|
||||||
{
|
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VerificationException(String message, Throwable cause)
|
public VerificationException(String message, Throwable cause) {
|
||||||
{
|
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VerificationException(Throwable cause)
|
public VerificationException(Throwable cause) {
|
||||||
{
|
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package org.keycloak.jaxrs;
|
package org.keycloak.jaxrs;
|
||||||
|
|
||||||
import org.jboss.resteasy.logging.Logger;
|
import org.jboss.resteasy.logging.Logger;
|
||||||
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.RSATokenVerifier;
|
import org.keycloak.RSATokenVerifier;
|
||||||
import org.keycloak.ResourceMetadata;
|
import org.keycloak.ResourceMetadata;
|
||||||
import org.keycloak.SkeletonKeyPrincipal;
|
import org.keycloak.SkeletonKeyPrincipal;
|
||||||
import org.keycloak.SkeletonKeySession;
|
import org.keycloak.SkeletonKeySession;
|
||||||
import org.keycloak.VerificationException;
|
import org.keycloak.VerificationException;
|
||||||
import org.keycloak.representations.SkeletonKeyToken;
|
import org.keycloak.representations.SkeletonKeyToken;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
|
||||||
|
|
||||||
import javax.annotation.Priority;
|
import javax.annotation.Priority;
|
||||||
import javax.ws.rs.Priorities;
|
import javax.ws.rs.Priorities;
|
||||||
|
@ -25,26 +25,21 @@ import java.security.Principal;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
@Priority(Priorities.AUTHENTICATION)
|
@Priority(Priorities.AUTHENTICATION)
|
||||||
public class JaxrsBearerTokenFilter implements ContainerRequestFilter
|
public class JaxrsBearerTokenFilter implements ContainerRequestFilter {
|
||||||
{
|
|
||||||
protected ResourceMetadata resourceMetadata;
|
protected ResourceMetadata resourceMetadata;
|
||||||
private static Logger log = Logger.getLogger(JaxrsBearerTokenFilter.class);
|
private static Logger log = Logger.getLogger(JaxrsBearerTokenFilter.class);
|
||||||
|
|
||||||
public JaxrsBearerTokenFilter(ResourceMetadata resourceMetadata)
|
public JaxrsBearerTokenFilter(ResourceMetadata resourceMetadata) {
|
||||||
{
|
|
||||||
this.resourceMetadata = resourceMetadata;
|
this.resourceMetadata = resourceMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void challengeResponse(ContainerRequestContext request, String error, String description)
|
protected void challengeResponse(ContainerRequestContext request, String error, String description) {
|
||||||
{
|
|
||||||
StringBuilder header = new StringBuilder("Bearer realm=\"");
|
StringBuilder header = new StringBuilder("Bearer realm=\"");
|
||||||
header.append(resourceMetadata.getRealm()).append("\"");
|
header.append(resourceMetadata.getRealm()).append("\"");
|
||||||
if (error != null)
|
if (error != null) {
|
||||||
{
|
|
||||||
header.append(", error=\"").append(error).append("\"");
|
header.append(", error=\"").append(error).append("\"");
|
||||||
}
|
}
|
||||||
if (description != null)
|
if (description != null) {
|
||||||
{
|
|
||||||
header.append(", error_description=\"").append(description).append("\"");
|
header.append(", error_description=\"").append(description).append("\"");
|
||||||
}
|
}
|
||||||
request.abortWith(Response.status(401).header("WWW-Authenticate", header.toString()).build());
|
request.abortWith(Response.status(401).header("WWW-Authenticate", header.toString()).build());
|
||||||
|
@ -55,11 +50,9 @@ public class JaxrsBearerTokenFilter implements ContainerRequestFilter
|
||||||
protected SecurityContext securityContext;
|
protected SecurityContext securityContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filter(ContainerRequestContext request) throws IOException
|
public void filter(ContainerRequestContext request) throws IOException {
|
||||||
{
|
|
||||||
String authHeader = request.getHeaderString(HttpHeaders.AUTHORIZATION);
|
String authHeader = request.getHeaderString(HttpHeaders.AUTHORIZATION);
|
||||||
if (authHeader == null)
|
if (authHeader == null) {
|
||||||
{
|
|
||||||
challengeResponse(request, null, null);
|
challengeResponse(request, null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -72,8 +65,7 @@ public class JaxrsBearerTokenFilter implements ContainerRequestFilter
|
||||||
String tokenString = split[1];
|
String tokenString = split[1];
|
||||||
|
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
SkeletonKeyToken token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata);
|
SkeletonKeyToken token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata);
|
||||||
SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata);
|
SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata);
|
||||||
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
||||||
|
@ -82,45 +74,35 @@ public class JaxrsBearerTokenFilter implements ContainerRequestFilter
|
||||||
final SkeletonKeyPrincipal principal = new SkeletonKeyPrincipal(token.getPrincipal(), callerPrincipal);
|
final SkeletonKeyPrincipal principal = new SkeletonKeyPrincipal(token.getPrincipal(), callerPrincipal);
|
||||||
final boolean isSecure = securityContext.isSecure();
|
final boolean isSecure = securityContext.isSecure();
|
||||||
final SkeletonKeyToken.Access access;
|
final SkeletonKeyToken.Access access;
|
||||||
if (resourceMetadata.getResourceName() != null)
|
if (resourceMetadata.getResourceName() != null) {
|
||||||
{
|
|
||||||
access = token.getResourceAccess(resourceMetadata.getResourceName());
|
access = token.getResourceAccess(resourceMetadata.getResourceName());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
access = token.getRealmAccess();
|
access = token.getRealmAccess();
|
||||||
}
|
}
|
||||||
SecurityContext ctx = new SecurityContext()
|
SecurityContext ctx = new SecurityContext() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public Principal getUserPrincipal()
|
public Principal getUserPrincipal() {
|
||||||
{
|
|
||||||
return principal;
|
return principal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUserInRole(String role)
|
public boolean isUserInRole(String role) {
|
||||||
{
|
|
||||||
if (access.getRoles() == null) return false;
|
if (access.getRoles() == null) return false;
|
||||||
return access.getRoles().contains(role);
|
return access.getRoles().contains(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecure()
|
public boolean isSecure() {
|
||||||
{
|
|
||||||
return isSecure;
|
return isSecure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAuthenticationScheme()
|
public String getAuthenticationScheme() {
|
||||||
{
|
|
||||||
return "OAUTH_BEARER";
|
return "OAUTH_BEARER";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
request.setSecurityContext(ctx);
|
request.setSecurityContext(ctx);
|
||||||
}
|
} catch (VerificationException e) {
|
||||||
catch (VerificationException e)
|
|
||||||
{
|
|
||||||
log.error("Failed to verify token", e);
|
log.error("Failed to verify token", e);
|
||||||
challengeResponse(request, "invalid_token", e.getMessage());
|
challengeResponse(request, "invalid_token", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,8 @@ import java.net.URI;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class JaxrsOAuthClient extends AbstractOAuthClient
|
public class JaxrsOAuthClient extends AbstractOAuthClient {
|
||||||
{
|
public Response redirect(UriInfo uriInfo, String redirectUri) {
|
||||||
public Response redirect(UriInfo uriInfo, String redirectUri)
|
|
||||||
{
|
|
||||||
String state = getStateCode();
|
String state = getStateCode();
|
||||||
|
|
||||||
URI url = UriBuilder.fromUri(authUrl)
|
URI url = UriBuilder.fromUri(authUrl)
|
||||||
|
@ -35,17 +33,16 @@ public class JaxrsOAuthClient extends AbstractOAuthClient
|
||||||
.cookie(cookie).build();
|
.cookie(cookie).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBearerToken(UriInfo uriInfo, HttpHeaders headers) throws BadRequestException, InternalServerErrorException
|
public String getBearerToken(UriInfo uriInfo, HttpHeaders headers) throws BadRequestException, InternalServerErrorException {
|
||||||
{
|
|
||||||
String error = uriInfo.getQueryParameters().getFirst("error");
|
String error = uriInfo.getQueryParameters().getFirst("error");
|
||||||
if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error));
|
if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error));
|
||||||
Cookie stateCookie = headers.getCookies().get(stateCookieName);
|
Cookie stateCookie = headers.getCookies().get(stateCookieName);
|
||||||
if (stateCookie == null) throw new BadRequestException(new Exception("state cookie not set"));;
|
if (stateCookie == null) throw new BadRequestException(new Exception("state cookie not set"));
|
||||||
|
;
|
||||||
|
|
||||||
String state = uriInfo.getQueryParameters().getFirst("state");
|
String state = uriInfo.getQueryParameters().getFirst("state");
|
||||||
if (state == null) throw new BadRequestException(new Exception("state parameter was null"));
|
if (state == null) throw new BadRequestException(new Exception("state parameter was null"));
|
||||||
if (!state.equals(stateCookie.getValue()))
|
if (!state.equals(stateCookie.getValue())) {
|
||||||
{
|
|
||||||
throw new BadRequestException(new Exception("state parameter invalid"));
|
throw new BadRequestException(new Exception("state parameter invalid"));
|
||||||
}
|
}
|
||||||
String code = uriInfo.getQueryParameters().getFirst("code");
|
String code = uriInfo.getQueryParameters().getFirst("code");
|
||||||
|
|
|
@ -8,8 +8,7 @@ import org.codehaus.jackson.annotate.JsonProperty;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class AccessTokenResponse
|
public class AccessTokenResponse {
|
||||||
{
|
|
||||||
@JsonProperty("access_token")
|
@JsonProperty("access_token")
|
||||||
protected String token;
|
protected String token;
|
||||||
|
|
||||||
|
@ -22,43 +21,35 @@ public class AccessTokenResponse
|
||||||
@JsonProperty("token_type")
|
@JsonProperty("token_type")
|
||||||
protected String tokenType;
|
protected String tokenType;
|
||||||
|
|
||||||
public String getToken()
|
public String getToken() {
|
||||||
{
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setToken(String token)
|
public void setToken(String token) {
|
||||||
{
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getExpiresIn()
|
public long getExpiresIn() {
|
||||||
{
|
|
||||||
return expiresIn;
|
return expiresIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExpiresIn(long expiresIn)
|
public void setExpiresIn(long expiresIn) {
|
||||||
{
|
|
||||||
this.expiresIn = expiresIn;
|
this.expiresIn = expiresIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRefreshToken()
|
public String getRefreshToken() {
|
||||||
{
|
|
||||||
return refreshToken;
|
return refreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRefreshToken(String refreshToken)
|
public void setRefreshToken(String refreshToken) {
|
||||||
{
|
|
||||||
this.refreshToken = refreshToken;
|
this.refreshToken = refreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTokenType()
|
public String getTokenType() {
|
||||||
{
|
|
||||||
return tokenType;
|
return tokenType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTokenType(String tokenType)
|
public void setTokenType(String tokenType) {
|
||||||
{
|
|
||||||
this.tokenType = tokenType;
|
this.tokenType = tokenType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,5 @@ import javax.ws.rs.core.MultivaluedHashMap;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class SkeletonKeyScope extends MultivaluedHashMap<String, String>
|
public class SkeletonKeyScope extends MultivaluedHashMap<String, String> {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,47 +13,39 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class SkeletonKeyToken extends JsonWebToken
|
public class SkeletonKeyToken extends JsonWebToken {
|
||||||
{
|
public static class Access {
|
||||||
public static class Access
|
|
||||||
{
|
|
||||||
@JsonProperty("roles")
|
@JsonProperty("roles")
|
||||||
protected Set<String> roles;
|
protected Set<String> roles;
|
||||||
@JsonProperty("verify_caller")
|
@JsonProperty("verify_caller")
|
||||||
protected Boolean verifyCaller;
|
protected Boolean verifyCaller;
|
||||||
|
|
||||||
public Set<String> getRoles()
|
public Set<String> getRoles() {
|
||||||
{
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Access roles(Set<String> roles)
|
public Access roles(Set<String> roles) {
|
||||||
{
|
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isUserInRole(String role)
|
public boolean isUserInRole(String role) {
|
||||||
{
|
|
||||||
if (roles == null) return false;
|
if (roles == null) return false;
|
||||||
return roles.contains(role);
|
return roles.contains(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Access addRole(String role)
|
public Access addRole(String role) {
|
||||||
{
|
|
||||||
if (roles == null) roles = new HashSet<String>();
|
if (roles == null) roles = new HashSet<String>();
|
||||||
roles.add(role);
|
roles.add(role);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getVerifyCaller()
|
public Boolean getVerifyCaller() {
|
||||||
{
|
|
||||||
return verifyCaller;
|
return verifyCaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Access verifyCaller(Boolean required)
|
public Access verifyCaller(Boolean required) {
|
||||||
{
|
|
||||||
this.verifyCaller = required;
|
this.verifyCaller = required;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -72,8 +64,7 @@ public class SkeletonKeyToken extends JsonWebToken
|
||||||
@JsonProperty("resource_access")
|
@JsonProperty("resource_access")
|
||||||
protected Map<String, Access> resourceAccess = new HashMap<String, Access>();
|
protected Map<String, Access> resourceAccess = new HashMap<String, Access>();
|
||||||
|
|
||||||
public Map<String, Access> getResourceAccess()
|
public Map<String, Access> getResourceAccess() {
|
||||||
{
|
|
||||||
return resourceAccess;
|
return resourceAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,9 +74,9 @@ public class SkeletonKeyToken extends JsonWebToken
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isVerifyCaller()
|
public boolean isVerifyCaller() {
|
||||||
{
|
if (getRealmAccess() != null && getRealmAccess().getVerifyCaller() != null)
|
||||||
if (getRealmAccess() != null && getRealmAccess().getVerifyCaller() != null) return getRealmAccess().getVerifyCaller().booleanValue();
|
return getRealmAccess().getVerifyCaller().booleanValue();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,91 +87,76 @@ public class SkeletonKeyToken extends JsonWebToken
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isVerifyCaller(String resource)
|
public boolean isVerifyCaller(String resource) {
|
||||||
{
|
|
||||||
Access access = getResourceAccess(resource);
|
Access access = getResourceAccess(resource);
|
||||||
if (access != null && access.getVerifyCaller() != null) return access.getVerifyCaller().booleanValue();
|
if (access != null && access.getVerifyCaller() != null) return access.getVerifyCaller().booleanValue();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public Access getResourceAccess(String resource)
|
public Access getResourceAccess(String resource) {
|
||||||
{
|
|
||||||
return resourceAccess.get(resource);
|
return resourceAccess.get(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Access addAccess(String service)
|
public Access addAccess(String service) {
|
||||||
{
|
|
||||||
Access token = new Access();
|
Access token = new Access();
|
||||||
resourceAccess.put(service, token);
|
resourceAccess.put(service, token);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken id(String id)
|
public SkeletonKeyToken id(String id) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.id(id);
|
return (SkeletonKeyToken) super.id(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken expiration(long expiration)
|
public SkeletonKeyToken expiration(long expiration) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.expiration(expiration);
|
return (SkeletonKeyToken) super.expiration(expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken notBefore(long notBefore)
|
public SkeletonKeyToken notBefore(long notBefore) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.notBefore(notBefore);
|
return (SkeletonKeyToken) super.notBefore(notBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken issuedAt(long issuedAt)
|
public SkeletonKeyToken issuedAt(long issuedAt) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.issuedAt(issuedAt);
|
return (SkeletonKeyToken) super.issuedAt(issuedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken issuer(String issuer)
|
public SkeletonKeyToken issuer(String issuer) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.issuer(issuer);
|
return (SkeletonKeyToken) super.issuer(issuer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken audience(String audience)
|
public SkeletonKeyToken audience(String audience) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.audience(audience);
|
return (SkeletonKeyToken) super.audience(audience);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken principal(String principal)
|
public SkeletonKeyToken principal(String principal) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.principal(principal);
|
return (SkeletonKeyToken) super.principal(principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkeletonKeyToken type(String type)
|
public SkeletonKeyToken type(String type) {
|
||||||
{
|
|
||||||
return (SkeletonKeyToken) super.type(type);
|
return (SkeletonKeyToken) super.type(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Access getRealmAccess()
|
public Access getRealmAccess() {
|
||||||
{
|
|
||||||
return realmAccess;
|
return realmAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmAccess(Access realmAccess)
|
public void setRealmAccess(Access realmAccess) {
|
||||||
{
|
|
||||||
this.realmAccess = realmAccess;
|
this.realmAccess = realmAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getTrustedCertificates()
|
public Set<String> getTrustedCertificates() {
|
||||||
{
|
|
||||||
return trustedCertificates;
|
return trustedCertificates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTrustedCertificates(Set<String> trustedCertificates)
|
public void setTrustedCertificates(Set<String> trustedCertificates) {
|
||||||
{
|
|
||||||
this.trustedCertificates = trustedCertificates;
|
this.trustedCertificates = trustedCertificates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,13 +165,11 @@ public class SkeletonKeyToken extends JsonWebToken
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getIssuedFor()
|
public String getIssuedFor() {
|
||||||
{
|
|
||||||
return issuedFor;
|
return issuedFor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkeletonKeyToken issuedFor(String issuedFor)
|
public SkeletonKeyToken issuedFor(String issuedFor) {
|
||||||
{
|
|
||||||
this.issuedFor = issuedFor;
|
this.issuedFor = issuedFor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,7 @@ import java.security.PublicKey;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class PublishedRealmRepresentation
|
public class PublishedRealmRepresentation {
|
||||||
{
|
|
||||||
protected String realm;
|
protected String realm;
|
||||||
protected String self;
|
protected String self;
|
||||||
|
|
||||||
|
@ -33,54 +32,53 @@ public class PublishedRealmRepresentation
|
||||||
@JsonProperty("identity-grants")
|
@JsonProperty("identity-grants")
|
||||||
protected String identityGrantUrl;
|
protected String identityGrantUrl;
|
||||||
|
|
||||||
|
@JsonProperty("admin-role")
|
||||||
|
protected String adminRole;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
protected volatile transient PublicKey publicKey;
|
protected volatile transient PublicKey publicKey;
|
||||||
|
|
||||||
|
public String getAdminRole() {
|
||||||
|
return adminRole;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRealm()
|
public void setAdminRole(String adminRole) {
|
||||||
{
|
this.adminRole = adminRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealm() {
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealm(String realm)
|
public void setRealm(String realm) {
|
||||||
{
|
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSelf()
|
public String getSelf() {
|
||||||
{
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelf(String self)
|
public void setSelf(String self) {
|
||||||
{
|
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPublicKeyPem()
|
public String getPublicKeyPem() {
|
||||||
{
|
|
||||||
return publicKeyPem;
|
return publicKeyPem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPublicKeyPem(String publicKeyPem)
|
public void setPublicKeyPem(String publicKeyPem) {
|
||||||
{
|
|
||||||
this.publicKeyPem = publicKeyPem;
|
this.publicKeyPem = publicKeyPem;
|
||||||
this.publicKey = null;
|
this.publicKey = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public PublicKey getPublicKey()
|
public PublicKey getPublicKey() {
|
||||||
{
|
|
||||||
if (publicKey != null) return publicKey;
|
if (publicKey != null) return publicKey;
|
||||||
if (publicKeyPem != null)
|
if (publicKeyPem != null) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
publicKey = PemUtils.decodePublicKey(publicKeyPem);
|
publicKey = PemUtils.decodePublicKey(publicKeyPem);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,18 +86,14 @@ public class PublishedRealmRepresentation
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public void setPublicKey(PublicKey publicKey)
|
public void setPublicKey(PublicKey publicKey) {
|
||||||
{
|
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey;
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
PEMWriter pemWriter = new PEMWriter(writer);
|
PEMWriter pemWriter = new PEMWriter(writer);
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
pemWriter.writeObject(publicKey);
|
pemWriter.writeObject(publicKey);
|
||||||
pemWriter.flush();
|
pemWriter.flush();
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
String s = writer.toString();
|
String s = writer.toString();
|
||||||
|
@ -107,43 +101,35 @@ public class PublishedRealmRepresentation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getAuthorizationUrl()
|
public String getAuthorizationUrl() {
|
||||||
{
|
|
||||||
return authorizationUrl;
|
return authorizationUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthorizationUrl(String authorizationUrl)
|
public void setAuthorizationUrl(String authorizationUrl) {
|
||||||
{
|
|
||||||
this.authorizationUrl = authorizationUrl;
|
this.authorizationUrl = authorizationUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCodeUrl()
|
public String getCodeUrl() {
|
||||||
{
|
|
||||||
return codeUrl;
|
return codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCodeUrl(String codeUrl)
|
public void setCodeUrl(String codeUrl) {
|
||||||
{
|
|
||||||
this.codeUrl = codeUrl;
|
this.codeUrl = codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGrantUrl()
|
public String getGrantUrl() {
|
||||||
{
|
|
||||||
return grantUrl;
|
return grantUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGrantUrl(String grantUrl)
|
public void setGrantUrl(String grantUrl) {
|
||||||
{
|
|
||||||
this.grantUrl = grantUrl;
|
this.grantUrl = grantUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIdentityGrantUrl()
|
public String getIdentityGrantUrl() {
|
||||||
{
|
|
||||||
return identityGrantUrl;
|
return identityGrantUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIdentityGrantUrl(String identityGrantUrl)
|
public void setIdentityGrantUrl(String identityGrantUrl) {
|
||||||
{
|
|
||||||
this.identityGrantUrl = identityGrantUrl;
|
this.identityGrantUrl = identityGrantUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,7 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class RealmRepresentation
|
public class RealmRepresentation {
|
||||||
{
|
|
||||||
protected String self; // link
|
protected String self; // link
|
||||||
protected String realm;
|
protected String realm;
|
||||||
protected long tokenLifespan;
|
protected long tokenLifespan;
|
||||||
|
@ -25,38 +24,31 @@ public class RealmRepresentation
|
||||||
protected List<ResourceRepresentation> resources;
|
protected List<ResourceRepresentation> resources;
|
||||||
|
|
||||||
|
|
||||||
public String getSelf()
|
public String getSelf() {
|
||||||
{
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelf(String self)
|
public void setSelf(String self) {
|
||||||
{
|
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealm()
|
public String getRealm() {
|
||||||
{
|
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealm(String realm)
|
public void setRealm(String realm) {
|
||||||
{
|
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UserRepresentation> getUsers()
|
public List<UserRepresentation> getUsers() {
|
||||||
{
|
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ResourceRepresentation> getResources()
|
public List<ResourceRepresentation> getResources() {
|
||||||
{
|
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceRepresentation resource(String name)
|
public ResourceRepresentation resource(String name) {
|
||||||
{
|
|
||||||
ResourceRepresentation resource = new ResourceRepresentation();
|
ResourceRepresentation resource = new ResourceRepresentation();
|
||||||
if (resources == null) resources = new ArrayList<ResourceRepresentation>();
|
if (resources == null) resources = new ArrayList<ResourceRepresentation>();
|
||||||
resources.add(resource);
|
resources.add(resource);
|
||||||
|
@ -64,13 +56,11 @@ public class RealmRepresentation
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsers(List<UserRepresentation> users)
|
public void setUsers(List<UserRepresentation> users) {
|
||||||
{
|
|
||||||
this.users = users;
|
this.users = users;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserRepresentation user(String username)
|
public UserRepresentation user(String username) {
|
||||||
{
|
|
||||||
UserRepresentation user = new UserRepresentation();
|
UserRepresentation user = new UserRepresentation();
|
||||||
user.setUsername(username);
|
user.setUsername(username);
|
||||||
if (users == null) users = new ArrayList<UserRepresentation>();
|
if (users == null) users = new ArrayList<UserRepresentation>();
|
||||||
|
@ -78,58 +68,47 @@ public class RealmRepresentation
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResources(List<ResourceRepresentation> resources)
|
public void setResources(List<ResourceRepresentation> resources) {
|
||||||
{
|
|
||||||
this.resources = resources;
|
this.resources = resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled()
|
public boolean isEnabled() {
|
||||||
{
|
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled)
|
public void setEnabled(boolean enabled) {
|
||||||
{
|
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSslNotRequired()
|
public boolean isSslNotRequired() {
|
||||||
{
|
|
||||||
return sslNotRequired;
|
return sslNotRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSslNotRequired(boolean sslNotRequired)
|
public void setSslNotRequired(boolean sslNotRequired) {
|
||||||
{
|
|
||||||
this.sslNotRequired = sslNotRequired;
|
this.sslNotRequired = sslNotRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCookieLoginAllowed()
|
public boolean isCookieLoginAllowed() {
|
||||||
{
|
|
||||||
return cookieLoginAllowed;
|
return cookieLoginAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCookieLoginAllowed(boolean cookieLoginAllowed)
|
public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
|
||||||
{
|
|
||||||
this.cookieLoginAllowed = cookieLoginAllowed;
|
this.cookieLoginAllowed = cookieLoginAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTokenLifespan()
|
public long getTokenLifespan() {
|
||||||
{
|
|
||||||
return tokenLifespan;
|
return tokenLifespan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTokenLifespan(long tokenLifespan)
|
public void setTokenLifespan(long tokenLifespan) {
|
||||||
{
|
|
||||||
this.tokenLifespan = tokenLifespan;
|
this.tokenLifespan = tokenLifespan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RoleMappingRepresentation> getRoleMappings()
|
public List<RoleMappingRepresentation> getRoleMappings() {
|
||||||
{
|
|
||||||
return roleMappings;
|
return roleMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoleMappingRepresentation roleMapping(String username)
|
public RoleMappingRepresentation roleMapping(String username) {
|
||||||
{
|
|
||||||
RoleMappingRepresentation mapping = new RoleMappingRepresentation();
|
RoleMappingRepresentation mapping = new RoleMappingRepresentation();
|
||||||
mapping.setUsername(username);
|
mapping.setUsername(username);
|
||||||
if (roleMappings == null) roleMappings = new ArrayList<RoleMappingRepresentation>();
|
if (roleMappings == null) roleMappings = new ArrayList<RoleMappingRepresentation>();
|
||||||
|
@ -137,13 +116,11 @@ public class RealmRepresentation
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ScopeMappingRepresentation> getScopeMappings()
|
public List<ScopeMappingRepresentation> getScopeMappings() {
|
||||||
{
|
|
||||||
return scopeMappings;
|
return scopeMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScopeMappingRepresentation scopeMapping(String username)
|
public ScopeMappingRepresentation scopeMapping(String username) {
|
||||||
{
|
|
||||||
ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
|
ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
|
||||||
mapping.setUsername(username);
|
mapping.setUsername(username);
|
||||||
if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
|
if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
|
||||||
|
@ -151,33 +128,27 @@ public class RealmRepresentation
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RequiredCredentialRepresentation> getRequiredCredentials()
|
public List<RequiredCredentialRepresentation> getRequiredCredentials() {
|
||||||
{
|
|
||||||
return requiredCredentials;
|
return requiredCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRequiredCredentials(List<RequiredCredentialRepresentation> requiredCredentials)
|
public void setRequiredCredentials(List<RequiredCredentialRepresentation> requiredCredentials) {
|
||||||
{
|
|
||||||
this.requiredCredentials = requiredCredentials;
|
this.requiredCredentials = requiredCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getAccessCodeLifespan()
|
public long getAccessCodeLifespan() {
|
||||||
{
|
|
||||||
return accessCodeLifespan;
|
return accessCodeLifespan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessCodeLifespan(long accessCodeLifespan)
|
public void setAccessCodeLifespan(long accessCodeLifespan) {
|
||||||
{
|
|
||||||
this.accessCodeLifespan = accessCodeLifespan;
|
this.accessCodeLifespan = accessCodeLifespan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getRoles()
|
public Set<String> getRoles() {
|
||||||
{
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoles(Set<String> roles)
|
public void setRoles(Set<String> roles) {
|
||||||
{
|
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,7 @@ package org.keycloak.representations.idm;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class RequiredCredentialRepresentation
|
public class RequiredCredentialRepresentation {
|
||||||
{
|
|
||||||
public static final String PASSWORD = "Password";
|
public static final String PASSWORD = "Password";
|
||||||
public static final String TOTP = "TOTP";
|
public static final String TOTP = "TOTP";
|
||||||
public static final String CLIENT_CERT = "CLIENT_CERT";
|
public static final String CLIENT_CERT = "CLIENT_CERT";
|
||||||
|
@ -14,33 +13,27 @@ public class RequiredCredentialRepresentation
|
||||||
protected boolean input;
|
protected boolean input;
|
||||||
protected boolean secret;
|
protected boolean secret;
|
||||||
|
|
||||||
public String getType()
|
public String getType() {
|
||||||
{
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(String type)
|
public void setType(String type) {
|
||||||
{
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInput()
|
public boolean isInput() {
|
||||||
{
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInput(boolean input)
|
public void setInput(boolean input) {
|
||||||
{
|
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSecret()
|
public boolean isSecret() {
|
||||||
{
|
|
||||||
return secret;
|
return secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSecret(boolean secret)
|
public void setSecret(boolean secret) {
|
||||||
{
|
|
||||||
this.secret = secret;
|
this.secret = secret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class ResourceRepresentation
|
public class ResourceRepresentation {
|
||||||
{
|
|
||||||
protected String self; // link
|
protected String self; // link
|
||||||
protected String name;
|
protected String name;
|
||||||
protected boolean surrogateAuthRequired;
|
protected boolean surrogateAuthRequired;
|
||||||
|
@ -18,60 +17,49 @@ public class ResourceRepresentation
|
||||||
protected List<RoleMappingRepresentation> roleMappings;
|
protected List<RoleMappingRepresentation> roleMappings;
|
||||||
protected List<ScopeMappingRepresentation> scopeMappings;
|
protected List<ScopeMappingRepresentation> scopeMappings;
|
||||||
|
|
||||||
public String getSelf()
|
public String getSelf() {
|
||||||
{
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelf(String self)
|
public void setSelf(String self) {
|
||||||
{
|
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName()
|
public String getName() {
|
||||||
{
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name)
|
public void setName(String name) {
|
||||||
{
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSurrogateAuthRequired()
|
public boolean isSurrogateAuthRequired() {
|
||||||
{
|
|
||||||
return surrogateAuthRequired;
|
return surrogateAuthRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired)
|
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||||
{
|
|
||||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getRoles()
|
public Set<String> getRoles() {
|
||||||
{
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoles(Set<String> roles)
|
public void setRoles(Set<String> roles) {
|
||||||
{
|
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceRepresentation role(String role)
|
public ResourceRepresentation role(String role) {
|
||||||
{
|
|
||||||
if (this.roles == null) this.roles = new HashSet<String>();
|
if (this.roles == null) this.roles = new HashSet<String>();
|
||||||
this.roles.add(role);
|
this.roles.add(role);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RoleMappingRepresentation> getRoleMappings()
|
public List<RoleMappingRepresentation> getRoleMappings() {
|
||||||
{
|
|
||||||
return roleMappings;
|
return roleMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoleMappingRepresentation roleMapping(String username)
|
public RoleMappingRepresentation roleMapping(String username) {
|
||||||
{
|
|
||||||
RoleMappingRepresentation mapping = new RoleMappingRepresentation();
|
RoleMappingRepresentation mapping = new RoleMappingRepresentation();
|
||||||
mapping.setUsername(username);
|
mapping.setUsername(username);
|
||||||
if (roleMappings == null) roleMappings = new ArrayList<RoleMappingRepresentation>();
|
if (roleMappings == null) roleMappings = new ArrayList<RoleMappingRepresentation>();
|
||||||
|
@ -79,13 +67,11 @@ public class ResourceRepresentation
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ScopeMappingRepresentation> getScopeMappings()
|
public List<ScopeMappingRepresentation> getScopeMappings() {
|
||||||
{
|
|
||||||
return scopeMappings;
|
return scopeMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScopeMappingRepresentation scopeMapping(String username)
|
public ScopeMappingRepresentation scopeMapping(String username) {
|
||||||
{
|
|
||||||
ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
|
ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
|
||||||
mapping.setUsername(username);
|
mapping.setUsername(username);
|
||||||
if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
|
if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
|
||||||
|
|
|
@ -4,49 +4,39 @@ import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class RoleMappingRepresentation
|
public class RoleMappingRepresentation {
|
||||||
{
|
|
||||||
protected String self; // link
|
protected String self; // link
|
||||||
protected String username;
|
protected String username;
|
||||||
protected Set<String> roles;
|
protected Set<String> roles;
|
||||||
|
|
||||||
public String getSelf()
|
public String getSelf() {
|
||||||
{
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelf(String self)
|
public void setSelf(String self) {
|
||||||
{
|
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername()
|
public String getUsername() {
|
||||||
{
|
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username)
|
public void setUsername(String username) {
|
||||||
{
|
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getRoles()
|
public Set<String> getRoles() {
|
||||||
{
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoles(Set<String> roles)
|
public void setRoles(Set<String> roles) {
|
||||||
{
|
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoleMappingRepresentation role(String role)
|
public RoleMappingRepresentation role(String role) {
|
||||||
{
|
|
||||||
if (this.roles == null) this.roles = new HashSet<String>();
|
if (this.roles == null) this.roles = new HashSet<String>();
|
||||||
this.roles.add(role);
|
this.roles.add(role);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -4,49 +4,39 @@ import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class ScopeMappingRepresentation
|
public class ScopeMappingRepresentation {
|
||||||
{
|
|
||||||
protected String self; // link
|
protected String self; // link
|
||||||
protected String username;
|
protected String username;
|
||||||
protected Set<String> roles;
|
protected Set<String> roles;
|
||||||
|
|
||||||
public String getSelf()
|
public String getSelf() {
|
||||||
{
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelf(String self)
|
public void setSelf(String self) {
|
||||||
{
|
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername()
|
public String getUsername() {
|
||||||
{
|
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username)
|
public void setUsername(String username) {
|
||||||
{
|
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getRoles()
|
public Set<String> getRoles() {
|
||||||
{
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoles(Set<String> roles)
|
public void setRoles(Set<String> roles) {
|
||||||
{
|
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScopeMappingRepresentation role(String role)
|
public ScopeMappingRepresentation role(String role) {
|
||||||
{
|
|
||||||
if (this.roles == null) this.roles = new HashSet<String>();
|
if (this.roles == null) this.roles = new HashSet<String>();
|
||||||
this.roles.add(role);
|
this.roles.add(role);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -9,41 +9,33 @@ import java.util.Map;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class UserRepresentation
|
public class UserRepresentation {
|
||||||
{
|
public static class Credential {
|
||||||
public static class Credential
|
|
||||||
{
|
|
||||||
protected String type;
|
protected String type;
|
||||||
protected String value;
|
protected String value;
|
||||||
protected boolean hashed;
|
protected boolean hashed;
|
||||||
|
|
||||||
public String getType()
|
public String getType() {
|
||||||
{
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(String type)
|
public void setType(String type) {
|
||||||
{
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue()
|
public String getValue() {
|
||||||
{
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(String value)
|
public void setValue(String value) {
|
||||||
{
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHashed()
|
public boolean isHashed() {
|
||||||
{
|
|
||||||
return hashed;
|
return hashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHashed(boolean hashed)
|
public void setHashed(boolean hashed) {
|
||||||
{
|
|
||||||
this.hashed = hashed;
|
this.hashed = hashed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,55 +46,45 @@ public class UserRepresentation
|
||||||
protected Map<String, String> attributes;
|
protected Map<String, String> attributes;
|
||||||
protected List<Credential> credentials;
|
protected List<Credential> credentials;
|
||||||
|
|
||||||
public String getSelf()
|
public String getSelf() {
|
||||||
{
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelf(String self)
|
public void setSelf(String self) {
|
||||||
{
|
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername()
|
public String getUsername() {
|
||||||
{
|
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username)
|
public void setUsername(String username) {
|
||||||
{
|
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getAttributes()
|
public Map<String, String> getAttributes() {
|
||||||
{
|
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAttributes(Map<String, String> attributes)
|
public void setAttributes(Map<String, String> attributes) {
|
||||||
{
|
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Credential> getCredentials()
|
public List<Credential> getCredentials() {
|
||||||
{
|
|
||||||
return credentials;
|
return credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCredentials(List<Credential> credentials)
|
public void setCredentials(List<Credential> credentials) {
|
||||||
{
|
|
||||||
this.credentials = credentials;
|
this.credentials = credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserRepresentation attribute(String name, String value)
|
public UserRepresentation attribute(String name, String value) {
|
||||||
{
|
|
||||||
if (this.attributes == null) attributes = new HashMap<String, String>();
|
if (this.attributes == null) attributes = new HashMap<String, String>();
|
||||||
attributes.put(name, value);
|
attributes.put(name, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserRepresentation credential(String type, String value, boolean hashed)
|
public UserRepresentation credential(String type, String value, boolean hashed) {
|
||||||
{
|
|
||||||
if (this.credentials == null) credentials = new ArrayList<Credential>();
|
if (this.credentials == null) credentials = new ArrayList<Credential>();
|
||||||
Credential cred = new Credential();
|
Credential cred = new Credential();
|
||||||
cred.setType(type);
|
cred.setType(type);
|
||||||
|
@ -112,13 +94,11 @@ public class UserRepresentation
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled()
|
public boolean isEnabled() {
|
||||||
{
|
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled)
|
public void setEnabled(boolean enabled) {
|
||||||
{
|
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.keycloak.servlet;
|
package org.keycloak.servlet;
|
||||||
|
|
||||||
import org.jboss.resteasy.plugins.server.servlet.ServletUtil;
|
import org.jboss.resteasy.plugins.server.servlet.ServletUtil;
|
||||||
import org.keycloak.AbstractOAuthClient;
|
|
||||||
import org.jboss.resteasy.spi.ResteasyUriInfo;
|
import org.jboss.resteasy.spi.ResteasyUriInfo;
|
||||||
|
import org.keycloak.AbstractOAuthClient;
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -17,21 +17,17 @@ import java.net.URI;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class ServletOAuthClient extends AbstractOAuthClient
|
public class ServletOAuthClient extends AbstractOAuthClient {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Start the process of obtaining an access token by redirecting the browser
|
* Start the process of obtaining an access token by redirecting the browser
|
||||||
* to the authentication server
|
* to the authentication server
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param relativePath path relative to context root you want auth server to redirect back to
|
* @param relativePath path relative to context root you want auth server to redirect back to
|
||||||
* @param request
|
* @param request
|
||||||
* @param response
|
* @param response
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void redirectRelative(String relativePath, HttpServletRequest request, HttpServletResponse response) throws IOException
|
public void redirectRelative(String relativePath, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
{
|
|
||||||
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
||||||
String redirect = uriInfo.getBaseUriBuilder().path(relativePath).toTemplate();
|
String redirect = uriInfo.getBaseUriBuilder().path(relativePath).toTemplate();
|
||||||
redirect(redirect, request, response);
|
redirect(redirect, request, response);
|
||||||
|
@ -47,8 +43,7 @@ public class ServletOAuthClient extends AbstractOAuthClient
|
||||||
* @param response
|
* @param response
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException
|
public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
{
|
|
||||||
String state = getStateCode();
|
String state = getStateCode();
|
||||||
|
|
||||||
URI url = UriBuilder.fromUri(authUrl)
|
URI url = UriBuilder.fromUri(authUrl)
|
||||||
|
@ -66,24 +61,20 @@ public class ServletOAuthClient extends AbstractOAuthClient
|
||||||
response.sendRedirect(url.toString());
|
response.sendRedirect(url.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getCookieValue(String name, HttpServletRequest request)
|
protected String getCookieValue(String name, HttpServletRequest request) {
|
||||||
{
|
|
||||||
if (request.getCookies() == null) return null;
|
if (request.getCookies() == null) return null;
|
||||||
|
|
||||||
for (Cookie cookie : request.getCookies())
|
for (Cookie cookie : request.getCookies()) {
|
||||||
{
|
|
||||||
if (cookie.getName().equals(name)) return cookie.getValue();
|
if (cookie.getName().equals(name)) return cookie.getValue();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getCode(HttpServletRequest request)
|
protected String getCode(HttpServletRequest request) {
|
||||||
{
|
|
||||||
String query = request.getQueryString();
|
String query = request.getQueryString();
|
||||||
if (query == null) return null;
|
if (query == null) return null;
|
||||||
String[] params = query.split("&");
|
String[] params = query.split("&");
|
||||||
for (String param : params)
|
for (String param : params) {
|
||||||
{
|
|
||||||
int eq = param.indexOf('=');
|
int eq = param.indexOf('=');
|
||||||
if (eq == -1) continue;
|
if (eq == -1) continue;
|
||||||
String name = param.substring(0, eq);
|
String name = param.substring(0, eq);
|
||||||
|
@ -103,8 +94,7 @@ public class ServletOAuthClient extends AbstractOAuthClient
|
||||||
* @throws BadRequestException
|
* @throws BadRequestException
|
||||||
* @throws InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public String getBearerToken(HttpServletRequest request) throws BadRequestException, InternalServerErrorException
|
public String getBearerToken(HttpServletRequest request) throws BadRequestException, InternalServerErrorException {
|
||||||
{
|
|
||||||
String error = request.getParameter("error");
|
String error = request.getParameter("error");
|
||||||
if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error));
|
if (error != null) throw new BadRequestException(new Exception("OAuth error: " + error));
|
||||||
String redirectUri = request.getRequestURL().append("?").append(request.getQueryString()).toString();
|
String redirectUri = request.getRequestURL().append("?").append(request.getQueryString()).toString();
|
||||||
|
@ -115,8 +105,7 @@ public class ServletOAuthClient extends AbstractOAuthClient
|
||||||
String code = request.getParameter("code");
|
String code = request.getParameter("code");
|
||||||
|
|
||||||
if (state == null) throw new BadRequestException(new Exception("state parameter was null"));
|
if (state == null) throw new BadRequestException(new Exception("state parameter was null"));
|
||||||
if (!state.equals(stateCookie))
|
if (!state.equals(stateCookie)) {
|
||||||
{
|
|
||||||
throw new BadRequestException(new Exception("state parameter invalid"));
|
throw new BadRequestException(new Exception("state parameter invalid"));
|
||||||
}
|
}
|
||||||
if (code == null) throw new BadRequestException(new Exception("code parameter was null"));
|
if (code == null) throw new BadRequestException(new Exception("code parameter was null"));
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
<deployment>
|
<deployment>
|
||||||
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
|
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!--
|
|
||||||
<module name="org.jboss.resteasy.resteasy-jaxrs" services="import"/>
|
|
||||||
<module name="org.jboss.resteasy.resteasy-jackson-provider" services="import"/> -->
|
|
||||||
<module name="org.jboss.resteasy.jose-jwt"/>
|
<module name="org.jboss.resteasy.jose-jwt"/>
|
||||||
<module name="org.jboss.resteasy.resteasy-crypto"/>
|
<module name="org.jboss.resteasy.resteasy-crypto"/>
|
||||||
<module name="org.bouncycastle"/>
|
<module name="org.bouncycastle"/>
|
||||||
|
|
|
@ -4,8 +4,7 @@ package org.keycloak.adapters.as7;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface Actions
|
public interface Actions {
|
||||||
{
|
|
||||||
public static final String J_OAUTH_ADMIN_FORCED_LOGOUT = "j_oauth_admin_forced_logout";
|
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_LOGOUT = "j_oauth_logout";
|
||||||
public static final String J_OAUTH_RESOLVE_ACCESS_CODE = "j_oauth_resolve_access_code";
|
public static final String J_OAUTH_RESOLVE_ACCESS_CODE = "j_oauth_resolve_access_code";
|
||||||
|
|
|
@ -10,10 +10,10 @@ import org.apache.catalina.connector.Response;
|
||||||
import org.apache.catalina.core.StandardContext;
|
import org.apache.catalina.core.StandardContext;
|
||||||
import org.apache.catalina.deploy.LoginConfig;
|
import org.apache.catalina.deploy.LoginConfig;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.ResourceMetadata;
|
import org.keycloak.ResourceMetadata;
|
||||||
import org.keycloak.adapters.as7.config.ManagedResourceConfig;
|
import org.keycloak.adapters.as7.config.ManagedResourceConfig;
|
||||||
import org.keycloak.adapters.as7.config.ManagedResourceConfigLoader;
|
import org.keycloak.adapters.as7.config.ManagedResourceConfigLoader;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
|
||||||
|
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
@ -27,60 +27,48 @@ import java.io.IOException;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class BearerTokenAuthenticatorValve extends AuthenticatorBase implements LifecycleListener
|
public class BearerTokenAuthenticatorValve extends AuthenticatorBase implements LifecycleListener {
|
||||||
{
|
|
||||||
private static final Logger log = Logger.getLogger(BearerTokenAuthenticatorValve.class);
|
private static final Logger log = Logger.getLogger(BearerTokenAuthenticatorValve.class);
|
||||||
protected ManagedResourceConfig remoteSkeletonKeyConfig;
|
protected ManagedResourceConfig remoteSkeletonKeyConfig;
|
||||||
protected ResourceMetadata resourceMetadata;
|
protected ResourceMetadata resourceMetadata;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws LifecycleException
|
public void start() throws LifecycleException {
|
||||||
{
|
|
||||||
super.start();
|
super.start();
|
||||||
StandardContext standardContext = (StandardContext) context;
|
StandardContext standardContext = (StandardContext) context;
|
||||||
standardContext.addLifecycleListener(this);
|
standardContext.addLifecycleListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lifecycleEvent(LifecycleEvent event)
|
public void lifecycleEvent(LifecycleEvent event) {
|
||||||
{
|
|
||||||
if (event.getType() == Lifecycle.AFTER_START_EVENT) init();
|
if (event.getType() == Lifecycle.AFTER_START_EVENT) init();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void init()
|
protected void init() {
|
||||||
{
|
|
||||||
ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context);
|
ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context);
|
||||||
resourceMetadata = managedResourceConfigLoader.getResourceMetadata();
|
resourceMetadata = managedResourceConfigLoader.getResourceMetadata();
|
||||||
remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig();
|
remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig();
|
||||||
|
managedResourceConfigLoader.init(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(Request request, Response response) throws IOException, ServletException
|
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
super.invoke(request, response);
|
super.invoke(request, response);
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession
|
ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException
|
protected boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, !remoteSkeletonKeyConfig.isCancelPropagation(), true);
|
CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, !remoteSkeletonKeyConfig.isCancelPropagation(), true);
|
||||||
if (bearer.login(request, response))
|
if (bearer.login(request, response)) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
} catch (LoginException e) {
|
||||||
catch (LoginException e)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ package org.keycloak.adapters.as7;
|
||||||
|
|
||||||
import org.apache.catalina.connector.Request;
|
import org.apache.catalina.connector.Request;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.RSATokenVerifier;
|
import org.keycloak.RSATokenVerifier;
|
||||||
import org.keycloak.ResourceMetadata;
|
import org.keycloak.ResourceMetadata;
|
||||||
import org.keycloak.SkeletonKeyPrincipal;
|
import org.keycloak.SkeletonKeyPrincipal;
|
||||||
import org.keycloak.SkeletonKeySession;
|
import org.keycloak.SkeletonKeySession;
|
||||||
import org.keycloak.VerificationException;
|
import org.keycloak.VerificationException;
|
||||||
import org.keycloak.representations.SkeletonKeyToken;
|
import org.keycloak.representations.SkeletonKeyToken;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
|
||||||
|
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -21,8 +21,7 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class CatalinaBearerTokenAuthenticator
|
public class CatalinaBearerTokenAuthenticator {
|
||||||
{
|
|
||||||
protected ResourceMetadata resourceMetadata;
|
protected ResourceMetadata resourceMetadata;
|
||||||
protected boolean challenge;
|
protected boolean challenge;
|
||||||
protected Logger log = Logger.getLogger(CatalinaBearerTokenAuthenticator.class);
|
protected Logger log = Logger.getLogger(CatalinaBearerTokenAuthenticator.class);
|
||||||
|
@ -31,45 +30,35 @@ public class CatalinaBearerTokenAuthenticator
|
||||||
private Principal principal;
|
private Principal principal;
|
||||||
protected boolean propagateToken;
|
protected boolean propagateToken;
|
||||||
|
|
||||||
public CatalinaBearerTokenAuthenticator(ResourceMetadata resourceMetadata, boolean propagateToken, boolean challenge)
|
public CatalinaBearerTokenAuthenticator(ResourceMetadata resourceMetadata, boolean propagateToken, boolean challenge) {
|
||||||
{
|
|
||||||
this.resourceMetadata = resourceMetadata;
|
this.resourceMetadata = resourceMetadata;
|
||||||
this.challenge = challenge;
|
this.challenge = challenge;
|
||||||
this.propagateToken = propagateToken;
|
this.propagateToken = propagateToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceMetadata getResourceMetadata()
|
public ResourceMetadata getResourceMetadata() {
|
||||||
{
|
|
||||||
return resourceMetadata;
|
return resourceMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTokenString()
|
public String getTokenString() {
|
||||||
{
|
|
||||||
return tokenString;
|
return tokenString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkeletonKeyToken getToken()
|
public SkeletonKeyToken getToken() {
|
||||||
{
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Principal getPrincipal()
|
public Principal getPrincipal() {
|
||||||
{
|
|
||||||
return principal;
|
return principal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean login(Request request, HttpServletResponse response) throws LoginException, IOException
|
public boolean login(Request request, HttpServletResponse response) throws LoginException, IOException {
|
||||||
{
|
|
||||||
String authHeader = request.getHeader("Authorization");
|
String authHeader = request.getHeader("Authorization");
|
||||||
if (authHeader == null)
|
if (authHeader == null) {
|
||||||
{
|
if (challenge) {
|
||||||
if (challenge)
|
|
||||||
{
|
|
||||||
challengeResponse(response, null, null);
|
challengeResponse(response, null, null);
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,42 +70,33 @@ public class CatalinaBearerTokenAuthenticator
|
||||||
|
|
||||||
tokenString = split[1];
|
tokenString = split[1];
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata);
|
token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata);
|
||||||
}
|
} catch (VerificationException e) {
|
||||||
catch (VerificationException e)
|
|
||||||
{
|
|
||||||
log.error("Failed to verify token", e);
|
log.error("Failed to verify token", e);
|
||||||
challengeResponse(response, "invalid_token", e.getMessage());
|
challengeResponse(response, "invalid_token", e.getMessage());
|
||||||
}
|
}
|
||||||
boolean verifyCaller = false;
|
boolean verifyCaller = false;
|
||||||
Set<String> roles = null;
|
Set<String> roles = null;
|
||||||
if (resourceMetadata.getResourceName() != null)
|
if (resourceMetadata.getResourceName() != null) {
|
||||||
{
|
|
||||||
SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName());
|
SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName());
|
||||||
if (access != null) roles = access.getRoles();
|
if (access != null) roles = access.getRoles();
|
||||||
verifyCaller = token.isVerifyCaller(resourceMetadata.getResourceName());
|
verifyCaller = token.isVerifyCaller(resourceMetadata.getResourceName());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
verifyCaller = token.isVerifyCaller();
|
verifyCaller = token.isVerifyCaller();
|
||||||
SkeletonKeyToken.Access access = token.getRealmAccess();
|
SkeletonKeyToken.Access access = token.getRealmAccess();
|
||||||
if (access != null) roles = access.getRoles();
|
if (access != null) roles = access.getRoles();
|
||||||
}
|
}
|
||||||
String surrogate = null;
|
String surrogate = null;
|
||||||
if (verifyCaller)
|
if (verifyCaller) {
|
||||||
{
|
if (token.getTrustedCertificates() == null || token.getTrustedCertificates().size() == 0) {
|
||||||
if (token.getTrustedCertificates() == null || token.getTrustedCertificates().size() == 0)
|
|
||||||
{
|
|
||||||
response.sendError(400);
|
response.sendError(400);
|
||||||
throw new LoginException("No trusted certificates in token");
|
throw new LoginException("No trusted certificates in token");
|
||||||
}
|
}
|
||||||
// for now, we just make sure JBoss Web did two-way SSL
|
// for now, we just make sure JBoss Web did two-way SSL
|
||||||
// assume JBoss Web verifies the client cert
|
// assume JBoss Web verifies the client cert
|
||||||
X509Certificate[] chain = request.getCertificateChain();
|
X509Certificate[] chain = request.getCertificateChain();
|
||||||
if (chain == null || chain.length == 0)
|
if (chain == null || chain.length == 0) {
|
||||||
{
|
|
||||||
response.sendError(400);
|
response.sendError(400);
|
||||||
throw new LoginException("No certificates provided by jboss web to verify the caller");
|
throw new LoginException("No certificates provided by jboss web to verify the caller");
|
||||||
}
|
}
|
||||||
|
@ -126,8 +106,7 @@ public class CatalinaBearerTokenAuthenticator
|
||||||
principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skeletonKeyPrincipal, roles);
|
principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skeletonKeyPrincipal, roles);
|
||||||
request.setUserPrincipal(principal);
|
request.setUserPrincipal(principal);
|
||||||
request.setAuthType("OAUTH_BEARER");
|
request.setAuthType("OAUTH_BEARER");
|
||||||
if (propagateToken)
|
if (propagateToken) {
|
||||||
{
|
|
||||||
SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata);
|
SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata);
|
||||||
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
||||||
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
||||||
|
@ -137,25 +116,19 @@ public class CatalinaBearerTokenAuthenticator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void challengeResponse(HttpServletResponse response, String error, String description) throws LoginException
|
protected void challengeResponse(HttpServletResponse response, String error, String description) throws LoginException {
|
||||||
{
|
|
||||||
StringBuilder header = new StringBuilder("Bearer realm=\"");
|
StringBuilder header = new StringBuilder("Bearer realm=\"");
|
||||||
header.append(resourceMetadata.getRealm()).append("\"");
|
header.append(resourceMetadata.getRealm()).append("\"");
|
||||||
if (error != null)
|
if (error != null) {
|
||||||
{
|
|
||||||
header.append(", error=\"").append(error).append("\"");
|
header.append(", error=\"").append(error).append("\"");
|
||||||
}
|
}
|
||||||
if (description != null)
|
if (description != null) {
|
||||||
{
|
|
||||||
header.append(", error_description=\"").append(description).append("\"");
|
header.append(", error_description=\"").append(description).append("\"");
|
||||||
}
|
}
|
||||||
response.setHeader("WWW-Authenticate", header.toString());
|
response.setHeader("WWW-Authenticate", header.toString());
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
response.sendError(401);
|
response.sendError(401);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
throw new LoginException("Challenged");
|
throw new LoginException("Challenged");
|
||||||
|
|
|
@ -24,22 +24,18 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class CatalinaSecurityContextHelper
|
public class CatalinaSecurityContextHelper {
|
||||||
{
|
public GenericPrincipal createPrincipal(Realm realm, Principal identity, Collection<String> roleSet) {
|
||||||
public GenericPrincipal createPrincipal(Realm realm, Principal identity, Collection<String> roleSet)
|
|
||||||
{
|
|
||||||
Subject subject = new Subject();
|
Subject subject = new Subject();
|
||||||
String credentials = "";
|
String credentials = "";
|
||||||
Set<Principal> principals = subject.getPrincipals();
|
Set<Principal> principals = subject.getPrincipals();
|
||||||
principals.add(identity);
|
principals.add(identity);
|
||||||
Group[] roleSets = getRoleSets(roleSet);
|
Group[] roleSets = getRoleSets(roleSet);
|
||||||
for(int g = 0; g < roleSets.length; g ++)
|
for (int g = 0; g < roleSets.length; g++) {
|
||||||
{
|
|
||||||
Group group = roleSets[g];
|
Group group = roleSets[g];
|
||||||
String name = group.getName();
|
String name = group.getName();
|
||||||
Group subjectGroup = createGroup(name, principals);
|
Group subjectGroup = createGroup(name, principals);
|
||||||
if( subjectGroup instanceof NestableGroup)
|
if (subjectGroup instanceof NestableGroup) {
|
||||||
{
|
|
||||||
/* A NestableGroup only allows Groups to be added to it so we
|
/* A NestableGroup only allows Groups to be added to it so we
|
||||||
need to add a SimpleGroup to subjectRoles to contain the roles
|
need to add a SimpleGroup to subjectRoles to contain the roles
|
||||||
*/
|
*/
|
||||||
|
@ -49,8 +45,7 @@ public class CatalinaSecurityContextHelper
|
||||||
}
|
}
|
||||||
// Copy the group members to the Subject group
|
// Copy the group members to the Subject group
|
||||||
Enumeration<? extends Principal> members = group.members();
|
Enumeration<? extends Principal> members = group.members();
|
||||||
while( members.hasMoreElements() )
|
while (members.hasMoreElements()) {
|
||||||
{
|
|
||||||
Principal role = (Principal) members.nextElement();
|
Principal role = (Principal) members.nextElement();
|
||||||
subjectGroup.addMember(role);
|
subjectGroup.addMember(role);
|
||||||
}
|
}
|
||||||
|
@ -68,6 +63,7 @@ public class CatalinaSecurityContextHelper
|
||||||
userPrincipal, null, credentials, null, subject);
|
userPrincipal, null, credentials, null, subject);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Principal given the authenticated Subject. Currently the first principal that is not of type {@code Group} is
|
* 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.
|
* considered or the single principal inside the CallerPrincipal group.
|
||||||
|
@ -99,37 +95,31 @@ public class CatalinaSecurityContextHelper
|
||||||
return callerPrincipal == null ? principal : callerPrincipal;
|
return callerPrincipal == null ? principal : callerPrincipal;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Group createGroup(String name, Set<Principal> principals)
|
protected Group createGroup(String name, Set<Principal> principals) {
|
||||||
{
|
|
||||||
Group roles = null;
|
Group roles = null;
|
||||||
Iterator<Principal> iter = principals.iterator();
|
Iterator<Principal> iter = principals.iterator();
|
||||||
while( iter.hasNext() )
|
while (iter.hasNext()) {
|
||||||
{
|
|
||||||
Object next = iter.next();
|
Object next = iter.next();
|
||||||
if ((next instanceof Group) == false)
|
if ((next instanceof Group) == false)
|
||||||
continue;
|
continue;
|
||||||
Group grp = (Group) next;
|
Group grp = (Group) next;
|
||||||
if( grp.getName().equals(name) )
|
if (grp.getName().equals(name)) {
|
||||||
{
|
|
||||||
roles = grp;
|
roles = grp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we did not find a group create one
|
// If we did not find a group create one
|
||||||
if( roles == null )
|
if (roles == null) {
|
||||||
{
|
|
||||||
roles = new SimpleGroup(name);
|
roles = new SimpleGroup(name);
|
||||||
principals.add(roles);
|
principals.add(roles);
|
||||||
}
|
}
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Group[] getRoleSets(Collection<String> roleSet)
|
protected Group[] getRoleSets(Collection<String> roleSet) {
|
||||||
{
|
|
||||||
SimpleGroup roles = new SimpleGroup("Roles");
|
SimpleGroup roles = new SimpleGroup("Roles");
|
||||||
Group[] roleSets = {roles};
|
Group[] roleSets = {roles};
|
||||||
for (String role : roleSet)
|
for (String role : roleSet) {
|
||||||
{
|
|
||||||
roles.addMember(new SimplePrincipal(role));
|
roles.addMember(new SimplePrincipal(role));
|
||||||
}
|
}
|
||||||
return roleSets;
|
return roleSets;
|
||||||
|
|
|
@ -25,6 +25,9 @@ import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
|
||||||
import org.jboss.resteasy.jwt.JsonSerialization;
|
import org.jboss.resteasy.jwt.JsonSerialization;
|
||||||
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
||||||
import org.jboss.resteasy.plugins.server.servlet.ServletUtil;
|
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.EnvUtil;
|
||||||
import org.keycloak.PemUtils;
|
import org.keycloak.PemUtils;
|
||||||
import org.keycloak.ResourceMetadata;
|
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.adapters.as7.config.ManagedResourceConfig;
|
||||||
import org.keycloak.representations.AccessTokenResponse;
|
import org.keycloak.representations.AccessTokenResponse;
|
||||||
import org.keycloak.representations.SkeletonKeyToken;
|
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.security.auth.login.LoginException;
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
|
@ -79,12 +79,10 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class OAuthAuthenticationServerValve extends FormAuthenticator implements LifecycleListener
|
public class OAuthAuthenticationServerValve extends FormAuthenticator implements LifecycleListener {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
public static class AccessCode
|
public static class AccessCode {
|
||||||
{
|
|
||||||
protected String id = UUID.randomUUID().toString() + System.currentTimeMillis();
|
protected String id = UUID.randomUUID().toString() + System.currentTimeMillis();
|
||||||
protected long expiration;
|
protected long expiration;
|
||||||
protected SkeletonKeyToken token;
|
protected SkeletonKeyToken token;
|
||||||
|
@ -92,63 +90,51 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
protected boolean sso;
|
protected boolean sso;
|
||||||
protected String redirect;
|
protected String redirect;
|
||||||
|
|
||||||
public boolean isExpired()
|
public boolean isExpired() {
|
||||||
{
|
|
||||||
return expiration != 0 && (System.currentTimeMillis() / 1000) > expiration;
|
return expiration != 0 && (System.currentTimeMillis() / 1000) > expiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId()
|
public String getId() {
|
||||||
{
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getExpiration()
|
public long getExpiration() {
|
||||||
{
|
|
||||||
return expiration;
|
return expiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExpiration(long expiration)
|
public void setExpiration(long expiration) {
|
||||||
{
|
|
||||||
this.expiration = expiration;
|
this.expiration = expiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkeletonKeyToken getToken()
|
public SkeletonKeyToken getToken() {
|
||||||
{
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setToken(SkeletonKeyToken token)
|
public void setToken(SkeletonKeyToken token) {
|
||||||
{
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClient()
|
public String getClient() {
|
||||||
{
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClient(String client)
|
public void setClient(String client) {
|
||||||
{
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSso()
|
public boolean isSso() {
|
||||||
{
|
|
||||||
return sso;
|
return sso;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSso(boolean sso)
|
public void setSso(boolean sso) {
|
||||||
{
|
|
||||||
this.sso = sso;
|
this.sso = sso;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRedirect()
|
public String getRedirect() {
|
||||||
{
|
|
||||||
return redirect;
|
return redirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRedirect(String redirect)
|
public void setRedirect(String redirect) {
|
||||||
{
|
|
||||||
this.redirect = redirect;
|
this.redirect = redirect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,8 +144,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
|
|
||||||
private static AtomicLong counter = new AtomicLong(1);
|
private static AtomicLong counter = new AtomicLong(1);
|
||||||
|
|
||||||
private static String generateId()
|
private static String generateId() {
|
||||||
{
|
|
||||||
return counter.getAndIncrement() + "." + UUID.randomUUID().toString();
|
return counter.getAndIncrement() + "." + UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +159,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
protected ObjectWriter accessTokenResponseWriter;
|
protected ObjectWriter accessTokenResponseWriter;
|
||||||
protected ObjectWriter mapWriter;
|
protected ObjectWriter mapWriter;
|
||||||
|
|
||||||
private static KeyStore loadKeyStore(String filename, String password) throws Exception
|
private static KeyStore loadKeyStore(String filename, String password) throws Exception {
|
||||||
{
|
|
||||||
KeyStore trustStore = KeyStore.getInstance(KeyStore
|
KeyStore trustStore = KeyStore.getInstance(KeyStore
|
||||||
.getDefaultType());
|
.getDefaultType());
|
||||||
File truststoreFile = new File(filename);
|
File truststoreFile = new File(filename);
|
||||||
|
@ -186,21 +170,18 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws LifecycleException
|
public void start() throws LifecycleException {
|
||||||
{
|
|
||||||
super.start();
|
super.start();
|
||||||
StandardContext standardContext = (StandardContext) context;
|
StandardContext standardContext = (StandardContext) context;
|
||||||
standardContext.addLifecycleListener(this);
|
standardContext.addLifecycleListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lifecycleEvent(LifecycleEvent event)
|
public void lifecycleEvent(LifecycleEvent event) {
|
||||||
{
|
|
||||||
if (event.getType() == Lifecycle.AFTER_START_EVENT) init();
|
if (event.getType() == Lifecycle.AFTER_START_EVENT) init();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void init()
|
protected void init() {
|
||||||
{
|
|
||||||
mapper = new ObjectMapper();
|
mapper = new ObjectMapper();
|
||||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
||||||
accessTokenResponseWriter = mapper.writerWithType(AccessTokenResponse.class);
|
accessTokenResponseWriter = mapper.writerWithType(AccessTokenResponse.class);
|
||||||
|
@ -208,95 +189,66 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
|
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
String path = context.getServletContext().getInitParameter("skeleton.key.config.file");
|
String path = context.getServletContext().getInitParameter("skeleton.key.config.file");
|
||||||
if (path == null)
|
if (path == null) {
|
||||||
{
|
|
||||||
is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json");
|
is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json");
|
||||||
}
|
} else {
|
||||||
else
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
is = new FileInputStream(path);
|
is = new FileInputStream(path);
|
||||||
}
|
} catch (FileNotFoundException e) {
|
||||||
catch (FileNotFoundException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
skeletonKeyConfig = mapper.readValue(is, AuthServerConfig.class);
|
skeletonKeyConfig = mapper.readValue(is, AuthServerConfig.class);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
if (skeletonKeyConfig.getLoginRole() == null)
|
if (skeletonKeyConfig.getLoginRole() == null) {
|
||||||
{
|
|
||||||
throw new RuntimeException("You must define the login-role in your config file");
|
throw new RuntimeException("You must define the login-role in your config file");
|
||||||
}
|
}
|
||||||
if (skeletonKeyConfig.getClientRole() == null)
|
if (skeletonKeyConfig.getClientRole() == null) {
|
||||||
{
|
|
||||||
throw new RuntimeException("You must define the oauth-client-role in your config file");
|
throw new RuntimeException("You must define the oauth-client-role in your config file");
|
||||||
}
|
}
|
||||||
if (skeletonKeyConfig.getRealmPrivateKey() != null)
|
if (skeletonKeyConfig.getRealmPrivateKey() != null) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
realmPrivateKey = PemUtils.decodePrivateKey(skeletonKeyConfig.getRealmPrivateKey());
|
realmPrivateKey = PemUtils.decodePrivateKey(skeletonKeyConfig.getRealmPrivateKey());
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (skeletonKeyConfig.getRealmPublicKey() != null)
|
if (skeletonKeyConfig.getRealmPublicKey() != null) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
realmPublicKey = PemUtils.decodePublicKey(skeletonKeyConfig.getRealmPublicKey());
|
realmPublicKey = PemUtils.decodePublicKey(skeletonKeyConfig.getRealmPublicKey());
|
||||||
realmPublicKeyPem = skeletonKeyConfig.getRealmPublicKey();
|
realmPublicKeyPem = skeletonKeyConfig.getRealmPublicKey();
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (skeletonKeyConfig.getRealmKeyStore() != null)
|
if (skeletonKeyConfig.getRealmKeyStore() != null) {
|
||||||
{
|
|
||||||
if (skeletonKeyConfig.getRealmKeyAlias() == null) throw new RuntimeException("Must define realm-key-alias");
|
if (skeletonKeyConfig.getRealmKeyAlias() == null) throw new RuntimeException("Must define realm-key-alias");
|
||||||
String keystorePath = EnvUtil.replace(skeletonKeyConfig.getRealmKeyStore());
|
String keystorePath = EnvUtil.replace(skeletonKeyConfig.getRealmKeyStore());
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
KeyStore ks = loadKeyStore(keystorePath, skeletonKeyConfig.getRealmKeystorePassword());
|
KeyStore ks = loadKeyStore(keystorePath, skeletonKeyConfig.getRealmKeystorePassword());
|
||||||
if (realmPrivateKey == null)
|
if (realmPrivateKey == null) {
|
||||||
{
|
|
||||||
realmPrivateKey = (PrivateKey) ks.getKey(skeletonKeyConfig.getRealmKeyAlias(), skeletonKeyConfig.getRealmPrivateKeyPassword().toCharArray());
|
realmPrivateKey = (PrivateKey) ks.getKey(skeletonKeyConfig.getRealmKeyAlias(), skeletonKeyConfig.getRealmPrivateKeyPassword().toCharArray());
|
||||||
}
|
}
|
||||||
if (realmPublicKey == null)
|
if (realmPublicKey == null) {
|
||||||
{
|
|
||||||
Certificate cert = ks.getCertificate(skeletonKeyConfig.getRealmKeyAlias());
|
Certificate cert = ks.getCertificate(skeletonKeyConfig.getRealmKeyAlias());
|
||||||
realmPublicKey = cert.getPublicKey();
|
realmPublicKey = cert.getPublicKey();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (realmPublicKey == null) throw new RuntimeException("You have not declared a keystore or public key");
|
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 (realmPrivateKey == null) throw new RuntimeException("You have not declared a keystore or private key");
|
||||||
if (realmPublicKeyPem == null)
|
if (realmPublicKeyPem == null) {
|
||||||
{
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PEMWriter writer = new PEMWriter(sw);
|
PEMWriter writer = new PEMWriter(sw);
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
writer.writeObject(realmPublicKey);
|
writer.writeObject(realmPublicKey);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
realmPublicKeyPem = sw.toString();
|
realmPublicKeyPem = sw.toString();
|
||||||
|
@ -305,47 +257,36 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
providers = new ResteasyProviderFactory();
|
providers = new ResteasyProviderFactory();
|
||||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||||
Thread.currentThread().setContextClassLoader(OAuthAuthenticationServerValve.class.getClassLoader());
|
Thread.currentThread().setContextClassLoader(OAuthAuthenticationServerValve.class.getClassLoader());
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
ResteasyProviderFactory.getInstance(); // initialize builtins
|
ResteasyProviderFactory.getInstance(); // initialize builtins
|
||||||
RegisterBuiltin.register(providers);
|
RegisterBuiltin.register(providers);
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
Thread.currentThread().setContextClassLoader(old);
|
Thread.currentThread().setContextClassLoader(old);
|
||||||
}
|
}
|
||||||
resourceMetadata = new ResourceMetadata();
|
resourceMetadata = new ResourceMetadata();
|
||||||
resourceMetadata.setRealm(skeletonKeyConfig.getRealm());
|
resourceMetadata.setRealm(skeletonKeyConfig.getRealm());
|
||||||
resourceMetadata.setRealmKey(realmPublicKey);
|
resourceMetadata.setRealmKey(realmPublicKey);
|
||||||
String truststore = skeletonKeyConfig.getTruststore();
|
String truststore = skeletonKeyConfig.getTruststore();
|
||||||
if (truststore != null)
|
if (truststore != null) {
|
||||||
{
|
|
||||||
truststore = EnvUtil.replace(truststore);
|
truststore = EnvUtil.replace(truststore);
|
||||||
String truststorePassword = skeletonKeyConfig.getTruststorePassword();
|
String truststorePassword = skeletonKeyConfig.getTruststorePassword();
|
||||||
KeyStore trust = null;
|
KeyStore trust = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
trust = loadKeyStore(truststore, truststorePassword);
|
trust = loadKeyStore(truststore, truststorePassword);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException("Failed to load truststore", e);
|
throw new RuntimeException("Failed to load truststore", e);
|
||||||
}
|
}
|
||||||
resourceMetadata.setTruststore(trust);
|
resourceMetadata.setTruststore(trust);
|
||||||
}
|
}
|
||||||
String clientKeystore = skeletonKeyConfig.getClientKeystore();
|
String clientKeystore = skeletonKeyConfig.getClientKeystore();
|
||||||
String clientKeyPassword = null;
|
String clientKeyPassword = null;
|
||||||
if (clientKeystore != null)
|
if (clientKeystore != null) {
|
||||||
{
|
|
||||||
clientKeystore = EnvUtil.replace(clientKeystore);
|
clientKeystore = EnvUtil.replace(clientKeystore);
|
||||||
String clientKeystorePassword = skeletonKeyConfig.getClientKeystorePassword();
|
String clientKeystorePassword = skeletonKeyConfig.getClientKeystorePassword();
|
||||||
KeyStore serverKS = null;
|
KeyStore serverKS = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
serverKS = loadKeyStore(clientKeystore, clientKeystorePassword);
|
serverKS = loadKeyStore(clientKeystore, clientKeystorePassword);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException("Failed to load keystore", e);
|
throw new RuntimeException("Failed to load keystore", e);
|
||||||
}
|
}
|
||||||
resourceMetadata.setClientKeystore(serverKS);
|
resourceMetadata.setClientKeystore(serverKS);
|
||||||
|
@ -355,66 +296,48 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(Request request, Response response) throws IOException, ServletException
|
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
String contextPath = request.getContextPath();
|
String contextPath = request.getContextPath();
|
||||||
String requestURI = request.getDecodedRequestURI();
|
String requestURI = request.getDecodedRequestURI();
|
||||||
log.debug("--- invoke: " + requestURI);
|
log.debug("--- invoke: " + requestURI);
|
||||||
if (request.getMethod().equalsIgnoreCase("GET")
|
if (request.getMethod().equalsIgnoreCase("GET")
|
||||||
&& context.getLoginConfig().getLoginPage().equals(request.getRequestPathMB().toString()))
|
&& context.getLoginConfig().getLoginPage().equals(request.getRequestPathMB().toString())) {
|
||||||
{
|
|
||||||
if (handleLoginPage(request, response)) return;
|
if (handleLoginPage(request, response)) return;
|
||||||
}
|
} else if (request.getMethod().equalsIgnoreCase("GET")
|
||||||
else if (request.getMethod().equalsIgnoreCase("GET")
|
&& requestURI.endsWith(Actions.J_OAUTH_LOGOUT)) {
|
||||||
&& requestURI.endsWith(Actions.J_OAUTH_LOGOUT))
|
|
||||||
{
|
|
||||||
logoutCurrentUser(request, response);
|
logoutCurrentUser(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||||
else if (request.getMethod().equalsIgnoreCase("POST")
|
&& requestURI.endsWith(Actions.J_OAUTH_ADMIN_FORCED_LOGOUT)) {
|
||||||
&& requestURI.endsWith(Actions.J_OAUTH_ADMIN_FORCED_LOGOUT))
|
|
||||||
{
|
|
||||||
adminLogout(request, response);
|
adminLogout(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||||
else if (request.getMethod().equalsIgnoreCase("POST")
|
|
||||||
&& requestURI.startsWith(contextPath) &&
|
&& requestURI.startsWith(contextPath) &&
|
||||||
requestURI.endsWith(Constants.FORM_ACTION)
|
requestURI.endsWith(Constants.FORM_ACTION)
|
||||||
&& request.getParameter("client_id") != null)
|
&& request.getParameter("client_id") != null) {
|
||||||
{
|
|
||||||
handleOAuth(request, response);
|
handleOAuth(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||||
else if (request.getMethod().equalsIgnoreCase("POST")
|
&& requestURI.endsWith(Actions.J_OAUTH_TOKEN_GRANT)) {
|
||||||
&& requestURI.endsWith(Actions.J_OAUTH_TOKEN_GRANT))
|
|
||||||
{
|
|
||||||
tokenGrant(request, response);
|
tokenGrant(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||||
else if (request.getMethod().equalsIgnoreCase("POST")
|
|
||||||
&& requestURI.startsWith(contextPath) &&
|
&& requestURI.startsWith(contextPath) &&
|
||||||
requestURI.endsWith(Actions.J_OAUTH_RESOLVE_ACCESS_CODE))
|
requestURI.endsWith(Actions.J_OAUTH_RESOLVE_ACCESS_CODE)) {
|
||||||
{
|
|
||||||
resolveAccessCode(request, response);
|
resolveAccessCode(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (request.getMethod().equalsIgnoreCase("GET")
|
||||||
else if (request.getMethod().equalsIgnoreCase("GET")
|
|
||||||
&& requestURI.startsWith(contextPath) &&
|
&& requestURI.startsWith(contextPath) &&
|
||||||
requestURI.endsWith("j_oauth_realm_info.html"))
|
requestURI.endsWith("j_oauth_realm_info.html")) {
|
||||||
{
|
|
||||||
publishRealmInfoHtml(request, response);
|
publishRealmInfoHtml(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// propagate the skeleton key token string?
|
// propagate the skeleton key token string?
|
||||||
if (!skeletonKeyConfig.isCancelPropagation())
|
if (!skeletonKeyConfig.isCancelPropagation()) {
|
||||||
{
|
if (request.getAttribute(SkeletonKeySession.class.getName()) == null && request.getSessionInternal() != null) {
|
||||||
if (request.getAttribute(SkeletonKeySession.class.getName()) == null && request.getSessionInternal() != null)
|
|
||||||
{
|
|
||||||
SkeletonKeySession skSession = (SkeletonKeySession) request.getSessionInternal().getNote(SkeletonKeySession.class.getName());
|
SkeletonKeySession skSession = (SkeletonKeySession) request.getSessionInternal().getNote(SkeletonKeySession.class.getName());
|
||||||
if (skSession != null)
|
if (skSession != null) {
|
||||||
{
|
|
||||||
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
||||||
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
||||||
}
|
}
|
||||||
|
@ -422,15 +345,12 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
}
|
}
|
||||||
request.setAttribute("OAUTH_FORM_ACTION", "j_security_check");
|
request.setAttribute("OAUTH_FORM_ACTION", "j_security_check");
|
||||||
super.invoke(request, response);
|
super.invoke(request, response);
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession
|
ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean handleLoginPage(Request request, Response response) throws IOException, ServletException
|
protected boolean handleLoginPage(Request request, Response response) throws IOException, ServletException {
|
||||||
{
|
|
||||||
String client_id = request.getParameter("client_id");
|
String client_id = request.getParameter("client_id");
|
||||||
// if this is not an OAUTH redirect, just return and let the default flow happen
|
// if this is not an OAUTH redirect, just return and let the default flow happen
|
||||||
if (client_id == null) return false;
|
if (client_id == null) return false;
|
||||||
|
@ -438,8 +358,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
String redirect_uri = request.getParameter("redirect_uri");
|
String redirect_uri = request.getParameter("redirect_uri");
|
||||||
String state = request.getParameter("state");
|
String state = request.getParameter("state");
|
||||||
|
|
||||||
if (redirect_uri == null)
|
if (redirect_uri == null) {
|
||||||
{
|
|
||||||
response.sendError(400, "No oauth redirect query parameter set");
|
response.sendError(400, "No oauth redirect query parameter set");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -449,14 +368,11 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
else if (!skeletonKeyConfig.isSsoDisabled()
|
else if (!skeletonKeyConfig.isSsoDisabled()
|
||||||
&& request.getSessionInternal() != null
|
&& request.getSessionInternal() != null
|
||||||
&& request.getSessionInternal().getPrincipal() != null
|
&& request.getSessionInternal().getPrincipal() != null
|
||||||
&& request.getParameter("login") != null)
|
&& request.getParameter("login") != null) {
|
||||||
{
|
|
||||||
log.debug("We're ALREADY LOGGED IN!!!");
|
log.debug("We're ALREADY LOGGED IN!!!");
|
||||||
GenericPrincipal gp = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
GenericPrincipal gp = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||||
redirectAccessCode(true, response, redirect_uri, client_id, state, gp);
|
redirectAccessCode(true, response, redirect_uri, client_id, state, gp);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
UriBuilder builder = UriBuilder.fromUri("j_security_check")
|
UriBuilder builder = UriBuilder.fromUri("j_security_check")
|
||||||
.queryParam("redirect_uri", redirect_uri)
|
.queryParam("redirect_uri", redirect_uri)
|
||||||
.queryParam("client_id", client_id);
|
.queryParam("client_id", client_id);
|
||||||
|
@ -468,66 +384,49 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GenericPrincipal checkLoggedIn(Request request, HttpServletResponse response)
|
protected GenericPrincipal checkLoggedIn(Request request, HttpServletResponse response) {
|
||||||
{
|
if (request.getPrincipal() != null) {
|
||||||
if (request.getPrincipal() != null)
|
|
||||||
{
|
|
||||||
return (GenericPrincipal) request.getPrincipal();
|
return (GenericPrincipal) request.getPrincipal();
|
||||||
}
|
} else if (request.getSessionInternal() != null && request.getSessionInternal().getPrincipal() != null) {
|
||||||
else if (request.getSessionInternal() != null && request.getSessionInternal().getPrincipal() != null)
|
|
||||||
{
|
|
||||||
return (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
return (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void adminLogout(Request request, HttpServletResponse response) throws IOException
|
protected void adminLogout(Request request, HttpServletResponse response) throws IOException {
|
||||||
{
|
|
||||||
log.debug("<< adminLogout");
|
log.debug("<< adminLogout");
|
||||||
GenericPrincipal gp = checkLoggedIn(request, response);
|
GenericPrincipal gp = checkLoggedIn(request, response);
|
||||||
if (gp == null)
|
if (gp == null) {
|
||||||
{
|
if (bearer(request, response, false)) {
|
||||||
if (bearer(request, response, false))
|
|
||||||
{
|
|
||||||
gp = (GenericPrincipal) request.getPrincipal();
|
gp = (GenericPrincipal) request.getPrincipal();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
response.sendError(403);
|
response.sendError(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!gp.hasRole(skeletonKeyConfig.getAdminRole()))
|
if (!gp.hasRole(skeletonKeyConfig.getAdminRole())) {
|
||||||
{
|
|
||||||
response.sendError(403);
|
response.sendError(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String logoutUser = request.getParameter("user");
|
String logoutUser = request.getParameter("user");
|
||||||
if (logoutUser != null)
|
if (logoutUser != null) {
|
||||||
{
|
|
||||||
userSessionManagement.logout(logoutUser);
|
userSessionManagement.logout(logoutUser);
|
||||||
logoutResources(logoutUser, gp.getName());
|
logoutResources(logoutUser, gp.getName());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
userSessionManagement.logoutAllBut(gp.getName());
|
userSessionManagement.logoutAllBut(gp.getName());
|
||||||
logoutResources(null, gp.getName());
|
logoutResources(null, gp.getName());
|
||||||
}
|
}
|
||||||
String forwardTo = request.getParameter("forward");
|
String forwardTo = request.getParameter("forward");
|
||||||
if (forwardTo == null)
|
if (forwardTo == null) {
|
||||||
{
|
|
||||||
response.setStatus(204);
|
response.setStatus(204);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RequestDispatcher disp =
|
RequestDispatcher disp =
|
||||||
context.getServletContext().getRequestDispatcher(forwardTo);
|
context.getServletContext().getRequestDispatcher(forwardTo);
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
disp.forward(request.getRequest(), response);
|
disp.forward(request.getRequest(), response);
|
||||||
}
|
} catch (Throwable t) {
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
|
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
|
||||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||||
"failed to forward");
|
"failed to forward");
|
||||||
|
@ -537,10 +436,8 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void logoutCurrentUser(Request request, HttpServletResponse response) throws IOException
|
protected void logoutCurrentUser(Request request, HttpServletResponse response) throws IOException {
|
||||||
{
|
if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null) {
|
||||||
if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null)
|
|
||||||
{
|
|
||||||
redirectToWelcomePage(request, response);
|
redirectToWelcomePage(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -555,10 +452,8 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
redirectToWelcomePage(request, response);
|
redirectToWelcomePage(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void logoutResources(String username, String admin)
|
protected void logoutResources(String username, String admin) {
|
||||||
{
|
if (skeletonKeyConfig.getResources().size() != 0) {
|
||||||
if (skeletonKeyConfig.getResources().size() != 0)
|
|
||||||
{
|
|
||||||
SkeletonKeyToken token = new SkeletonKeyToken();
|
SkeletonKeyToken token = new SkeletonKeyToken();
|
||||||
token.id(generateId());
|
token.id(generateId());
|
||||||
token.principal(admin);
|
token.principal(admin);
|
||||||
|
@ -573,12 +468,9 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
.trustStore(resourceMetadata.getTruststore())
|
.trustStore(resourceMetadata.getTruststore())
|
||||||
.keyStore(resourceMetadata.getClientKeystore(), resourceMetadata.getClientKeyPassword())
|
.keyStore(resourceMetadata.getClientKeystore(), resourceMetadata.getClientKeyPassword())
|
||||||
.build();
|
.build();
|
||||||
try
|
try {
|
||||||
{
|
for (String resource : skeletonKeyConfig.getResources()) {
|
||||||
for (String resource : skeletonKeyConfig.getResources())
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
log.debug("logging out: " + resource);
|
log.debug("logging out: " + resource);
|
||||||
WebTarget target = client.target(resource).path(Actions.J_OAUTH_REMOTE_LOGOUT);
|
WebTarget target = client.target(resource).path(Actions.J_OAUTH_REMOTE_LOGOUT);
|
||||||
if (username != null) target = target.queryParam("user", username);
|
if (username != null) target = target.queryParam("user", username);
|
||||||
|
@ -587,38 +479,29 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
.put(null);
|
.put(null);
|
||||||
if (response.getStatus() != 204) log.error("Failed to log out");
|
if (response.getStatus() != 204) log.error("Failed to log out");
|
||||||
response.close();
|
response.close();
|
||||||
}
|
} catch (Exception ignored) {
|
||||||
catch (Exception ignored)
|
|
||||||
{
|
|
||||||
log.error("Failed to log out", ignored);
|
log.error("Failed to log out", ignored);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void redirectToWelcomePage(Request request, HttpServletResponse response) throws IOException
|
protected void redirectToWelcomePage(Request request, HttpServletResponse response) throws IOException {
|
||||||
{
|
|
||||||
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
||||||
String[] welcomes = context.findWelcomeFiles();
|
String[] welcomes = context.findWelcomeFiles();
|
||||||
if (welcomes.length > 0)
|
if (welcomes.length > 0) {
|
||||||
{
|
|
||||||
UriBuilder welcome = uriInfo.getBaseUriBuilder().path(welcomes[0]);
|
UriBuilder welcome = uriInfo.getBaseUriBuilder().path(welcomes[0]);
|
||||||
response.sendRedirect(welcome.toTemplate());
|
response.sendRedirect(welcome.toTemplate());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
response.setStatus(204);
|
response.setStatus(204);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void publishRealmInfoHtml(Request request, HttpServletResponse response) throws IOException
|
protected void publishRealmInfoHtml(Request request, HttpServletResponse response) throws IOException {
|
||||||
{
|
|
||||||
ManagedResourceConfig rep = getRealmRepresentation(request);
|
ManagedResourceConfig rep = getRealmRepresentation(request);
|
||||||
StringWriter writer;
|
StringWriter writer;
|
||||||
String json;
|
String json;
|
||||||
|
@ -663,8 +546,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected ManagedResourceConfig getRealmRepresentation(Request request)
|
protected ManagedResourceConfig getRealmRepresentation(Request request) {
|
||||||
{
|
|
||||||
ManagedResourceConfig rep = new ManagedResourceConfig();
|
ManagedResourceConfig rep = new ManagedResourceConfig();
|
||||||
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
||||||
UriBuilder authUrl = uriInfo.getBaseUriBuilder().path(context.getLoginConfig().getLoginPage());
|
UriBuilder authUrl = uriInfo.getBaseUriBuilder().path(context.getLoginConfig().getLoginPage());
|
||||||
|
@ -677,36 +559,27 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean bearer(Request request, HttpServletResponse response, boolean propagate) throws IOException
|
public boolean bearer(Request request, HttpServletResponse response, boolean propagate) throws IOException {
|
||||||
{
|
if (request.getHeader("Authorization") != null) {
|
||||||
if (request.getHeader("Authorization") != null)
|
|
||||||
{
|
|
||||||
CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, true, false);
|
CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, true, false);
|
||||||
try
|
try {
|
||||||
{
|
if (bearer.login(request, response)) {
|
||||||
if (bearer.login(request, response))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} catch (LoginException e) {
|
||||||
catch (LoginException e)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void register(Request request, HttpServletResponse response, Principal principal, String authType, String username, String password)
|
protected void register(Request request, HttpServletResponse response, Principal principal, String authType, String username, String password) {
|
||||||
{
|
|
||||||
super.register(request, response, principal, authType, username, password);
|
super.register(request, response, principal, authType, username, password);
|
||||||
log.debug("authenticate userSessionManage.login(): " + principal.getName());
|
log.debug("authenticate userSessionManage.login(): " + principal.getName());
|
||||||
userSessionManagement.login(request.getSessionInternal(), principal.getName());
|
userSessionManagement.login(request.getSessionInternal(), principal.getName());
|
||||||
if (!skeletonKeyConfig.isCancelPropagation())
|
if (!skeletonKeyConfig.isCancelPropagation()) {
|
||||||
{
|
|
||||||
GenericPrincipal gp = (GenericPrincipal) request.getPrincipal();
|
GenericPrincipal gp = (GenericPrincipal) request.getPrincipal();
|
||||||
if (gp != null)
|
if (gp != null) {
|
||||||
{
|
|
||||||
SkeletonKeyToken token = buildToken(gp);
|
SkeletonKeyToken token = buildToken(gp);
|
||||||
String stringToken = buildTokenString(realmPrivateKey, token);
|
String stringToken = buildTokenString(realmPrivateKey, token);
|
||||||
SkeletonKeySession skSession = new SkeletonKeySession(stringToken, resourceMetadata);
|
SkeletonKeySession skSession = new SkeletonKeySession(stringToken, resourceMetadata);
|
||||||
|
@ -718,20 +591,16 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException
|
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
|
||||||
{
|
if (bearer(request, response, true)) {
|
||||||
if (bearer(request, response, true))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.authenticate(request, response, config);
|
return super.authenticate(request, response, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void resolveAccessCode(Request request, Response response) throws IOException
|
protected void resolveAccessCode(Request request, Response response) throws IOException {
|
||||||
{
|
if (!request.isSecure()) {
|
||||||
if (!request.isSecure())
|
|
||||||
{
|
|
||||||
response.sendError(400);
|
response.sendError(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -740,16 +609,12 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
String code = request.getParameter("code");
|
String code = request.getParameter("code");
|
||||||
JWSInput input = new JWSInput(code, providers);
|
JWSInput input = new JWSInput(code, providers);
|
||||||
boolean verifiedCode = false;
|
boolean verifiedCode = false;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
verifiedCode = RSAProvider.verify(input, realmPublicKey);
|
verifiedCode = RSAProvider.verify(input, realmPublicKey);
|
||||||
}
|
} catch (Exception ignored) {
|
||||||
catch (Exception ignored)
|
|
||||||
{
|
|
||||||
log.error("Failed to verify signature", ignored);
|
log.error("Failed to verify signature", ignored);
|
||||||
}
|
}
|
||||||
if (!verifiedCode)
|
if (!verifiedCode) {
|
||||||
{
|
|
||||||
Map<String, String> res = new HashMap<String, String>();
|
Map<String, String> res = new HashMap<String, String>();
|
||||||
res.put("error", "invalid_grant");
|
res.put("error", "invalid_grant");
|
||||||
res.put("error_description", "Unable to verify code signature");
|
res.put("error_description", "Unable to verify code signature");
|
||||||
|
@ -764,19 +629,16 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
String redirect = request.getParameter("redirect_uri");
|
String redirect = request.getParameter("redirect_uri");
|
||||||
|
|
||||||
GenericPrincipal gp = basicAuth(request, response);
|
GenericPrincipal gp = basicAuth(request, response);
|
||||||
if (gp == null)
|
if (gp == null) {
|
||||||
{
|
|
||||||
log.error("Failed to authenticate client_id");
|
log.error("Failed to authenticate client_id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (accessCode == null)
|
if (accessCode == null) {
|
||||||
{
|
|
||||||
log.error("No access code: " + code);
|
log.error("No access code: " + code);
|
||||||
response.sendError(400);
|
response.sendError(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (accessCode.isExpired())
|
if (accessCode.isExpired()) {
|
||||||
{
|
|
||||||
log.debug("Access code expired");
|
log.debug("Access code expired");
|
||||||
Map<String, String> res = new HashMap<String, String>();
|
Map<String, String> res = new HashMap<String, String>();
|
||||||
res.put("error", "invalid_grant");
|
res.put("error", "invalid_grant");
|
||||||
|
@ -787,8 +649,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
response.getOutputStream().flush();
|
response.getOutputStream().flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!accessCode.getToken().isActive())
|
if (!accessCode.getToken().isActive()) {
|
||||||
{
|
|
||||||
log.debug("token not active");
|
log.debug("token not active");
|
||||||
Map<String, String> res = new HashMap<String, String>();
|
Map<String, String> res = new HashMap<String, String>();
|
||||||
res.put("error", "invalid_grant");
|
res.put("error", "invalid_grant");
|
||||||
|
@ -799,8 +660,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
response.getOutputStream().flush();
|
response.getOutputStream().flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!gp.getName().equals(accessCode.getClient()))
|
if (!gp.getName().equals(accessCode.getClient())) {
|
||||||
{
|
|
||||||
log.debug("not equal client");
|
log.debug("not equal client");
|
||||||
Map<String, String> res = new HashMap<String, String>();
|
Map<String, String> res = new HashMap<String, String>();
|
||||||
res.put("error", "invalid_grant");
|
res.put("error", "invalid_grant");
|
||||||
|
@ -811,8 +671,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
response.getOutputStream().flush();
|
response.getOutputStream().flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!accessCode.getRedirect().equals(redirect))
|
if (!accessCode.getRedirect().equals(redirect)) {
|
||||||
{
|
|
||||||
log.debug("not equal redirect");
|
log.debug("not equal redirect");
|
||||||
Map<String, String> res = new HashMap<String, String>();
|
Map<String, String> res = new HashMap<String, String>();
|
||||||
res.put("error", "invalid_grant");
|
res.put("error", "invalid_grant");
|
||||||
|
@ -823,8 +682,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
response.getOutputStream().flush();
|
response.getOutputStream().flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (accessCode.isSso() && !gp.hasRole(skeletonKeyConfig.getLoginRole()))
|
if (accessCode.isSso() && !gp.hasRole(skeletonKeyConfig.getLoginRole())) {
|
||||||
{
|
|
||||||
// we did not authenticate user on an access code request because a session was already established
|
// 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
|
// 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
|
// to always ask for credentials from a simple oath request
|
||||||
|
@ -838,9 +696,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
mapWriter.writeValue(response.getOutputStream(), res);
|
mapWriter.writeValue(response.getOutputStream(), res);
|
||||||
response.getOutputStream().flush();
|
response.getOutputStream().flush();
|
||||||
return;
|
return;
|
||||||
}
|
} else if (!gp.hasRole(skeletonKeyConfig.getClientRole()) && !gp.hasRole(skeletonKeyConfig.getLoginRole())) {
|
||||||
else if (!gp.hasRole(skeletonKeyConfig.getClientRole()) && !gp.hasRole(skeletonKeyConfig.getLoginRole()))
|
|
||||||
{
|
|
||||||
log.debug("does not have login or client role permission for access token request");
|
log.debug("does not have login or client role permission for access token request");
|
||||||
Map<String, String> res = new HashMap<String, String>();
|
Map<String, String> res = new HashMap<String, String>();
|
||||||
res.put("error", "invalid_grant");
|
res.put("error", "invalid_grant");
|
||||||
|
@ -855,8 +711,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
String wildcard = skeletonKeyConfig.getWildcardRole() == null ? "*" : skeletonKeyConfig.getWildcardRole();
|
String wildcard = skeletonKeyConfig.getWildcardRole() == null ? "*" : skeletonKeyConfig.getWildcardRole();
|
||||||
Set<String> codeRoles = accessCode.getToken().getRealmAccess().getRoles();
|
Set<String> codeRoles = accessCode.getToken().getRealmAccess().getRoles();
|
||||||
if (codeRoles != null &&
|
if (codeRoles != null &&
|
||||||
(codeRoles.contains(skeletonKeyConfig.getClientRole()) || codeRoles.contains(skeletonKeyConfig.getLoginRole())))
|
(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
|
// 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.
|
// permissions if they are logging in.
|
||||||
Set<String> newRoles = new HashSet<String>();
|
Set<String> newRoles = new HashSet<String>();
|
||||||
|
@ -871,19 +726,15 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
// Also, if the client has the "wildcard" role, then we don't need to filter out roles
|
// Also, if the client has the "wildcard" role, then we don't need to filter out roles
|
||||||
if (codeRoles != null
|
if (codeRoles != null
|
||||||
&& !gp.hasRole(wildcard)
|
&& !gp.hasRole(wildcard)
|
||||||
&& !gp.hasRole(skeletonKeyConfig.getLoginRole()))
|
&& !gp.hasRole(skeletonKeyConfig.getLoginRole())) {
|
||||||
{
|
|
||||||
Set<String> clientAllowed = new HashSet<String>();
|
Set<String> clientAllowed = new HashSet<String>();
|
||||||
for (String role : gp.getRoles())
|
for (String role : gp.getRoles()) {
|
||||||
{
|
|
||||||
clientAllowed.add(role);
|
clientAllowed.add(role);
|
||||||
}
|
}
|
||||||
Set<String> newRoles = new HashSet<String>();
|
Set<String> newRoles = new HashSet<String>();
|
||||||
newRoles.addAll(codeRoles);
|
newRoles.addAll(codeRoles);
|
||||||
for (String role : newRoles)
|
for (String role : newRoles) {
|
||||||
{
|
if (!clientAllowed.contains(role)) {
|
||||||
if (!clientAllowed.contains(role))
|
|
||||||
{
|
|
||||||
codeRoles.remove(role);
|
codeRoles.remove(role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -895,30 +746,24 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
response.getOutputStream().flush();
|
response.getOutputStream().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token)
|
protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token) {
|
||||||
{
|
|
||||||
String encodedToken = buildTokenString(privateKey, token);
|
String encodedToken = buildTokenString(privateKey, token);
|
||||||
|
|
||||||
AccessTokenResponse res = new AccessTokenResponse();
|
AccessTokenResponse res = new AccessTokenResponse();
|
||||||
res.setToken(encodedToken);
|
res.setToken(encodedToken);
|
||||||
res.setTokenType("bearer");
|
res.setTokenType("bearer");
|
||||||
if (token.getExpiration() != 0)
|
if (token.getExpiration() != 0) {
|
||||||
{
|
|
||||||
long time = token.getExpiration() - (System.currentTimeMillis() / 1000);
|
long time = token.getExpiration() - (System.currentTimeMillis() / 1000);
|
||||||
res.setExpiresIn(time);
|
res.setExpiresIn(time);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String buildTokenString(PrivateKey privateKey, SkeletonKeyToken token)
|
protected String buildTokenString(PrivateKey privateKey, SkeletonKeyToken token) {
|
||||||
{
|
|
||||||
byte[] tokenBytes = null;
|
byte[] tokenBytes = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
tokenBytes = JsonSerialization.toByteArray(token, false);
|
tokenBytes = JsonSerialization.toByteArray(token, false);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return new JWSBuilder()
|
return new JWSBuilder()
|
||||||
|
@ -927,8 +772,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void handleOAuth(Request request, Response response) throws IOException
|
protected void handleOAuth(Request request, Response response) throws IOException {
|
||||||
{
|
|
||||||
log.debug("<--- Begin oauthAuthenticate");
|
log.debug("<--- Begin oauthAuthenticate");
|
||||||
String redirect_uri = request.getParameter("redirect_uri");
|
String redirect_uri = request.getParameter("redirect_uri");
|
||||||
String client_id = request.getParameter("client_id");
|
String client_id = request.getParameter("client_id");
|
||||||
|
@ -936,8 +780,7 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
String username = request.getParameter(Constants.FORM_USERNAME);
|
String username = request.getParameter(Constants.FORM_USERNAME);
|
||||||
String password = request.getParameter(Constants.FORM_PASSWORD);
|
String password = request.getParameter(Constants.FORM_PASSWORD);
|
||||||
Principal principal = context.getRealm().authenticate(username, password);
|
Principal principal = context.getRealm().authenticate(username, password);
|
||||||
if (principal == null)
|
if (principal == null) {
|
||||||
{
|
|
||||||
UriBuilder builder = UriBuilder.fromUri(redirect_uri).queryParam("error", "unauthorized_client");
|
UriBuilder builder = UriBuilder.fromUri(redirect_uri).queryParam("error", "unauthorized_client");
|
||||||
if (state != null) builder.queryParam("state", state);
|
if (state != null) builder.queryParam("state", state);
|
||||||
response.sendRedirect(builder.toTemplate());
|
response.sendRedirect(builder.toTemplate());
|
||||||
|
@ -951,10 +794,8 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void tokenGrant(Request request, Response response) throws IOException
|
protected void tokenGrant(Request request, Response response) throws IOException {
|
||||||
{
|
if (!request.isSecure()) {
|
||||||
if (!request.isSecure())
|
|
||||||
{
|
|
||||||
response.sendError(400);
|
response.sendError(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -968,39 +809,33 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
response.getOutputStream().flush();
|
response.getOutputStream().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GenericPrincipal basicAuth(Request request, Response response) throws IOException
|
protected GenericPrincipal basicAuth(Request request, Response response) throws IOException {
|
||||||
{
|
|
||||||
String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
|
String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||||
if (authHeader == null)
|
if (authHeader == null) {
|
||||||
{
|
|
||||||
basicAuthError(response);
|
basicAuthError(response);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] creds = BasicAuthHelper.parseHeader(authHeader);
|
String[] creds = BasicAuthHelper.parseHeader(authHeader);
|
||||||
if (creds == null)
|
if (creds == null) {
|
||||||
{
|
|
||||||
basicAuthError(response);
|
basicAuthError(response);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String username = creds[0];
|
String username = creds[0];
|
||||||
String password = creds[1];
|
String password = creds[1];
|
||||||
GenericPrincipal gp = (GenericPrincipal) context.getRealm().authenticate(username, password);
|
GenericPrincipal gp = (GenericPrincipal) context.getRealm().authenticate(username, password);
|
||||||
if (gp == null)
|
if (gp == null) {
|
||||||
{
|
|
||||||
basicAuthError(response);
|
basicAuthError(response);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return gp;
|
return gp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void basicAuthError(Response response) throws IOException
|
protected void basicAuthError(Response response) throws IOException {
|
||||||
{
|
|
||||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + context.getLoginConfig().getRealmName() + "\"");
|
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + context.getLoginConfig().getRealmName() + "\"");
|
||||||
response.sendError(401);
|
response.sendError(401);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void redirectAccessCode(boolean sso, Response response, String redirect_uri, String client_id, String state, GenericPrincipal gp) throws IOException
|
protected void redirectAccessCode(boolean sso, Response response, String redirect_uri, String client_id, String state, GenericPrincipal gp) throws IOException {
|
||||||
{
|
|
||||||
SkeletonKeyToken token = buildToken(gp);
|
SkeletonKeyToken token = buildToken(gp);
|
||||||
AccessCode code = new AccessCode();
|
AccessCode code = new AccessCode();
|
||||||
code.setToken(token);
|
code.setToken(token);
|
||||||
|
@ -1012,12 +847,9 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
accessCodeMap.put(code.getId(), code);
|
accessCodeMap.put(code.getId(), code);
|
||||||
log.debug("--- sign access code");
|
log.debug("--- sign access code");
|
||||||
String accessCode = null;
|
String accessCode = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
accessCode = new JWSBuilder().content(code.getId().getBytes("UTF-8")).rsa256(realmPrivateKey);
|
accessCode = new JWSBuilder().content(code.getId().getBytes("UTF-8")).rsa256(realmPrivateKey);
|
||||||
}
|
} catch (UnsupportedEncodingException e) {
|
||||||
catch (UnsupportedEncodingException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
log.debug("--- build redirect");
|
log.debug("--- build redirect");
|
||||||
|
@ -1027,20 +859,17 @@ public class OAuthAuthenticationServerValve extends FormAuthenticator implements
|
||||||
log.debug("<--- end oauthAuthenticate");
|
log.debug("<--- end oauthAuthenticate");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SkeletonKeyToken buildToken(GenericPrincipal gp)
|
protected SkeletonKeyToken buildToken(GenericPrincipal gp) {
|
||||||
{
|
|
||||||
SkeletonKeyToken token = new SkeletonKeyToken();
|
SkeletonKeyToken token = new SkeletonKeyToken();
|
||||||
token.id(generateId());
|
token.id(generateId());
|
||||||
token.principal(gp.getName());
|
token.principal(gp.getName());
|
||||||
token.audience(skeletonKeyConfig.getRealm());
|
token.audience(skeletonKeyConfig.getRealm());
|
||||||
int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 3600 : skeletonKeyConfig.getAccessCodeLifetime();
|
int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 3600 : skeletonKeyConfig.getAccessCodeLifetime();
|
||||||
if (skeletonKeyConfig.getTokenLifetime() > 0)
|
if (skeletonKeyConfig.getTokenLifetime() > 0) {
|
||||||
{
|
|
||||||
token.expiration((System.currentTimeMillis() / 1000) + expiration);
|
token.expiration((System.currentTimeMillis() / 1000) + expiration);
|
||||||
}
|
}
|
||||||
SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access();
|
SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access();
|
||||||
for (String role : gp.getRoles())
|
for (String role : gp.getRoles()) {
|
||||||
{
|
|
||||||
realmAccess.addRole(role);
|
realmAccess.addRole(role);
|
||||||
}
|
}
|
||||||
token.setRealmAccess(realmAccess);
|
token.setRealmAccess(realmAccess);
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||||
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
||||||
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.RealmConfiguration;
|
import org.keycloak.RealmConfiguration;
|
||||||
import org.keycloak.ResourceMetadata;
|
import org.keycloak.ResourceMetadata;
|
||||||
import org.keycloak.SkeletonKeyPrincipal;
|
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.ManagedResourceConfig;
|
||||||
import org.keycloak.adapters.as7.config.ManagedResourceConfigLoader;
|
import org.keycloak.adapters.as7.config.ManagedResourceConfigLoader;
|
||||||
import org.keycloak.representations.SkeletonKeyToken;
|
import org.keycloak.representations.SkeletonKeyToken;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
|
||||||
|
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
@ -42,8 +42,7 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class OAuthManagedResourceValve extends FormAuthenticator implements LifecycleListener
|
public class OAuthManagedResourceValve extends FormAuthenticator implements LifecycleListener {
|
||||||
{
|
|
||||||
protected RealmConfiguration realmConfiguration;
|
protected RealmConfiguration realmConfiguration;
|
||||||
private static final Logger log = Logger.getLogger(OAuthManagedResourceValve.class);
|
private static final Logger log = Logger.getLogger(OAuthManagedResourceValve.class);
|
||||||
protected UserSessionManagement userSessionManagement = new UserSessionManagement();
|
protected UserSessionManagement userSessionManagement = new UserSessionManagement();
|
||||||
|
@ -52,179 +51,123 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws LifecycleException
|
public void start() throws LifecycleException {
|
||||||
{
|
|
||||||
super.start();
|
super.start();
|
||||||
StandardContext standardContext = (StandardContext) context;
|
StandardContext standardContext = (StandardContext) context;
|
||||||
standardContext.addLifecycleListener(this);
|
standardContext.addLifecycleListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lifecycleEvent(LifecycleEvent event)
|
public void lifecycleEvent(LifecycleEvent event) {
|
||||||
{
|
|
||||||
if (event.getType() == Lifecycle.AFTER_START_EVENT) init();
|
if (event.getType() == Lifecycle.AFTER_START_EVENT) init();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void init()
|
protected void init() {
|
||||||
{
|
|
||||||
ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context);
|
ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context);
|
||||||
|
managedResourceConfigLoader.init(true);
|
||||||
resourceMetadata = managedResourceConfigLoader.getResourceMetadata();
|
resourceMetadata = managedResourceConfigLoader.getResourceMetadata();
|
||||||
remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig();
|
remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig();
|
||||||
String client_id = remoteSkeletonKeyConfig.getClientId();
|
String client_id = remoteSkeletonKeyConfig.getClientId();
|
||||||
if (client_id == null)
|
if (client_id == null) {
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Must set client-id to use with auth server");
|
throw new IllegalArgumentException("Must set client-id to use with auth server");
|
||||||
}
|
}
|
||||||
realmConfiguration = new RealmConfiguration();
|
realmConfiguration = new RealmConfiguration();
|
||||||
String authUrl = remoteSkeletonKeyConfig.getAuthUrl();
|
String authUrl = remoteSkeletonKeyConfig.getAuthUrl();
|
||||||
if (authUrl == null)
|
if (authUrl == null) {
|
||||||
{
|
|
||||||
throw new RuntimeException("You must specify auth-url");
|
throw new RuntimeException("You must specify auth-url");
|
||||||
}
|
}
|
||||||
String tokenUrl = remoteSkeletonKeyConfig.getCodeUrl();
|
String tokenUrl = remoteSkeletonKeyConfig.getCodeUrl();
|
||||||
if (tokenUrl == null)
|
if (tokenUrl == null) {
|
||||||
{
|
|
||||||
throw new RuntimeException("You mut specify code-url");
|
throw new RuntimeException("You mut specify code-url");
|
||||||
}
|
}
|
||||||
realmConfiguration.setMetadata(resourceMetadata);
|
realmConfiguration.setMetadata(resourceMetadata);
|
||||||
realmConfiguration.setClientId(client_id);
|
realmConfiguration.setClientId(client_id);
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getClientCredentials().entrySet())
|
for (Map.Entry<String, String> entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getClientCredentials().entrySet()) {
|
||||||
{
|
|
||||||
realmConfiguration.getCredentials().param(entry.getKey(), entry.getValue());
|
realmConfiguration.getCredentials().param(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
int size = 10;
|
|
||||||
if (managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getConnectionPoolSize() > 0)
|
ResteasyClient client = managedResourceConfigLoader.getClient();
|
||||||
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.setClient(client);
|
||||||
realmConfiguration.setAuthUrl(UriBuilder.fromUri(authUrl).queryParam("client_id", client_id));
|
realmConfiguration.setAuthUrl(UriBuilder.fromUri(authUrl).queryParam("client_id", client_id));
|
||||||
realmConfiguration.setCodeUrl(client.target(tokenUrl));
|
realmConfiguration.setCodeUrl(client.target(tokenUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(Request request, Response response) throws IOException, ServletException
|
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
String requestURI = request.getDecodedRequestURI();
|
String requestURI = request.getDecodedRequestURI();
|
||||||
if (requestURI.endsWith("j_oauth_remote_logout"))
|
if (requestURI.endsWith("j_oauth_remote_logout")) {
|
||||||
{
|
|
||||||
remoteLogout(request, response);
|
remoteLogout(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super.invoke(request, response);
|
super.invoke(request, response);
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession
|
ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException
|
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
if (bearer(false, request, response)) return true;
|
if (bearer(false, request, response)) return true;
|
||||||
else if (checkLoggedIn(request, response))
|
else if (checkLoggedIn(request, response)) {
|
||||||
{
|
if (request.getSessionInternal().getNote(Constants.FORM_REQUEST_NOTE) != null) {
|
||||||
if (request.getSessionInternal().getNote(Constants.FORM_REQUEST_NOTE) != null)
|
if (restoreRequest(request, request.getSessionInternal())) {
|
||||||
{
|
|
||||||
if (restoreRequest(request, request.getSessionInternal()))
|
|
||||||
{
|
|
||||||
log.debug("restoreRequest");
|
log.debug("restoreRequest");
|
||||||
return (true);
|
return (true);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
log.debug("Restore of original request failed");
|
log.debug("Restore of original request failed");
|
||||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
|
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// initiate or continue oauth2 protocol
|
// initiate or continue oauth2 protocol
|
||||||
oauth(request, response);
|
oauth(request, response);
|
||||||
}
|
} catch (LoginException e) {
|
||||||
catch (LoginException e)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void remoteLogout(Request request, HttpServletResponse response) throws IOException
|
protected void remoteLogout(Request request, HttpServletResponse response) throws IOException {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
log.debug("->> remoteLogout: ");
|
log.debug("->> remoteLogout: ");
|
||||||
if (!bearer(true, request, response))
|
if (!bearer(true, request, response)) {
|
||||||
{
|
|
||||||
log.debug("remoteLogout: bearer auth failed");
|
log.debug("remoteLogout: bearer auth failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GenericPrincipal gp = (GenericPrincipal) request.getPrincipal();
|
GenericPrincipal gp = (GenericPrincipal) request.getPrincipal();
|
||||||
if (!gp.hasRole(remoteSkeletonKeyConfig.getAdminRole()))
|
if (!gp.hasRole(remoteSkeletonKeyConfig.getAdminRole())) {
|
||||||
{
|
|
||||||
log.debug("remoteLogout: role failure");
|
log.debug("remoteLogout: role failure");
|
||||||
response.sendError(403);
|
response.sendError(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String user = request.getParameter("user");
|
String user = request.getParameter("user");
|
||||||
if (user != null)
|
if (user != null) {
|
||||||
{
|
|
||||||
userSessionManagement.logout(user);
|
userSessionManagement.logout(user);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
userSessionManagement.logoutAll();
|
userSessionManagement.logoutAll();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
log.error("failed to logout", e);
|
log.error("failed to logout", e);
|
||||||
}
|
}
|
||||||
response.setStatus(204);
|
response.setStatus(204);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean bearer(boolean challenge, Request request, HttpServletResponse response) throws LoginException, IOException
|
protected boolean bearer(boolean challenge, Request request, HttpServletResponse response) throws LoginException, IOException {
|
||||||
{
|
|
||||||
CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(realmConfiguration.getMetadata(), !remoteSkeletonKeyConfig.isCancelPropagation(), challenge);
|
CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(realmConfiguration.getMetadata(), !remoteSkeletonKeyConfig.isCancelPropagation(), challenge);
|
||||||
if (bearer.login(request, response))
|
if (bearer.login(request, response)) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean checkLoggedIn(Request request, HttpServletResponse response)
|
protected boolean checkLoggedIn(Request request, HttpServletResponse response) {
|
||||||
{
|
|
||||||
if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null)
|
if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null)
|
||||||
return false;
|
return false;
|
||||||
log.debug("remote logged in already");
|
log.debug("remote logged in already");
|
||||||
|
@ -232,11 +175,9 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
|
||||||
request.setUserPrincipal(principal);
|
request.setUserPrincipal(principal);
|
||||||
request.setAuthType("OAUTH");
|
request.setAuthType("OAUTH");
|
||||||
Session session = request.getSessionInternal();
|
Session session = request.getSessionInternal();
|
||||||
if (session != null && !remoteSkeletonKeyConfig.isCancelPropagation())
|
if (session != null && !remoteSkeletonKeyConfig.isCancelPropagation()) {
|
||||||
{
|
|
||||||
SkeletonKeySession skSession = (SkeletonKeySession) session.getNote(SkeletonKeySession.class.getName());
|
SkeletonKeySession skSession = (SkeletonKeySession) session.getNote(SkeletonKeySession.class.getName());
|
||||||
if (skSession != null)
|
if (skSession != null) {
|
||||||
{
|
|
||||||
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
||||||
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
||||||
|
|
||||||
|
@ -248,38 +189,28 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
|
||||||
/**
|
/**
|
||||||
* This method always set the HTTP response, so do not continue after invoking
|
* This method always set the HTTP response, so do not continue after invoking
|
||||||
*/
|
*/
|
||||||
protected void oauth(Request request, HttpServletResponse response) throws IOException
|
protected void oauth(Request request, HttpServletResponse response) throws IOException {
|
||||||
{
|
|
||||||
ServletOAuthLogin oauth = new ServletOAuthLogin(realmConfiguration, request, response, request.getConnector().getRedirectPort());
|
ServletOAuthLogin oauth = new ServletOAuthLogin(realmConfiguration, request, response, request.getConnector().getRedirectPort());
|
||||||
String code = oauth.getCode();
|
String code = oauth.getCode();
|
||||||
if (code == null)
|
if (code == null) {
|
||||||
{
|
|
||||||
String error = oauth.getError();
|
String error = oauth.getError();
|
||||||
if (error != null)
|
if (error != null) {
|
||||||
{
|
|
||||||
response.sendError(400, "OAuth " + error);
|
response.sendError(400, "OAuth " + error);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
saveRequest(request, request.getSessionInternal(true));
|
saveRequest(request, request.getSessionInternal(true));
|
||||||
oauth.loginRedirect();
|
oauth.loginRedirect();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!oauth.resolveCode(code)) return;
|
if (!oauth.resolveCode(code)) return;
|
||||||
|
|
||||||
SkeletonKeyToken token = oauth.getToken();
|
SkeletonKeyToken token = oauth.getToken();
|
||||||
Set<String> roles = null;
|
Set<String> roles = null;
|
||||||
if (resourceMetadata.getResourceName() != null)
|
if (resourceMetadata.getResourceName() != null) {
|
||||||
{
|
|
||||||
SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName());
|
SkeletonKeyToken.Access access = token.getResourceAccess(resourceMetadata.getResourceName());
|
||||||
if (access != null) roles = access.getRoles();
|
if (access != null) roles = access.getRoles();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
SkeletonKeyToken.Access access = token.getRealmAccess();
|
SkeletonKeyToken.Access access = token.getRealmAccess();
|
||||||
if (access != null) roles = access.getRoles();
|
if (access != null) roles = access.getRoles();
|
||||||
}
|
}
|
||||||
|
@ -288,8 +219,7 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
|
||||||
Session session = request.getSessionInternal(true);
|
Session session = request.getSessionInternal(true);
|
||||||
session.setPrincipal(principal);
|
session.setPrincipal(principal);
|
||||||
session.setAuthType("OAUTH");
|
session.setAuthType("OAUTH");
|
||||||
if (!remoteSkeletonKeyConfig.isCancelPropagation())
|
if (!remoteSkeletonKeyConfig.isCancelPropagation()) {
|
||||||
{
|
|
||||||
SkeletonKeySession skSession = new SkeletonKeySession(oauth.getTokenString(), realmConfiguration.getMetadata());
|
SkeletonKeySession skSession = new SkeletonKeySession(oauth.getTokenString(), realmConfiguration.getMetadata());
|
||||||
session.setNote(SkeletonKeySession.class.getName(), skSession);
|
session.setNote(SkeletonKeySession.class.getName(), skSession);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package org.keycloak.adapters.as7;
|
package org.keycloak.adapters.as7;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.resteasy.util.BasicAuthHelper;
|
||||||
import org.keycloak.RSATokenVerifier;
|
import org.keycloak.RSATokenVerifier;
|
||||||
import org.keycloak.RealmConfiguration;
|
import org.keycloak.RealmConfiguration;
|
||||||
import org.keycloak.VerificationException;
|
import org.keycloak.VerificationException;
|
||||||
import org.keycloak.representations.AccessTokenResponse;
|
import org.keycloak.representations.AccessTokenResponse;
|
||||||
import org.keycloak.representations.SkeletonKeyToken;
|
import org.keycloak.representations.SkeletonKeyToken;
|
||||||
import org.jboss.resteasy.util.BasicAuthHelper;
|
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -21,12 +21,10 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class ServletOAuthLogin
|
public class ServletOAuthLogin {
|
||||||
{
|
|
||||||
private static final Logger log = Logger.getLogger(ServletOAuthLogin.class);
|
private static final Logger log = Logger.getLogger(ServletOAuthLogin.class);
|
||||||
protected HttpServletRequest request;
|
protected HttpServletRequest request;
|
||||||
protected HttpServletResponse response;
|
protected HttpServletResponse response;
|
||||||
|
@ -36,97 +34,76 @@ public class ServletOAuthLogin
|
||||||
protected String tokenString;
|
protected String tokenString;
|
||||||
protected SkeletonKeyToken token;
|
protected SkeletonKeyToken token;
|
||||||
|
|
||||||
public ServletOAuthLogin(RealmConfiguration realmInfo, HttpServletRequest request, HttpServletResponse response, int redirectPort)
|
public ServletOAuthLogin(RealmConfiguration realmInfo, HttpServletRequest request, HttpServletResponse response, int redirectPort) {
|
||||||
{
|
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.realmInfo = realmInfo;
|
this.realmInfo = realmInfo;
|
||||||
this.redirectPort = redirectPort;
|
this.redirectPort = redirectPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTokenString()
|
public String getTokenString() {
|
||||||
{
|
|
||||||
return tokenString;
|
return tokenString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkeletonKeyToken getToken()
|
public SkeletonKeyToken getToken() {
|
||||||
{
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RealmConfiguration getRealmInfo()
|
public RealmConfiguration getRealmInfo() {
|
||||||
{
|
|
||||||
return realmInfo;
|
return realmInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getDefaultCookiePath()
|
protected String getDefaultCookiePath() {
|
||||||
{
|
|
||||||
String path = request.getContextPath();
|
String path = request.getContextPath();
|
||||||
if ("".equals(path) || path == null) path = "/";
|
if ("".equals(path) || path == null) path = "/";
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getRequestUrl()
|
protected String getRequestUrl() {
|
||||||
{
|
|
||||||
return request.getRequestURL().toString();
|
return request.getRequestURL().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isRequestSecure()
|
protected boolean isRequestSecure() {
|
||||||
{
|
|
||||||
return request.isSecure();
|
return request.isSecure();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendError(int code)
|
protected void sendError(int code) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
response.sendError(code);
|
response.sendError(code);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendRedirect(String url)
|
protected void sendRedirect(String url) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
response.sendRedirect(url);
|
response.sendRedirect(url);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Cookie getCookie(String cookieName)
|
protected Cookie getCookie(String cookieName) {
|
||||||
{
|
|
||||||
if (request.getCookies() == null) return null;
|
if (request.getCookies() == null) return null;
|
||||||
for (Cookie cookie : request.getCookies())
|
for (Cookie cookie : request.getCookies()) {
|
||||||
{
|
if (cookie.getName().equals(cookieName)) {
|
||||||
if (cookie.getName().equals(cookieName))
|
|
||||||
{
|
|
||||||
return cookie;
|
return cookie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getCookieValue(String cookieName)
|
protected String getCookieValue(String cookieName) {
|
||||||
{
|
|
||||||
Cookie cookie = getCookie(cookieName);
|
Cookie cookie = getCookie(cookieName);
|
||||||
if (cookie == null) return null;
|
if (cookie == null) return null;
|
||||||
return cookie.getValue();
|
return cookie.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getQueryParamValue(String paramName)
|
protected String getQueryParamValue(String paramName) {
|
||||||
{
|
|
||||||
String query = request.getQueryString();
|
String query = request.getQueryString();
|
||||||
if (query == null) return null;
|
if (query == null) return null;
|
||||||
String[] params = query.split("&");
|
String[] params = query.split("&");
|
||||||
for (String param : params)
|
for (String param : params) {
|
||||||
{
|
|
||||||
int eq = param.indexOf('=');
|
int eq = param.indexOf('=');
|
||||||
if (eq == -1) continue;
|
if (eq == -1) continue;
|
||||||
String name = param.substring(0, eq);
|
String name = param.substring(0, eq);
|
||||||
|
@ -136,18 +113,15 @@ public class ServletOAuthLogin
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getError()
|
public String getError() {
|
||||||
{
|
|
||||||
return getQueryParamValue("error");
|
return getQueryParamValue("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCode()
|
public String getCode() {
|
||||||
{
|
|
||||||
return getQueryParamValue("code");
|
return getQueryParamValue("code");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setCookie(String name, String value, String domain, String path, boolean secure)
|
protected void setCookie(String name, String value, String domain, String path, boolean secure) {
|
||||||
{
|
|
||||||
Cookie cookie = new Cookie(name, value);
|
Cookie cookie = new Cookie(name, value);
|
||||||
if (domain != null) cookie.setDomain(domain);
|
if (domain != null) cookie.setDomain(domain);
|
||||||
if (path != null) cookie.setPath(path);
|
if (path != null) cookie.setPath(path);
|
||||||
|
@ -155,14 +129,11 @@ public class ServletOAuthLogin
|
||||||
response.addCookie(cookie);
|
response.addCookie(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getRedirectUri(String state)
|
protected String getRedirectUri(String state) {
|
||||||
{
|
|
||||||
String url = getRequestUrl();
|
String url = getRequestUrl();
|
||||||
if (!isRequestSecure() && realmInfo.isSslRequired())
|
if (!isRequestSecure() && realmInfo.isSslRequired()) {
|
||||||
{
|
|
||||||
int port = redirectPort;
|
int port = redirectPort;
|
||||||
if (port < 0)
|
if (port < 0) {
|
||||||
{
|
|
||||||
// disabled?
|
// disabled?
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -180,17 +151,14 @@ public class ServletOAuthLogin
|
||||||
|
|
||||||
protected static final AtomicLong counter = new AtomicLong();
|
protected static final AtomicLong counter = new AtomicLong();
|
||||||
|
|
||||||
protected String getStateCode()
|
protected String getStateCode() {
|
||||||
{
|
|
||||||
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
|
return counter.getAndIncrement() + "/" + UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loginRedirect()
|
public void loginRedirect() {
|
||||||
{
|
|
||||||
String state = getStateCode();
|
String state = getStateCode();
|
||||||
String redirect = getRedirectUri(state);
|
String redirect = getRedirectUri(state);
|
||||||
if (redirect == null)
|
if (redirect == null) {
|
||||||
{
|
|
||||||
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -198,12 +166,10 @@ public class ServletOAuthLogin
|
||||||
sendRedirect(redirect);
|
sendRedirect(redirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkStateCookie()
|
public boolean checkStateCookie() {
|
||||||
{
|
|
||||||
Cookie stateCookie = getCookie(realmInfo.getStateCookieName());
|
Cookie stateCookie = getCookie(realmInfo.getStateCookieName());
|
||||||
|
|
||||||
if (stateCookie == null)
|
if (stateCookie == null) {
|
||||||
{
|
|
||||||
sendError(400);
|
sendError(400);
|
||||||
log.warn("No state cookie");
|
log.warn("No state cookie");
|
||||||
return false;
|
return false;
|
||||||
|
@ -217,14 +183,12 @@ public class ServletOAuthLogin
|
||||||
String stateCookieValue = getCookieValue(realmInfo.getStateCookieName());
|
String stateCookieValue = getCookieValue(realmInfo.getStateCookieName());
|
||||||
// its ok to call request.getParameter() because this should be a redirect
|
// its ok to call request.getParameter() because this should be a redirect
|
||||||
String state = request.getParameter("state");
|
String state = request.getParameter("state");
|
||||||
if (state == null)
|
if (state == null) {
|
||||||
{
|
|
||||||
sendError(400);
|
sendError(400);
|
||||||
log.warn("state parameter was null");
|
log.warn("state parameter was null");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!state.equals(stateCookieValue))
|
if (!state.equals(stateCookieValue)) {
|
||||||
{
|
|
||||||
sendError(400);
|
sendError(400);
|
||||||
log.warn("state parameter invalid");
|
log.warn("state parameter invalid");
|
||||||
log.warn("cookie: " + stateCookieValue);
|
log.warn("cookie: " + stateCookieValue);
|
||||||
|
@ -237,21 +201,19 @@ public class ServletOAuthLogin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start or continue the oauth login process.
|
* Start or continue the oauth login process.
|
||||||
*
|
* <p/>
|
||||||
* if code query parameter is not present, then browser is redirected to authUrl. The redirect URL will be
|
* if code query parameter is not present, then browser is redirected to authUrl. The redirect URL will be
|
||||||
* the URL of the current request.
|
* the URL of the current request.
|
||||||
*
|
* <p/>
|
||||||
* If code query parameter is present, then an access token is obtained by invoking a secure request to the codeUrl.
|
* 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
|
* 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.
|
* protocol specific query parameters are removed.
|
||||||
*
|
*
|
||||||
* @return true if an access token was obtained
|
* @return true if an access token was obtained
|
||||||
*/
|
*/
|
||||||
public boolean resolveCode(String code)
|
public boolean resolveCode(String code) {
|
||||||
{
|
|
||||||
// abort if not HTTPS
|
// abort if not HTTPS
|
||||||
if (realmInfo.isSslRequired() && !isRequestSecure())
|
if (realmInfo.isSslRequired() && !isRequestSecure()) {
|
||||||
{
|
|
||||||
log.error("SSL is required");
|
log.error("SSL is required");
|
||||||
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
||||||
return false;
|
return false;
|
||||||
|
@ -270,10 +232,8 @@ public class ServletOAuthLogin
|
||||||
|
|
||||||
Response res = realmInfo.getCodeUrl().request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(form));
|
Response res = realmInfo.getCodeUrl().request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(form));
|
||||||
AccessTokenResponse tokenResponse;
|
AccessTokenResponse tokenResponse;
|
||||||
try
|
try {
|
||||||
{
|
if (res.getStatus() != 200) {
|
||||||
if (res.getStatus() != 200)
|
|
||||||
{
|
|
||||||
log.error("failed to turn code into token");
|
log.error("failed to turn code into token");
|
||||||
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
||||||
return false;
|
return false;
|
||||||
|
@ -281,20 +241,15 @@ public class ServletOAuthLogin
|
||||||
log.debug("media type: " + res.getMediaType());
|
log.debug("media type: " + res.getMediaType());
|
||||||
log.debug("Content-Type header: " + res.getHeaderString("Content-Type"));
|
log.debug("Content-Type header: " + res.getHeaderString("Content-Type"));
|
||||||
tokenResponse = res.readEntity(AccessTokenResponse.class);
|
tokenResponse = res.readEntity(AccessTokenResponse.class);
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
res.close();
|
res.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenString = tokenResponse.getToken();
|
tokenString = tokenResponse.getToken();
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata());
|
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata());
|
||||||
log.debug("Verification succeeded!");
|
log.debug("Verification succeeded!");
|
||||||
}
|
} catch (VerificationException e) {
|
||||||
catch (VerificationException e)
|
|
||||||
{
|
|
||||||
log.error("failed verification of token");
|
log.error("failed verification of token");
|
||||||
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
||||||
return false;
|
return false;
|
||||||
|
@ -307,8 +262,7 @@ public class ServletOAuthLogin
|
||||||
/**
|
/**
|
||||||
* strip out unwanted query parameters and redirect so bookmarks don't retain oauth protocol bits
|
* strip out unwanted query parameters and redirect so bookmarks don't retain oauth protocol bits
|
||||||
*/
|
*/
|
||||||
protected String stripOauthParametersFromRedirect()
|
protected String stripOauthParametersFromRedirect() {
|
||||||
{
|
|
||||||
StringBuffer buf = request.getRequestURL().append("?").append(request.getQueryString());
|
StringBuffer buf = request.getRequestURL().append("?").append(request.getQueryString());
|
||||||
UriBuilder builder = UriBuilder.fromUri(buf.toString())
|
UriBuilder builder = UriBuilder.fromUri(buf.toString())
|
||||||
.replaceQueryParam("code", null)
|
.replaceQueryParam("code", null)
|
||||||
|
|
|
@ -18,62 +18,50 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class UserSessionManagement implements SessionListener
|
public class UserSessionManagement implements SessionListener {
|
||||||
{
|
|
||||||
private static final Logger log = Logger.getLogger(UserSessionManagement.class);
|
private static final Logger log = Logger.getLogger(UserSessionManagement.class);
|
||||||
protected ConcurrentHashMap<String, Map<String, Session>> userSessionMap = new ConcurrentHashMap<String, Map<String, Session>>();
|
protected ConcurrentHashMap<String, Map<String, Session>> userSessionMap = new ConcurrentHashMap<String, Map<String, Session>>();
|
||||||
|
|
||||||
protected void login(Session session, String username)
|
protected void login(Session session, String username) {
|
||||||
{
|
|
||||||
Map<String, Session> map = userSessionMap.get(username);
|
Map<String, Session> map = userSessionMap.get(username);
|
||||||
if (map == null)
|
if (map == null) {
|
||||||
{
|
|
||||||
final Map<String, Session> value = new HashMap<String, Session>();
|
final Map<String, Session> value = new HashMap<String, Session>();
|
||||||
map = userSessionMap.putIfAbsent(username, value);
|
map = userSessionMap.putIfAbsent(username, value);
|
||||||
if (map == null)
|
if (map == null) {
|
||||||
{
|
|
||||||
map = value;
|
map = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
synchronized (map)
|
synchronized (map) {
|
||||||
{
|
|
||||||
map.put(session.getId(), session);
|
map.put(session.getId(), session);
|
||||||
}
|
}
|
||||||
session.addSessionListener(this);
|
session.addSessionListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logoutAll()
|
public void logoutAll() {
|
||||||
{
|
|
||||||
List<String> users = new ArrayList<String>();
|
List<String> users = new ArrayList<String>();
|
||||||
users.addAll(userSessionMap.keySet());
|
users.addAll(userSessionMap.keySet());
|
||||||
for (String user : users) logout(user);
|
for (String user : users) logout(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logoutAllBut(String but)
|
public void logoutAllBut(String but) {
|
||||||
{
|
|
||||||
List<String> users = new ArrayList<String>();
|
List<String> users = new ArrayList<String>();
|
||||||
users.addAll(userSessionMap.keySet());
|
users.addAll(userSessionMap.keySet());
|
||||||
for (String user : users)
|
for (String user : users) {
|
||||||
{
|
|
||||||
if (!but.equals(user)) logout(user);
|
if (!but.equals(user)) logout(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void logout(String user)
|
public void logout(String user) {
|
||||||
{
|
|
||||||
log.debug("logoutUser: " + user);
|
log.debug("logoutUser: " + user);
|
||||||
Map<String, Session> map = userSessionMap.remove(user);
|
Map<String, Session> map = userSessionMap.remove(user);
|
||||||
if (map == null)
|
if (map == null) {
|
||||||
{
|
|
||||||
log.debug("no session for user: " + user);
|
log.debug("no session for user: " + user);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.debug("found session for user");
|
log.debug("found session for user");
|
||||||
synchronized (map)
|
synchronized (map) {
|
||||||
{
|
for (Session session : map.values()) {
|
||||||
for (Session session : map.values())
|
|
||||||
{
|
|
||||||
log.debug("invalidating session for user: " + user);
|
log.debug("invalidating session for user: " + user);
|
||||||
session.setPrincipal(null);
|
session.setPrincipal(null);
|
||||||
session.setAuthType(null);
|
session.setAuthType(null);
|
||||||
|
@ -83,8 +71,7 @@ public class UserSessionManagement implements SessionListener
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionEvent(SessionEvent event)
|
public void sessionEvent(SessionEvent event) {
|
||||||
{
|
|
||||||
// We only care about session destroyed events
|
// We only care about session destroyed events
|
||||||
if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())
|
if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())
|
||||||
&& (!Session.SESSION_PASSIVATED_EVENT.equals(event.getType())))
|
&& (!Session.SESSION_PASSIVATED_EVENT.equals(event.getType())))
|
||||||
|
@ -100,8 +87,7 @@ public class UserSessionManagement implements SessionListener
|
||||||
String username = principal.getUserPrincipal().getName();
|
String username = principal.getUserPrincipal().getName();
|
||||||
Map<String, Session> map = userSessionMap.get(username);
|
Map<String, Session> map = userSessionMap.get(username);
|
||||||
if (map == null) return;
|
if (map == null) return;
|
||||||
synchronized (map)
|
synchronized (map) {
|
||||||
{
|
|
||||||
map.remove(session.getId());
|
map.remove(session.getId());
|
||||||
if (map.isEmpty()) userSessionMap.remove(username);
|
if (map.isEmpty()) userSessionMap.remove(username);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@ import java.util.List;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class AuthServerConfig
|
public class AuthServerConfig {
|
||||||
{
|
|
||||||
@JsonProperty("realm")
|
@JsonProperty("realm")
|
||||||
protected String realm;
|
protected String realm;
|
||||||
|
|
||||||
|
@ -72,208 +71,167 @@ public class AuthServerConfig
|
||||||
protected List<String> resources = new ArrayList<String>();
|
protected List<String> resources = new ArrayList<String>();
|
||||||
|
|
||||||
|
|
||||||
public String getRealm()
|
public String getRealm() {
|
||||||
{
|
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealm(String realm)
|
public void setRealm(String realm) {
|
||||||
{
|
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmPrivateKey()
|
public String getRealmPrivateKey() {
|
||||||
{
|
|
||||||
return realmPrivateKey;
|
return realmPrivateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmPrivateKey(String realmPrivateKey)
|
public void setRealmPrivateKey(String realmPrivateKey) {
|
||||||
{
|
|
||||||
this.realmPrivateKey = realmPrivateKey;
|
this.realmPrivateKey = realmPrivateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmPublicKey()
|
public String getRealmPublicKey() {
|
||||||
{
|
|
||||||
return realmPublicKey;
|
return realmPublicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmPublicKey(String realmPublicKey)
|
public void setRealmPublicKey(String realmPublicKey) {
|
||||||
{
|
|
||||||
this.realmPublicKey = realmPublicKey;
|
this.realmPublicKey = realmPublicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAccessCodeLifetime()
|
public int getAccessCodeLifetime() {
|
||||||
{
|
|
||||||
return accessCodeLifetime;
|
return accessCodeLifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessCodeLifetime(int accessCodeLifetime)
|
public void setAccessCodeLifetime(int accessCodeLifetime) {
|
||||||
{
|
|
||||||
this.accessCodeLifetime = accessCodeLifetime;
|
this.accessCodeLifetime = accessCodeLifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTruststore()
|
public String getTruststore() {
|
||||||
{
|
|
||||||
return truststore;
|
return truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTruststore(String truststore)
|
public void setTruststore(String truststore) {
|
||||||
{
|
|
||||||
this.truststore = truststore;
|
this.truststore = truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTruststorePassword()
|
public String getTruststorePassword() {
|
||||||
{
|
|
||||||
return truststorePassword;
|
return truststorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTruststorePassword(String truststorePassword)
|
public void setTruststorePassword(String truststorePassword) {
|
||||||
{
|
|
||||||
this.truststorePassword = truststorePassword;
|
this.truststorePassword = truststorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientKeystore()
|
public String getClientKeystore() {
|
||||||
{
|
|
||||||
return clientKeystore;
|
return clientKeystore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeystore(String clientKeystore)
|
public void setClientKeystore(String clientKeystore) {
|
||||||
{
|
|
||||||
this.clientKeystore = clientKeystore;
|
this.clientKeystore = clientKeystore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientKeystorePassword()
|
public String getClientKeystorePassword() {
|
||||||
{
|
|
||||||
return clientKeystorePassword;
|
return clientKeystorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeystorePassword(String clientKeystorePassword)
|
public void setClientKeystorePassword(String clientKeystorePassword) {
|
||||||
{
|
|
||||||
this.clientKeystorePassword = clientKeystorePassword;
|
this.clientKeystorePassword = clientKeystorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientKeyPassword()
|
public String getClientKeyPassword() {
|
||||||
{
|
|
||||||
return clientKeyPassword;
|
return clientKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeyPassword(String clientKeyPassword)
|
public void setClientKeyPassword(String clientKeyPassword) {
|
||||||
{
|
|
||||||
this.clientKeyPassword = clientKeyPassword;
|
this.clientKeyPassword = clientKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCancelPropagation()
|
public boolean isCancelPropagation() {
|
||||||
{
|
|
||||||
return cancelPropagation;
|
return cancelPropagation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCancelPropagation(boolean cancelPropagation)
|
public void setCancelPropagation(boolean cancelPropagation) {
|
||||||
{
|
|
||||||
this.cancelPropagation = cancelPropagation;
|
this.cancelPropagation = cancelPropagation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSsoDisabled()
|
public boolean isSsoDisabled() {
|
||||||
{
|
|
||||||
return ssoDisabled;
|
return ssoDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSsoDisabled(boolean ssoDisabled)
|
public void setSsoDisabled(boolean ssoDisabled) {
|
||||||
{
|
|
||||||
this.ssoDisabled = ssoDisabled;
|
this.ssoDisabled = ssoDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getResources()
|
public List<String> getResources() {
|
||||||
{
|
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAdminRole()
|
public String getAdminRole() {
|
||||||
{
|
|
||||||
return adminRole;
|
return adminRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAdminRole(String adminRole)
|
public void setAdminRole(String adminRole) {
|
||||||
{
|
|
||||||
this.adminRole = adminRole;
|
this.adminRole = adminRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLoginRole()
|
public String getLoginRole() {
|
||||||
{
|
|
||||||
return loginRole;
|
return loginRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoginRole(String loginRole)
|
public void setLoginRole(String loginRole) {
|
||||||
{
|
|
||||||
this.loginRole = loginRole;
|
this.loginRole = loginRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientRole()
|
public String getClientRole() {
|
||||||
{
|
|
||||||
return clientRole;
|
return clientRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientRole(String clientRole)
|
public void setClientRole(String clientRole) {
|
||||||
{
|
|
||||||
this.clientRole = clientRole;
|
this.clientRole = clientRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWildcardRole()
|
public String getWildcardRole() {
|
||||||
{
|
|
||||||
return wildcardRole;
|
return wildcardRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWildcardRole(String wildcardRole)
|
public void setWildcardRole(String wildcardRole) {
|
||||||
{
|
|
||||||
this.wildcardRole = wildcardRole;
|
this.wildcardRole = wildcardRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmKeyStore()
|
public String getRealmKeyStore() {
|
||||||
{
|
|
||||||
return realmKeyStore;
|
return realmKeyStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmKeyStore(String realmKeyStore)
|
public void setRealmKeyStore(String realmKeyStore) {
|
||||||
{
|
|
||||||
this.realmKeyStore = realmKeyStore;
|
this.realmKeyStore = realmKeyStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmKeystorePassword()
|
public String getRealmKeystorePassword() {
|
||||||
{
|
|
||||||
return realmKeystorePassword;
|
return realmKeystorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmKeystorePassword(String realmKeystorePassword)
|
public void setRealmKeystorePassword(String realmKeystorePassword) {
|
||||||
{
|
|
||||||
this.realmKeystorePassword = realmKeystorePassword;
|
this.realmKeystorePassword = realmKeystorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmKeyAlias()
|
public String getRealmKeyAlias() {
|
||||||
{
|
|
||||||
return realmKeyAlias;
|
return realmKeyAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmKeyAlias(String realmKeyAlias)
|
public void setRealmKeyAlias(String realmKeyAlias) {
|
||||||
{
|
|
||||||
this.realmKeyAlias = realmKeyAlias;
|
this.realmKeyAlias = realmKeyAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmPrivateKeyPassword()
|
public String getRealmPrivateKeyPassword() {
|
||||||
{
|
|
||||||
return realmPrivateKeyPassword;
|
return realmPrivateKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmPrivateKeyPassword(String realmPrivateKeyPassword)
|
public void setRealmPrivateKeyPassword(String realmPrivateKeyPassword) {
|
||||||
{
|
|
||||||
this.realmPrivateKeyPassword = realmPrivateKeyPassword;
|
this.realmPrivateKeyPassword = realmPrivateKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTokenLifetime()
|
public int getTokenLifetime() {
|
||||||
{
|
|
||||||
return tokenLifetime;
|
return tokenLifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTokenLifetime(int tokenLifetime)
|
public void setTokenLifetime(int tokenLifetime) {
|
||||||
{
|
|
||||||
this.tokenLifetime = tokenLifetime;
|
this.tokenLifetime = tokenLifetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,20 +10,18 @@ import java.util.Map;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
@JsonPropertyOrder({"realm", "resource", "realm-public-key", "admin-role", "auth-url", "code-url", "truststore", "truststore-password", "client-id", "client-credentials"})
|
@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
|
public class ManagedResourceConfig {
|
||||||
{
|
@JsonProperty("realm-url")
|
||||||
|
protected String realmUrl;
|
||||||
@JsonProperty("realm")
|
@JsonProperty("realm")
|
||||||
protected String realm;
|
protected String realm;
|
||||||
@JsonProperty("resource")
|
@JsonProperty("resource")
|
||||||
protected String resource;
|
protected String resource;
|
||||||
|
|
||||||
@JsonProperty("realm-public-key")
|
@JsonProperty("realm-public-key")
|
||||||
protected String realmKey;
|
protected String realmKey;
|
||||||
|
|
||||||
@JsonProperty("admin-role")
|
@JsonProperty("admin-role")
|
||||||
protected String adminRole;
|
protected String adminRole;
|
||||||
|
|
||||||
@JsonProperty("auth-url")
|
@JsonProperty("auth-url")
|
||||||
protected String authUrl;
|
protected String authUrl;
|
||||||
@JsonProperty("code-url")
|
@JsonProperty("code-url")
|
||||||
|
@ -31,10 +29,10 @@ public class ManagedResourceConfig
|
||||||
|
|
||||||
@JsonProperty("allow-any-hostname")
|
@JsonProperty("allow-any-hostname")
|
||||||
protected boolean allowAnyHostname;
|
protected boolean allowAnyHostname;
|
||||||
|
@JsonProperty("disable-trust-manager")
|
||||||
|
protected boolean disableTrustManager;
|
||||||
@JsonProperty("truststore")
|
@JsonProperty("truststore")
|
||||||
protected String truststore;
|
protected String truststore;
|
||||||
|
|
||||||
@JsonProperty("truststore-password")
|
@JsonProperty("truststore-password")
|
||||||
protected String truststorePassword;
|
protected String truststorePassword;
|
||||||
@JsonProperty("client-id")
|
@JsonProperty("client-id")
|
||||||
|
@ -45,169 +43,150 @@ public class ManagedResourceConfig
|
||||||
protected String clientKeystorePassword;
|
protected String clientKeystorePassword;
|
||||||
@JsonProperty("client-key-password")
|
@JsonProperty("client-key-password")
|
||||||
protected String clientKeyPassword;
|
protected String clientKeyPassword;
|
||||||
|
|
||||||
@JsonProperty("client-credentials")
|
@JsonProperty("client-credentials")
|
||||||
protected Map<String, String> clientCredentials = new HashMap<String, String>();
|
protected Map<String, String> clientCredentials = new HashMap<String, String>();
|
||||||
|
|
||||||
@JsonProperty("connection-pool-size")
|
@JsonProperty("connection-pool-size")
|
||||||
protected int connectionPoolSize;
|
protected int connectionPoolSize;
|
||||||
|
|
||||||
@JsonProperty("cancel-propagation")
|
@JsonProperty("cancel-propagation")
|
||||||
protected boolean cancelPropagation;
|
protected boolean cancelPropagation;
|
||||||
|
|
||||||
|
public String getRealmUrl() {
|
||||||
|
return realmUrl;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRealm()
|
public void setRealmUrl(String realmUrl) {
|
||||||
{
|
this.realmUrl = realmUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealm() {
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealm(String realm)
|
public void setRealm(String realm) {
|
||||||
{
|
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getResource()
|
public String getResource() {
|
||||||
{
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResource(String resource)
|
public void setResource(String resource) {
|
||||||
{
|
|
||||||
this.resource = resource;
|
this.resource = resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmKey()
|
public String getRealmKey() {
|
||||||
{
|
|
||||||
return realmKey;
|
return realmKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmKey(String realmKey)
|
public void setRealmKey(String realmKey) {
|
||||||
{
|
|
||||||
this.realmKey = realmKey;
|
this.realmKey = realmKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthUrl()
|
public String getAuthUrl() {
|
||||||
{
|
|
||||||
return authUrl;
|
return authUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthUrl(String authUrl)
|
public void setAuthUrl(String authUrl) {
|
||||||
{
|
|
||||||
this.authUrl = authUrl;
|
this.authUrl = authUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCodeUrl()
|
public String getCodeUrl() {
|
||||||
{
|
|
||||||
return codeUrl;
|
return codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCodeUrl(String codeUrl)
|
public void setCodeUrl(String codeUrl) {
|
||||||
{
|
|
||||||
this.codeUrl = codeUrl;
|
this.codeUrl = codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAllowAnyHostname()
|
public boolean isAllowAnyHostname() {
|
||||||
{
|
|
||||||
return allowAnyHostname;
|
return allowAnyHostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllowAnyHostname(boolean allowAnyHostname)
|
public void setAllowAnyHostname(boolean allowAnyHostname) {
|
||||||
{
|
|
||||||
this.allowAnyHostname = allowAnyHostname;
|
this.allowAnyHostname = allowAnyHostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTruststore()
|
public boolean isDisableTrustManager() {
|
||||||
{
|
return disableTrustManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisableTrustManager(boolean disableTrustManager) {
|
||||||
|
this.disableTrustManager = disableTrustManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTruststore() {
|
||||||
return truststore;
|
return truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTruststore(String truststore)
|
public void setTruststore(String truststore) {
|
||||||
{
|
|
||||||
this.truststore = truststore;
|
this.truststore = truststore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTruststorePassword()
|
public String getTruststorePassword() {
|
||||||
{
|
|
||||||
return truststorePassword;
|
return truststorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTruststorePassword(String truststorePassword)
|
public void setTruststorePassword(String truststorePassword) {
|
||||||
{
|
|
||||||
this.truststorePassword = truststorePassword;
|
this.truststorePassword = truststorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientId()
|
public String getClientId() {
|
||||||
{
|
|
||||||
return clientId;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientId(String clientId)
|
public void setClientId(String clientId) {
|
||||||
{
|
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getClientCredentials()
|
public Map<String, String> getClientCredentials() {
|
||||||
{
|
|
||||||
return clientCredentials;
|
return clientCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientKeystore()
|
public String getClientKeystore() {
|
||||||
{
|
|
||||||
return clientKeystore;
|
return clientKeystore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeystore(String clientKeystore)
|
public void setClientKeystore(String clientKeystore) {
|
||||||
{
|
|
||||||
this.clientKeystore = clientKeystore;
|
this.clientKeystore = clientKeystore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientKeystorePassword()
|
public String getClientKeystorePassword() {
|
||||||
{
|
|
||||||
return clientKeystorePassword;
|
return clientKeystorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeystorePassword(String clientKeystorePassword)
|
public void setClientKeystorePassword(String clientKeystorePassword) {
|
||||||
{
|
|
||||||
this.clientKeystorePassword = clientKeystorePassword;
|
this.clientKeystorePassword = clientKeystorePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClientKeyPassword()
|
public String getClientKeyPassword() {
|
||||||
{
|
|
||||||
return clientKeyPassword;
|
return clientKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientKeyPassword(String clientKeyPassword)
|
public void setClientKeyPassword(String clientKeyPassword) {
|
||||||
{
|
|
||||||
this.clientKeyPassword = clientKeyPassword;
|
this.clientKeyPassword = clientKeyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getConnectionPoolSize()
|
public int getConnectionPoolSize() {
|
||||||
{
|
|
||||||
return connectionPoolSize;
|
return connectionPoolSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConnectionPoolSize(int connectionPoolSize)
|
public void setConnectionPoolSize(int connectionPoolSize) {
|
||||||
{
|
|
||||||
this.connectionPoolSize = connectionPoolSize;
|
this.connectionPoolSize = connectionPoolSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCancelPropagation()
|
public boolean isCancelPropagation() {
|
||||||
{
|
|
||||||
return cancelPropagation;
|
return cancelPropagation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCancelPropagation(boolean cancelPropagation)
|
public void setCancelPropagation(boolean cancelPropagation) {
|
||||||
{
|
|
||||||
this.cancelPropagation = cancelPropagation;
|
this.cancelPropagation = cancelPropagation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAdminRole()
|
public String getAdminRole() {
|
||||||
{
|
|
||||||
return adminRole;
|
return adminRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAdminRole(String adminRole)
|
public void setAdminRole(String adminRole) {
|
||||||
{
|
|
||||||
this.adminRole = adminRole;
|
this.adminRole = adminRole;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,16 @@ import org.apache.catalina.Context;
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||||
import org.jboss.logging.Logger;
|
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.EnvUtil;
|
||||||
import org.keycloak.PemUtils;
|
import org.keycloak.PemUtils;
|
||||||
import org.keycloak.ResourceMetadata;
|
import org.keycloak.ResourceMetadata;
|
||||||
|
import org.keycloak.representations.idm.PublishedRealmRepresentation;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.WebTarget;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -16,107 +22,140 @@ import java.io.InputStream;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
|
||||||
public class ManagedResourceConfigLoader
|
public class ManagedResourceConfigLoader {
|
||||||
{
|
|
||||||
static final Logger log = Logger.getLogger(ManagedResourceConfigLoader.class);
|
static final Logger log = Logger.getLogger(ManagedResourceConfigLoader.class);
|
||||||
protected ManagedResourceConfig remoteSkeletonKeyConfig;
|
protected ManagedResourceConfig remoteSkeletonKeyConfig;
|
||||||
protected ResourceMetadata resourceMetadata;
|
protected ResourceMetadata resourceMetadata;
|
||||||
|
protected KeyStore clientCertKeystore;
|
||||||
|
protected KeyStore truststore;
|
||||||
|
protected ResteasyClient client;
|
||||||
|
|
||||||
public ManagedResourceConfigLoader(Context context)
|
public ManagedResourceConfigLoader(Context context) {
|
||||||
{
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
String path = context.getServletContext().getInitParameter("skeleton.key.config.file");
|
String path = context.getServletContext().getInitParameter("keycloak.config.file");
|
||||||
if (path == null)
|
if (path == null) {
|
||||||
{
|
|
||||||
is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json");
|
is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json");
|
||||||
}
|
} else {
|
||||||
else
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
is = new FileInputStream(path);
|
is = new FileInputStream(path);
|
||||||
}
|
} catch (FileNotFoundException e) {
|
||||||
catch (FileNotFoundException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remoteSkeletonKeyConfig = null;
|
remoteSkeletonKeyConfig = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
remoteSkeletonKeyConfig = mapper.readValue(is, ManagedResourceConfig.class);
|
remoteSkeletonKeyConfig = mapper.readValue(is, ManagedResourceConfig.class);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(boolean setupClient) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initClient();
|
||||||
|
|
||||||
String name = remoteSkeletonKeyConfig.getResource();
|
|
||||||
String realm = remoteSkeletonKeyConfig.getRealm();
|
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");
|
if (realm == null) throw new RuntimeException("Must set 'realm' in config");
|
||||||
|
|
||||||
String realmKeyPem = remoteSkeletonKeyConfig.getRealmKey();
|
String realmKeyPem = remoteSkeletonKeyConfig.getRealmKey();
|
||||||
if (realmKeyPem == null)
|
if (realmKeyPem == null) {
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("You must set the realm-public-key");
|
throw new IllegalArgumentException("You must set the realm-public-key");
|
||||||
}
|
}
|
||||||
|
|
||||||
PublicKey realmKey = null;
|
PublicKey realmKey = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
realmKey = PemUtils.decodePublicKey(realmKeyPem);
|
realmKey = PemUtils.decodePublicKey(realmKeyPem);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceMetadata = new ResourceMetadata();
|
resourceMetadata = new ResourceMetadata();
|
||||||
resourceMetadata.setRealm(realm);
|
resourceMetadata.setRealm(realm);
|
||||||
resourceMetadata.setResourceName(name);
|
resourceMetadata.setResourceName(resource);
|
||||||
resourceMetadata.setRealmKey(realmKey);
|
resourceMetadata.setRealmKey(realmKey);
|
||||||
|
resourceMetadata.setClientKeystore(clientCertKeystore);
|
||||||
|
|
||||||
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();
|
clientKeyPassword = remoteSkeletonKeyConfig.getClientKeyPassword();
|
||||||
resourceMetadata.setClientKeyPassword(clientKeyPassword);
|
resourceMetadata.setClientKeyPassword(clientKeyPassword);
|
||||||
}
|
resourceMetadata.setTruststore(this.truststore);
|
||||||
|
|
||||||
}
|
}
|
||||||
public static KeyStore loadKeyStore(String filename, String password) throws Exception
|
|
||||||
{
|
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
|
KeyStore trustStore = KeyStore.getInstance(KeyStore
|
||||||
.getDefaultType());
|
.getDefaultType());
|
||||||
File truststoreFile = new File(filename);
|
File truststoreFile = new File(filename);
|
||||||
|
@ -126,14 +165,23 @@ public class ManagedResourceConfigLoader
|
||||||
return trustStore;
|
return trustStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManagedResourceConfig getRemoteSkeletonKeyConfig()
|
public ManagedResourceConfig getRemoteSkeletonKeyConfig() {
|
||||||
{
|
|
||||||
return remoteSkeletonKeyConfig;
|
return remoteSkeletonKeyConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceMetadata getResourceMetadata()
|
public ResourceMetadata getResourceMetadata() {
|
||||||
{
|
|
||||||
return resourceMetadata;
|
return resourceMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ResteasyClient getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyStore getClientCertKeystore() {
|
||||||
|
return clientCertKeystore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyStore getTruststore() {
|
||||||
|
return truststore;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ import javax.ws.rs.core.UriInfo;
|
||||||
*/
|
*/
|
||||||
public class RealmSubResource {
|
public class RealmSubResource {
|
||||||
protected static final Logger logger = Logger.getLogger(RealmSubResource.class);
|
protected static final Logger logger = Logger.getLogger(RealmSubResource.class);
|
||||||
|
public static final String ADMIN_ROLE = "$REALM-ADMIN$";
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected UriInfo uriInfo;
|
protected UriInfo uriInfo;
|
||||||
|
@ -32,8 +33,13 @@ public class RealmSubResource {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static UriBuilder realmUrl(UriInfo uriInfo) {
|
||||||
|
UriBuilder base = uriInfo.getBaseUriBuilder()
|
||||||
|
.path(RealmsResource.class).path(RealmsResource.class, "getRealmResource");
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("json")
|
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) {
|
public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) {
|
||||||
return realmRep(realm, uriInfo);
|
return realmRep(realm, uriInfo);
|
||||||
|
@ -65,26 +71,14 @@ public class RealmSubResource {
|
||||||
public static PublishedRealmRepresentation realmRep(RealmModel realm, UriInfo uriInfo) {
|
public static PublishedRealmRepresentation realmRep(RealmModel realm, UriInfo uriInfo) {
|
||||||
PublishedRealmRepresentation rep = new PublishedRealmRepresentation();
|
PublishedRealmRepresentation rep = new PublishedRealmRepresentation();
|
||||||
rep.setRealm(realm.getName());
|
rep.setRealm(realm.getName());
|
||||||
rep.setSelf(uriInfo.getRequestUri().toString());
|
rep.setSelf(realmUrl(uriInfo).build(realm.getId()).toString());
|
||||||
rep.setPublicKeyPem(realm.getPublicKeyPem());
|
rep.setPublicKeyPem(realm.getPublicKeyPem());
|
||||||
|
rep.setAdminRole(ADMIN_ROLE);
|
||||||
|
|
||||||
UriBuilder auth = uriInfo.getBaseUriBuilder();
|
rep.setAuthorizationUrl(TokenService.loginPage(uriInfo).build(realm.getId()).toString());
|
||||||
auth.path(RealmsResource.class).path(RealmsResource.class, "getTokenService")
|
rep.setCodeUrl(TokenService.accessCodeRequest(uriInfo).build(realm.getId()).toString());
|
||||||
.path(TokenService.class, "requestAccessCode");
|
rep.setGrantUrl(TokenService.grantRequest(uriInfo).build(realm.getId()).toString());
|
||||||
rep.setAuthorizationUrl(auth.build(realm.getId()).toString());
|
String idGrantUrl = TokenService.identityGrantRequest(uriInfo).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.setIdentityGrantUrl(idGrantUrl);
|
rep.setIdentityGrantUrl(idGrantUrl);
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue