keycloak-service
静的公開メンバ関数 | 静的公開変数類 | 静的限定公開変数類 | 静的非公開メンバ関数 | 静的非公開変数類 | 全メンバ一覧
org.keycloak.services.util.MtlsHoKTokenUtil クラス
org.keycloak.services.util.MtlsHoKTokenUtil 連携図
Collaboration graph

静的公開メンバ関数

static AccessToken.CertConf bindTokenWithClientCertificate (HttpRequest request, KeycloakSession session)
 
static boolean verifyTokenBindingWithClientCertificate (AccessToken token, HttpRequest request, KeycloakSession session)
 

静的公開変数類

static final String CERT_VERIFY_ERROR_DESC = "Client certificate missing, or its thumbprint and one in the refresh token did NOT match"
 

静的限定公開変数類

static final Logger logger = Logger.getLogger(MtlsHoKTokenUtil.class)
 

静的非公開メンバ関数

static X509Certificate [] getCertificateChain (HttpRequest request, KeycloakSession session)
 
static String getCertificateThumbprintInSHA256DERX509Base64UrlEncoded (X509Certificate cert) throws NoSuchAlgorithmException, CertificateEncodingException
 
static void dumpCertInfo (X509Certificate[] certs) throws CertificateEncodingException
 

静的非公開変数類

static final String DIGEST_ALG = "SHA-256"
 

詳解

関数詳解

◆ bindTokenWithClientCertificate()

static AccessToken.CertConf org.keycloak.services.util.MtlsHoKTokenUtil.bindTokenWithClientCertificate ( HttpRequest  request,
KeycloakSession  session 
)
inlinestatic
27  {
28  X509Certificate[] certs = getCertificateChain(request, session);
29 
30  if (certs == null || certs.length < 1) {
31  logger.warnf("no client certificate available.");
32  return null;
33  }
34 
35  String DERX509Base64UrlEncoded = null;
36  try {
37  // On Certificate Chain, first entry is considered to be client certificate.
38  DERX509Base64UrlEncoded = getCertificateThumbprintInSHA256DERX509Base64UrlEncoded(certs[0]);
39  if (logger.isTraceEnabled()) dumpCertInfo(certs);
40  } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
41  // give up issuing MTLS HoK Token
42  logger.warnf("give up issuing hok token. %s", e);
43  return null;
44  }
45 
46  AccessToken.CertConf certConf = new AccessToken.CertConf();
47  certConf.setCertThumbprint(DERX509Base64UrlEncoded);
48  return certConf;
49  }
static String getCertificateThumbprintInSHA256DERX509Base64UrlEncoded(X509Certificate cert)
Definition: MtlsHoKTokenUtil.java:108
static final Logger logger
Definition: MtlsHoKTokenUtil.java:20
static void dumpCertInfo(X509Certificate[] certs)
Definition: MtlsHoKTokenUtil.java:120
static X509Certificate [] getCertificateChain(HttpRequest request, KeycloakSession session)
Definition: MtlsHoKTokenUtil.java:92

◆ dumpCertInfo()

static void org.keycloak.services.util.MtlsHoKTokenUtil.dumpCertInfo ( X509Certificate []  certs) throws CertificateEncodingException
inlinestaticprivate
120  {
121  logger.tracef(":: Try Holder of Key Token");
122  logger.tracef(":: # of x509 Client Certificate in Certificate Chain = %d", certs.length);
123  for (int i = 0; i < certs.length; i++) {
124  logger.tracef(":: certs[%d] Raw Bytes Counts of first x509 Client Certificate in Certificate Chain = %d", i, certs[i].toString().length());
125  logger.tracef(":: certs[%d] Raw Bytes String of first x509 Client Certificate in Certificate Chain = %s", i, certs[i].toString());
126  logger.tracef(":: certs[%d] DER Dump Bytes of first x509 Client Certificate in Certificate Chain = %d", i, certs[i].getEncoded().length);
127  String DERX509Base64UrlEncoded = null;
128  try {
129  DERX509Base64UrlEncoded = getCertificateThumbprintInSHA256DERX509Base64UrlEncoded(certs[i]);
130  } catch (Exception e) {}
131  logger.tracef(":: certs[%d] Base64URL Encoded SHA-256 Hash of DER formatted first x509 Client Certificate in Certificate Chain = %s", i, DERX509Base64UrlEncoded);
132  logger.tracef(":: certs[%d] DER Dump Bytes of first x509 Client Certificate TBScertificate in Certificate Chain = %d", i, certs[i].getTBSCertificate().length);
133  logger.tracef(":: certs[%d] Signature Algorithm of first x509 Client Certificate in Certificate Chain = %s", i, certs[i].getSigAlgName());
134  logger.tracef(":: certs[%d] Certfication Type of first x509 Client Certificate in Certificate Chain = %s", i, certs[i].getType());
135  logger.tracef(":: certs[%d] Issuer DN of first x509 Client Certificate in Certificate Chain = %s", i, certs[i].getIssuerDN().getName());
136  logger.tracef(":: certs[%d] Subject DN of first x509 Client Certificate in Certificate Chain = %s", i, certs[i].getSubjectDN().getName());
137  }
138  }
static String getCertificateThumbprintInSHA256DERX509Base64UrlEncoded(X509Certificate cert)
Definition: MtlsHoKTokenUtil.java:108
static final Logger logger
Definition: MtlsHoKTokenUtil.java:20

