KEYCLOAK-1295 pluggable client authentication. Support authenticate clients with signed JWT
This commit is contained in:
1 parent
a4e16ca9c7
commit
7028496601
74 files changed
+2630
-397
No files matched your search
@@ -31,6 +31,13 @@ public interface OAuth2Constants {
|
||||
|
||||
String CLIENT_CREDENTIALS = "client_credentials";
|
||||
|
||||
// https://tools.ietf.org/html/draft-ietf-oauth-assertions-01#page-5
|
||||
String CLIENT_ASSERTION_TYPE = "client_assertion_type";
|
||||
String CLIENT_ASSERTION = "client_assertion";
|
||||
|
||||
// https://tools.ietf.org/html/draft-jones-oauth-jwt-bearer-03#section-2.2
|
||||
String CLIENT_ASSERTION_TYPE_JWT = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.keycloak.representations.idm;
|
||||
|
||||
/**
|
||||
* PEM values of key and certificate
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class CertificateRepresentation {
|
||||
|
||||
protected String privateKey;
|
||||
protected String certificate;
|
||||
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public void setPrivateKey(String privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
public String getCertificate() {
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public void setCertificate(String certificate) {
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -90,6 +90,7 @@ public class RealmRepresentation {
|
||||
protected String browserFlow;
|
||||
protected String registrationFlow;
|
||||
protected String directGrantFlow;
|
||||
protected String clientAuthenticationFlow;
|
||||
|
||||
@Deprecated
|
||||
protected Boolean social;
|
||||
@@ -735,4 +736,12 @@ public class RealmRepresentation {
|
||||
public void setDirectGrantFlow(String directGrantFlow) {
|
||||
this.directGrantFlow = directGrantFlow;
|
||||
}
|
||||
|
||||
public String getClientAuthenticationFlow() {
|
||||
return clientAuthenticationFlow;
|
||||
}
|
||||
|
||||
public void setClientAuthenticationFlow(String clientAuthenticationFlow) {
|
||||
this.clientAuthenticationFlow = clientAuthenticationFlow;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
|
||||
import org.keycloak.constants.GenericConstants;
|
||||
|
||||
@@ -12,6 +13,14 @@ import org.keycloak.constants.GenericConstants;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class KeystoreUtil {
|
||||
static {
|
||||
BouncyIntegration.init();
|
||||
}
|
||||
|
||||
public enum KeystoreFormat {
|
||||
JKS,
|
||||
PKCS12
|
||||
}
|
||||
|
||||
public static KeyStore loadKeyStore(String filename, String password) throws Exception {
|
||||
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
@@ -22,4 +31,26 @@ public class KeystoreUtil {
|
||||
trustStream.close();
|
||||
return trustStore;
|
||||
}
|
||||
|
||||
public static PrivateKey loadPrivateKeyFromKeystore(String keystoreFile, String storePassword, String keyPassword, String keyAlias, KeystoreFormat format) {
|
||||
InputStream stream = FindFile.findFile(keystoreFile);
|
||||
|
||||
try {
|
||||
KeyStore keyStore = null;
|
||||
if (format == KeystoreFormat.JKS) {
|
||||
keyStore = KeyStore.getInstance(format.toString());
|
||||
} else {
|
||||
keyStore = KeyStore.getInstance(format.toString(), "BC");
|
||||
}
|
||||
|
||||
keyStore.load(stream, storePassword.toCharArray());
|
||||
PrivateKey key = (PrivateKey) keyStore.getKey(keyAlias, keyPassword.toCharArray());
|
||||
if (key == null) {
|
||||
throw new RuntimeException("Couldn't load key with alias '" + keyAlias + "' from keystore");
|
||||
}
|
||||
return key;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load private key: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user