◆ getCertificateChain()

static X509Certificate [] org.keycloak.services.util.MtlsHoKTokenUtil.getCertificateChain ( HttpRequest  request,
KeycloakSession  session 
)
inlinestaticprivate
92  {
93  try {
94  // Get a x509 client certificate
95  X509ClientCertificateLookup provider = session.getProvider(X509ClientCertificateLookup.class);
96  if (provider == null) {
97  logger.errorv("\"{0}\" Spi is not available, did you forget to update the configuration?", X509ClientCertificateLookup.class);
98  return null;
99  }
100  X509Certificate[] certs = provider.getCertificateChain(request);
101  return certs;
102  } catch (GeneralSecurityException e) {
103  logger.error(e.getMessage(), e);
104  }
105  return null;
106  }
static final Logger logger
Definition: MtlsHoKTokenUtil.java:20

◆ getCertificateThumbprintInSHA256DERX509Base64UrlEncoded()

static String org.keycloak.services.util.MtlsHoKTokenUtil.getCertificateThumbprintInSHA256DERX509Base64UrlEncoded ( X509Certificate  cert) throws NoSuchAlgorithmException, CertificateEncodingException
inlinestaticprivate
108  {
109  // need to calculate over DER encoding of the X.509 certificate
110  // https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3.1
111  // in order to do that, call getEncoded()
112  // https://docs.oracle.com/javase/8/docs/api/java/security/cert/Certificate.html#getEncoded--
113  byte[] DERX509Hash = cert.getEncoded();
114  MessageDigest md = MessageDigest.getInstance(DIGEST_ALG);
115  md.update(DERX509Hash);
116  String DERX509Base64UrlEncoded = Base64Url.encode(md.digest());
117  return DERX509Base64UrlEncoded;
118  }
static final String DIGEST_ALG
Definition: MtlsHoKTokenUtil.java:22

◆ verifyTokenBindingWithClientCertificate()

static boolean org.keycloak.services.util.MtlsHoKTokenUtil.verifyTokenBindingWithClientCertificate ( AccessToken  token,
HttpRequest  request,
KeycloakSession  session 
)
inlinestatic
51  {
52  if (token == null) {
53  logger.warnf("token is null");
54  return false;
55  }
56 
57  // Bearer Token, not MTLS HoK Token
58  if (token.getCertConf() == null) {
59  logger.warnf("bearer token received instead of hok token.");
60  return false;
61  }
62 
63  X509Certificate[] certs = getCertificateChain(request, session);
64 
65  // HoK Token, but no Client Certificate available
66  if (certs == null || certs.length < 1) {
67  logger.warnf("missing client certificate.");
68  return false;
69  }
70 
71  String DERX509Base64UrlEncoded = null;
72  String x5ts256 = token.getCertConf().getCertThumbprint();
73  logger.tracef("hok token cnf-x5t#s256 = %s", x5ts256);
74 
75  try {
76  // On Certificate Chain, first entry is considered to be client certificate.
77  DERX509Base64UrlEncoded = getCertificateThumbprintInSHA256DERX509Base64UrlEncoded(certs[0]);
78  if (logger.isTraceEnabled()) dumpCertInfo(certs);
79  } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
80  logger.warnf("client certificate exception. %s", e);
81  return false;
82  }
83 
84  if (!MessageDigest.isEqual(x5ts256.getBytes(), DERX509Base64UrlEncoded.getBytes())) {
85  logger.warnf("certificate's thumbprint and one in the refresh token did not match.");
86  return false;
87  }
88 
89  return true;
90  }
static String getCertificateThumbprintInSHA256DERX509Base64UrlEncoded(X509Certificate cert)
Definition: MtlsHoKTokenUtil.java:108
static final Logger logger
Definition: MtlsHoKTokenUtil.java:20
static void dumpCertInfo(X509Certificate[] certs)
Definition: MtlsHoKTokenUtil.java:120
static X509Certificate [] getCertificateChain(HttpRequest request, KeycloakSession session)
Definition: MtlsHoKTokenUtil.java:92

メンバ詳解

◆ CERT_VERIFY_ERROR_DESC

final String org.keycloak.services.util.MtlsHoKTokenUtil.CERT_VERIFY_ERROR_DESC = "Client certificate missing, or its thumbprint and one in the refresh token did NOT match"
static

◆ DIGEST_ALG

final String org.keycloak.services.util.MtlsHoKTokenUtil.DIGEST_ALG = "SHA-256"
staticprivate

◆ logger

final Logger org.keycloak.services.util.MtlsHoKTokenUtil.logger = Logger.getLogger(MtlsHoKTokenUtil.class)
staticprotected

このクラス詳解は次のファイルから抽出されました: