Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b70b5ddcd | ||
|
|
fd73d48e0e |
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ package org.keycloak.broker.oidc;
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.ClientConnection;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.broker.provider.util.SimpleHttp;
|
||||
import org.keycloak.broker.provider.AbstractIdentityProvider;
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.IdentityBrokerService;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.util.PemUtils;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.keycloak.broker.saml;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.ClientConnection;
|
||||
import org.keycloak.VerificationException;
|
||||
import org.keycloak.broker.provider.BrokeredIdentityContext;
|
||||
import org.keycloak.broker.provider.IdentityBrokerException;
|
||||
import org.keycloak.broker.provider.IdentityProvider;
|
||||
@@ -10,6 +10,7 @@ import org.keycloak.dom.saml.v2.assertion.AssertionType;
|
||||
import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
|
||||
import org.keycloak.dom.saml.v2.assertion.AttributeType;
|
||||
import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
|
||||
import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
|
||||
import org.keycloak.dom.saml.v2.assertion.NameIDType;
|
||||
import org.keycloak.dom.saml.v2.assertion.SubjectType;
|
||||
import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
|
||||
@@ -23,23 +24,31 @@ import org.keycloak.events.EventType;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder;
|
||||
import org.keycloak.saml.SAML2LogoutResponseBuilder;
|
||||
import org.keycloak.saml.SAMLRequestParser;
|
||||
import org.keycloak.protocol.saml.SAML2LogoutResponseBuilder;
|
||||
import org.keycloak.protocol.saml.SAMLRequestParser;
|
||||
import org.keycloak.protocol.saml.SamlProtocol;
|
||||
import org.keycloak.protocol.saml.SamlProtocolUtils;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLConstants;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
import org.keycloak.saml.common.util.DocumentUtil;
|
||||
import org.keycloak.saml.common.util.StaxParserUtil;
|
||||
import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
|
||||
import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
|
||||
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
||||
import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
|
||||
import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil;
|
||||
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
|
||||
import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
|
||||
import org.keycloak.saml.processing.core.util.XMLSignatureUtil;
|
||||
import org.keycloak.saml.processing.web.util.PostBindingUtil;
|
||||
import org.keycloak.services.ErrorPage;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.FormParam;
|
||||
@@ -52,7 +61,9 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import javax.xml.namespace.QName;
|
||||
import java.io.IOException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
@@ -144,7 +155,7 @@ public class SAMLEndpoint {
|
||||
}
|
||||
|
||||
protected abstract String getBindingType();
|
||||
protected abstract void verifySignature(String key, SAMLDocumentHolder documentHolder) throws VerificationException;
|
||||
protected abstract void verifySignature(SAMLDocumentHolder documentHolder) throws VerificationException;
|
||||
protected abstract SAMLDocumentHolder extractRequestDocument(String samlRequest);
|
||||
protected abstract SAMLDocumentHolder extractResponseDocument(String response);
|
||||
protected PublicKey getIDPKey() {
|
||||
@@ -177,7 +188,7 @@ public class SAMLEndpoint {
|
||||
}
|
||||
if (config.isValidateSignature()) {
|
||||
try {
|
||||
verifySignature(GeneralConstants.SAML_REQUEST_KEY, holder);
|
||||
verifySignature(holder);
|
||||
} catch (VerificationException e) {
|
||||
logger.error("validation failed", e);
|
||||
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
||||
@@ -236,18 +247,16 @@ public class SAMLEndpoint {
|
||||
builder.logoutRequestID(request.getID());
|
||||
builder.destination(config.getSingleLogoutServiceUrl());
|
||||
builder.issuer(issuerURL);
|
||||
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder()
|
||||
.relayState(relayState);
|
||||
builder.relayState(relayState);
|
||||
if (config.isWantAuthnRequestsSigned()) {
|
||||
binding.signWith(realm.getPrivateKey(), realm.getPublicKey(), realm.getCertificate())
|
||||
.signatureAlgorithm(provider.getSignatureAlgorithm())
|
||||
builder.signWith(realm.getPrivateKey(), realm.getPublicKey(), realm.getCertificate())
|
||||
.signDocument();
|
||||
}
|
||||
try {
|
||||
if (config.isPostBindingResponse()) {
|
||||
return binding.postBinding(builder.buildDocument()).response(config.getSingleLogoutServiceUrl());
|
||||
return builder.postBinding().response();
|
||||
} else {
|
||||
return binding.redirectBinding(builder.buildDocument()).response(config.getSingleLogoutServiceUrl());
|
||||
return builder.redirectBinding().response();
|
||||
}
|
||||
} catch (ConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -265,7 +274,7 @@ public class SAMLEndpoint {
|
||||
protected Response handleLoginResponse(String samlResponse, SAMLDocumentHolder holder, ResponseType responseType, String relayState) {
|
||||
|
||||
try {
|
||||
AssertionType assertion = AssertionUtil.getAssertion(responseType, realm.getPrivateKey());
|
||||
AssertionType assertion = getAssertion(responseType);
|
||||
SubjectType subject = assertion.getSubject();
|
||||
SubjectType.STSubType subType = subject.getSubType();
|
||||
NameIDType subjectNameID = (NameIDType) subType.getBaseID();
|
||||
@@ -325,6 +334,22 @@ public class SAMLEndpoint {
|
||||
|
||||
|
||||
|
||||
private AssertionType getAssertion(ResponseType responseType) throws ProcessingException {
|
||||
List<ResponseType.RTChoiceType> assertions = responseType.getAssertions();
|
||||
|
||||
if (assertions.isEmpty()) {
|
||||
throw new IdentityBrokerException("No assertion from response.");
|
||||
}
|
||||
|
||||
ResponseType.RTChoiceType rtChoiceType = assertions.get(0);
|
||||
EncryptedAssertionType encryptedAssertion = rtChoiceType.getEncryptedAssertion();
|
||||
|
||||
if (encryptedAssertion != null) {
|
||||
decryptAssertion(responseType, realm.getPrivateKey());
|
||||
|
||||
}
|
||||
return responseType.getAssertions().get(0).getAssertion();
|
||||
}
|
||||
|
||||
public Response handleSamlResponse(String samlResponse, String relayState) {
|
||||
SAMLDocumentHolder holder = extractResponseDocument(samlResponse);
|
||||
@@ -338,7 +363,7 @@ public class SAMLEndpoint {
|
||||
}
|
||||
if (config.isValidateSignature()) {
|
||||
try {
|
||||
verifySignature(GeneralConstants.SAML_RESPONSE_KEY, holder);
|
||||
verifySignature(holder);
|
||||
} catch (VerificationException e) {
|
||||
logger.error("validation failed", e);
|
||||
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
||||
@@ -381,14 +406,43 @@ public class SAMLEndpoint {
|
||||
}
|
||||
|
||||
|
||||
protected ResponseType decryptAssertion(ResponseType responseType, PrivateKey privateKey) throws ProcessingException {
|
||||
SAML2Response saml2Response = new SAML2Response();
|
||||
|
||||
try {
|
||||
Document doc = saml2Response.convert(responseType);
|
||||
Element enc = DocumentUtil.getElement(doc, new QName(JBossSAMLConstants.ENCRYPTED_ASSERTION.get()));
|
||||
|
||||
if (enc == null) {
|
||||
throw new IdentityBrokerException("No encrypted assertion found.");
|
||||
}
|
||||
|
||||
String oldID = enc.getAttribute(JBossSAMLConstants.ID.get());
|
||||
Document newDoc = DocumentUtil.createDocument();
|
||||
Node importedNode = newDoc.importNode(enc, true);
|
||||
newDoc.appendChild(importedNode);
|
||||
|
||||
Element decryptedDocumentElement = XMLEncryptionUtil.decryptElementInDocument(newDoc, privateKey);
|
||||
SAMLParser parser = new SAMLParser();
|
||||
|
||||
JAXPValidationUtil.checkSchemaValidation(decryptedDocumentElement);
|
||||
AssertionType assertion = (AssertionType) parser.parse(StaxParserUtil.getXMLEventReader(DocumentUtil
|
||||
.getNodeAsStream(decryptedDocumentElement)));
|
||||
|
||||
responseType.replaceAssertion(oldID, new ResponseType.RTChoiceType(assertion));
|
||||
|
||||
return responseType;
|
||||
} catch (Exception e) {
|
||||
throw new IdentityBrokerException("Could not decrypt assertion.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected class PostBinding extends Binding {
|
||||
@Override
|
||||
protected void verifySignature(String key, SAMLDocumentHolder documentHolder) throws VerificationException {
|
||||
protected void verifySignature(SAMLDocumentHolder documentHolder) throws VerificationException {
|
||||
SamlProtocolUtils.verifyDocumentSignature(documentHolder.getSamlDocument(), getIDPKey());
|
||||
}
|
||||
|
||||
@@ -411,9 +465,9 @@ public class SAMLEndpoint {
|
||||
|
||||
protected class RedirectBinding extends Binding {
|
||||
@Override
|
||||
protected void verifySignature(String key, SAMLDocumentHolder documentHolder) throws VerificationException {
|
||||
protected void verifySignature(SAMLDocumentHolder documentHolder) throws VerificationException {
|
||||
PublicKey publicKey = getIDPKey();
|
||||
SamlProtocolUtils.verifyRedirectSignature(publicKey, uriInfo, key);
|
||||
SamlProtocolUtils.verifyRedirectSignature(publicKey, uriInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,18 +33,20 @@ import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder;
|
||||
import org.keycloak.saml.SAML2AuthnRequestBuilder;
|
||||
import org.keycloak.saml.SAML2LogoutRequestBuilder;
|
||||
import org.keycloak.saml.SAML2NameIDPolicyBuilder;
|
||||
import org.keycloak.saml.SignatureAlgorithm;
|
||||
import org.keycloak.protocol.saml.SAML2AuthnRequestBuilder;
|
||||
import org.keycloak.protocol.saml.SAML2LogoutRequestBuilder;
|
||||
import org.keycloak.protocol.saml.SAML2NameIDPolicyBuilder;
|
||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
@@ -90,8 +92,7 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
.issuer(issuerURL)
|
||||
.forceAuthn(getConfig().isForceAuthn())
|
||||
.protocolBinding(protocolBinding)
|
||||
.nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat));
|
||||
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder()
|
||||
.nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat))
|
||||
.relayState(request.getState());
|
||||
|
||||
if (getConfig().isWantAuthnRequestsSigned()) {
|
||||
@@ -108,15 +109,14 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
|
||||
KeyPair keypair = new KeyPair(publicKey, privateKey);
|
||||
|
||||
binding.signWith(keypair);
|
||||
binding.signatureAlgorithm(getSignatureAlgorithm());
|
||||
binding.signDocument();
|
||||
authnRequestBuilder.signWith(keypair);
|
||||
authnRequestBuilder.signDocument();
|
||||
}
|
||||
|
||||
if (getConfig().isPostBindingAuthnRequest()) {
|
||||
return binding.postBinding(authnRequestBuilder.toDocument()).request(destinationUrl);
|
||||
return authnRequestBuilder.postBinding().request();
|
||||
} else {
|
||||
return binding.redirectBinding(authnRequestBuilder.toDocument()).request(destinationUrl);
|
||||
return authnRequestBuilder.redirectBinding().request();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IdentityBrokerException("Could not create authentication request.", e);
|
||||
@@ -153,10 +153,9 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
String singleLogoutServiceUrl = getConfig().getSingleLogoutServiceUrl();
|
||||
if (singleLogoutServiceUrl == null || singleLogoutServiceUrl.trim().equals("") || !getConfig().isBackchannelSupported()) return;
|
||||
SAML2LogoutRequestBuilder logoutBuilder = buildLogoutRequest(userSession, uriInfo, realm, singleLogoutServiceUrl);
|
||||
JaxrsSAML2BindingBuilder binding = buildLogoutBinding(userSession, realm);
|
||||
try {
|
||||
int status = SimpleHttp.doPost(singleLogoutServiceUrl)
|
||||
.param(GeneralConstants.SAML_REQUEST_KEY, binding.postBinding(logoutBuilder.buildDocument()).encoded())
|
||||
.param(GeneralConstants.SAML_REQUEST_KEY, logoutBuilder.postBinding().encoded())
|
||||
.param(GeneralConstants.RELAY_STATE, userSession.getId()).asStatus();
|
||||
boolean success = status >=200 && status < 400;
|
||||
if (!success) {
|
||||
@@ -179,8 +178,7 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
} else {
|
||||
try {
|
||||
SAML2LogoutRequestBuilder logoutBuilder = buildLogoutRequest(userSession, uriInfo, realm, singleLogoutServiceUrl);
|
||||
JaxrsSAML2BindingBuilder binding = buildLogoutBinding(userSession, realm);
|
||||
return binding.postBinding(logoutBuilder.buildDocument()).request(singleLogoutServiceUrl);
|
||||
return logoutBuilder.postBinding().request();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -194,19 +192,13 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
.issuer(getEntityId(uriInfo, realm))
|
||||
.sessionIndex(userSession.getNote(SAMLEndpoint.SAML_FEDERATED_SESSION_INDEX))
|
||||
.userPrincipal(userSession.getNote(SAMLEndpoint.SAML_FEDERATED_SUBJECT), userSession.getNote(SAMLEndpoint.SAML_FEDERATED_SUBJECT_NAMEFORMAT))
|
||||
.destination(singleLogoutServiceUrl);
|
||||
return logoutBuilder;
|
||||
}
|
||||
|
||||
private JaxrsSAML2BindingBuilder buildLogoutBinding(UserSessionModel userSession, RealmModel realm) {
|
||||
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder()
|
||||
.destination(singleLogoutServiceUrl)
|
||||
.relayState(userSession.getId());
|
||||
if (getConfig().isWantAuthnRequestsSigned()) {
|
||||
binding.signWith(realm.getPrivateKey(), realm.getPublicKey(), realm.getCertificate())
|
||||
.signatureAlgorithm(getSignatureAlgorithm())
|
||||
logoutBuilder.signWith(realm.getPrivateKey(), realm.getPublicKey(), realm.getCertificate())
|
||||
.signDocument();
|
||||
}
|
||||
return binding;
|
||||
return logoutBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,7 +220,7 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
|
||||
|
||||
String descriptor =
|
||||
"<EntityDescriptor xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\" entityID=\"" + getEntityId(uriInfo, realm) + "\">\n" +
|
||||
"<EntityDescriptor entityID=\"" + getEntityId(uriInfo, realm) + "\">\n" +
|
||||
" <SPSSODescriptor AuthnRequestsSigned=\"" + getConfig().isWantAuthnRequestsSigned() + "\"\n" +
|
||||
" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol http://schemas.xmlsoap.org/ws/2003/07/secext\">\n" +
|
||||
" <NameIDFormat>" + getConfig().getNameIDPolicyFormat() + "\n" +
|
||||
@@ -253,14 +245,4 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
"</EntityDescriptor>\n";
|
||||
return Response.ok(descriptor, MediaType.APPLICATION_XML_TYPE).build();
|
||||
}
|
||||
|
||||
public SignatureAlgorithm getSignatureAlgorithm() {
|
||||
String alg = getConfig().getSignatureAlgorithm();
|
||||
if (alg != null) {
|
||||
SignatureAlgorithm algorithm = SignatureAlgorithm.valueOf(alg);
|
||||
if (algorithm != null) return algorithm;
|
||||
}
|
||||
return SignatureAlgorithm.RSA_SHA256;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -87,14 +87,6 @@ public class SAMLIdentityProviderConfig extends IdentityProviderModel {
|
||||
getConfig().put("wantAuthnRequestsSigned", String.valueOf(wantAuthnRequestsSigned));
|
||||
}
|
||||
|
||||
public String getSignatureAlgorithm() {
|
||||
return getConfig().get("signatureAlgorithm");
|
||||
}
|
||||
|
||||
public void setSignatureAlgorithm(String signatureAlgorithm) {
|
||||
getConfig().put("signatureAlgorithm", signatureAlgorithm);
|
||||
}
|
||||
|
||||
public String getEncryptionPublicKey() {
|
||||
return getConfig().get("encryptionPublicKey");
|
||||
}
|
||||
|
||||
+60
-64
@@ -73,78 +73,74 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory
|
||||
List<EntityDescriptorType.EDTChoiceType> choiceType = entityType.getChoiceType();
|
||||
|
||||
if (!choiceType.isEmpty()) {
|
||||
IDPSSODescriptorType idpDescriptor = null;
|
||||
EntityDescriptorType.EDTChoiceType edtChoiceType = choiceType.get(0);
|
||||
List<EntityDescriptorType.EDTDescriptorChoiceType> descriptors = edtChoiceType.getDescriptors();
|
||||
|
||||
//Metadata documents can contain multiple Descriptors (See ADFS metadata documents) such as RoleDescriptor, SPSSODescriptor, IDPSSODescriptor.
|
||||
//So we need to loop through to find the IDPSSODescriptor.
|
||||
for(EntityDescriptorType.EDTChoiceType edtChoiceType : entityType.getChoiceType()) {
|
||||
List<EntityDescriptorType.EDTDescriptorChoiceType> descriptors = edtChoiceType.getDescriptors();
|
||||
if (!descriptors.isEmpty()) {
|
||||
EntityDescriptorType.EDTDescriptorChoiceType edtDescriptorChoiceType = descriptors.get(0);
|
||||
IDPSSODescriptorType idpDescriptor = edtDescriptorChoiceType.getIdpDescriptor();
|
||||
|
||||
if(!descriptors.isEmpty() && descriptors.get(0).getIdpDescriptor() != null) {
|
||||
idpDescriptor = descriptors.get(0).getIdpDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
if (idpDescriptor != null) {
|
||||
SAMLIdentityProviderConfig samlIdentityProviderConfig = new SAMLIdentityProviderConfig();
|
||||
String singleSignOnServiceUrl = null;
|
||||
boolean postBinding = false;
|
||||
for (EndpointType endpoint : idpDescriptor.getSingleSignOnService()) {
|
||||
if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) {
|
||||
singleSignOnServiceUrl = endpoint.getLocation().toString();
|
||||
postBinding = true;
|
||||
break;
|
||||
} else if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){
|
||||
singleSignOnServiceUrl = endpoint.getLocation().toString();
|
||||
}
|
||||
}
|
||||
String singleLogoutServiceUrl = null;
|
||||
for (EndpointType endpoint : idpDescriptor.getSingleLogoutService()) {
|
||||
if (postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) {
|
||||
singleLogoutServiceUrl = endpoint.getLocation().toString();
|
||||
break;
|
||||
} else if (!postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){
|
||||
singleLogoutServiceUrl = endpoint.getLocation().toString();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
samlIdentityProviderConfig.setSingleLogoutServiceUrl(singleLogoutServiceUrl);
|
||||
samlIdentityProviderConfig.setSingleSignOnServiceUrl(singleSignOnServiceUrl);
|
||||
samlIdentityProviderConfig.setWantAuthnRequestsSigned(idpDescriptor.isWantAuthnRequestsSigned());
|
||||
samlIdentityProviderConfig.setValidateSignature(idpDescriptor.isWantAuthnRequestsSigned());
|
||||
samlIdentityProviderConfig.setPostBindingResponse(postBinding);
|
||||
samlIdentityProviderConfig.setPostBindingAuthnRequest(postBinding);
|
||||
|
||||
List<KeyDescriptorType> keyDescriptor = idpDescriptor.getKeyDescriptor();
|
||||
String defaultCertificate = null;
|
||||
|
||||
if (keyDescriptor != null) {
|
||||
for (KeyDescriptorType keyDescriptorType : keyDescriptor) {
|
||||
Element keyInfo = keyDescriptorType.getKeyInfo();
|
||||
Element x509KeyInfo = DocumentUtil.getChildElement(keyInfo, new QName("dsig", "X509Certificate"));
|
||||
|
||||
if (KeyTypes.SIGNING.equals(keyDescriptorType.getUse())) {
|
||||
samlIdentityProviderConfig.setSigningCertificate(x509KeyInfo.getTextContent());
|
||||
} else if (KeyTypes.ENCRYPTION.equals(keyDescriptorType.getUse())) {
|
||||
samlIdentityProviderConfig.setEncryptionPublicKey(x509KeyInfo.getTextContent());
|
||||
} else if (keyDescriptorType.getUse() == null) {
|
||||
defaultCertificate = x509KeyInfo.getTextContent();
|
||||
if (idpDescriptor != null) {
|
||||
SAMLIdentityProviderConfig samlIdentityProviderConfig = new SAMLIdentityProviderConfig();
|
||||
String singleSignOnServiceUrl = null;
|
||||
boolean postBinding = false;
|
||||
for (EndpointType endpoint : idpDescriptor.getSingleSignOnService()) {
|
||||
if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) {
|
||||
singleSignOnServiceUrl = endpoint.getLocation().toString();
|
||||
postBinding = true;
|
||||
break;
|
||||
} else if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){
|
||||
singleSignOnServiceUrl = endpoint.getLocation().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
String singleLogoutServiceUrl = null;
|
||||
for (EndpointType endpoint : idpDescriptor.getSingleLogoutService()) {
|
||||
if (postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) {
|
||||
singleLogoutServiceUrl = endpoint.getLocation().toString();
|
||||
break;
|
||||
} else if (!postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){
|
||||
singleLogoutServiceUrl = endpoint.getLocation().toString();
|
||||
break;
|
||||
}
|
||||
|
||||
if (defaultCertificate != null) {
|
||||
if (samlIdentityProviderConfig.getSigningCertificate() == null) {
|
||||
samlIdentityProviderConfig.setSigningCertificate(defaultCertificate);
|
||||
}
|
||||
samlIdentityProviderConfig.setSingleLogoutServiceUrl(singleLogoutServiceUrl);
|
||||
samlIdentityProviderConfig.setSingleSignOnServiceUrl(singleSignOnServiceUrl);
|
||||
samlIdentityProviderConfig.setWantAuthnRequestsSigned(idpDescriptor.isWantAuthnRequestsSigned());
|
||||
samlIdentityProviderConfig.setValidateSignature(idpDescriptor.isWantAuthnRequestsSigned());
|
||||
samlIdentityProviderConfig.setPostBindingResponse(postBinding);
|
||||
samlIdentityProviderConfig.setPostBindingAuthnRequest(postBinding);
|
||||
|
||||
List<KeyDescriptorType> keyDescriptor = idpDescriptor.getKeyDescriptor();
|
||||
String defaultCertificate = null;
|
||||
|
||||
if (keyDescriptor != null) {
|
||||
for (KeyDescriptorType keyDescriptorType : keyDescriptor) {
|
||||
Element keyInfo = keyDescriptorType.getKeyInfo();
|
||||
Element x509KeyInfo = DocumentUtil.getChildElement(keyInfo, new QName("dsig", "X509Certificate"));
|
||||
|
||||
if (KeyTypes.SIGNING.equals(keyDescriptorType.getUse())) {
|
||||
samlIdentityProviderConfig.setSigningCertificate(x509KeyInfo.getTextContent());
|
||||
} else if (KeyTypes.ENCRYPTION.equals(keyDescriptorType.getUse())) {
|
||||
samlIdentityProviderConfig.setEncryptionPublicKey(x509KeyInfo.getTextContent());
|
||||
} else if (keyDescriptorType.getUse() == null) {
|
||||
defaultCertificate = x509KeyInfo.getTextContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (samlIdentityProviderConfig.getEncryptionPublicKey() == null) {
|
||||
samlIdentityProviderConfig.setEncryptionPublicKey(defaultCertificate);
|
||||
}
|
||||
}
|
||||
if (defaultCertificate != null) {
|
||||
if (samlIdentityProviderConfig.getSigningCertificate() == null) {
|
||||
samlIdentityProviderConfig.setSigningCertificate(defaultCertificate);
|
||||
}
|
||||
|
||||
return samlIdentityProviderConfig.getConfig();
|
||||
if (samlIdentityProviderConfig.getEncryptionPublicKey() == null) {
|
||||
samlIdentityProviderConfig.setEncryptionPublicKey(defaultCertificate);
|
||||
}
|
||||
}
|
||||
|
||||
return samlIdentityProviderConfig.getConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ParsingException pe) {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-client-api</artifactId>
|
||||
<name>Keycloak Client API</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,275 +0,0 @@
|
||||
package org.keycloak.client.registration;
|
||||
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.common.util.Base64;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class ClientRegistration {
|
||||
|
||||
private String clientRegistrationUrl;
|
||||
private HttpClient httpClient;
|
||||
private Auth auth;
|
||||
|
||||
public static ClientRegistrationBuilder create() {
|
||||
return new ClientRegistrationBuilder();
|
||||
}
|
||||
|
||||
private ClientRegistration() {
|
||||
}
|
||||
|
||||
public ClientRepresentation create(ClientRepresentation client) throws ClientRegistrationException {
|
||||
String content = serialize(client);
|
||||
InputStream resultStream = doPost(content);
|
||||
return deserialize(resultStream, ClientRepresentation.class);
|
||||
}
|
||||
|
||||
public ClientRepresentation get() throws ClientRegistrationException {
|
||||
if (auth instanceof ClientIdSecretAuth) {
|
||||
String clientId = ((ClientIdSecretAuth) auth).clientId;
|
||||
return get(clientId);
|
||||
} else {
|
||||
throw new ClientRegistrationException("Requires client authentication");
|
||||
}
|
||||
}
|
||||
|
||||
public ClientRepresentation get(String clientId) throws ClientRegistrationException {
|
||||
InputStream resultStream = doGet(clientId);
|
||||
return resultStream != null ? deserialize(resultStream, ClientRepresentation.class) : null;
|
||||
}
|
||||
|
||||
public void update(ClientRepresentation client) throws ClientRegistrationException {
|
||||
String content = serialize(client);
|
||||
doPut(content, client.getClientId());
|
||||
}
|
||||
|
||||
public void delete() throws ClientRegistrationException {
|
||||
if (auth instanceof ClientIdSecretAuth) {
|
||||
String clientId = ((ClientIdSecretAuth) auth).clientId;
|
||||
delete(clientId);
|
||||
} else {
|
||||
throw new ClientRegistrationException("Requires client authentication");
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(String clientId) throws ClientRegistrationException {
|
||||
doDelete(clientId);
|
||||
}
|
||||
|
||||
public void close() throws ClientRegistrationException {
|
||||
if (httpClient instanceof CloseableHttpClient) {
|
||||
try {
|
||||
((CloseableHttpClient) httpClient).close();
|
||||
} catch (IOException e) {
|
||||
throw new ClientRegistrationException("Failed to close http client", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream doPost(String content) throws ClientRegistrationException {
|
||||
try {
|
||||
HttpPost request = new HttpPost(clientRegistrationUrl);
|
||||
|
||||
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
|
||||
request.setHeader(HttpHeaders.ACCEPT, "application/json");
|
||||
request.setEntity(new StringEntity(content));
|
||||
|
||||
auth.addAuth(request);
|
||||
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
InputStream responseStream = null;
|
||||
if (response.getEntity() != null) {
|
||||
responseStream = response.getEntity().getContent();
|
||||
}
|
||||
|
||||
if (response.getStatusLine().getStatusCode() == 201) {
|
||||
return responseStream;
|
||||
} else {
|
||||
responseStream.close();
|
||||
throw new HttpErrorException(response.getStatusLine());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ClientRegistrationException("Failed to send request", e);
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream doGet(String endpoint) throws ClientRegistrationException {
|
||||
try {
|
||||
HttpGet request = new HttpGet(clientRegistrationUrl + "/" + endpoint);
|
||||
|
||||
request.setHeader(HttpHeaders.ACCEPT, "application/json");
|
||||
|
||||
auth.addAuth(request);
|
||||
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
InputStream responseStream = null;
|
||||
if (response.getEntity() != null) {
|
||||
responseStream = response.getEntity().getContent();
|
||||
}
|
||||
|
||||
if (response.getStatusLine().getStatusCode() == 200) {
|
||||
return responseStream;
|
||||
} else if (response.getStatusLine().getStatusCode() == 404) {
|
||||
responseStream.close();
|
||||
return null;
|
||||
} else {
|
||||
responseStream.close();
|
||||
throw new HttpErrorException(response.getStatusLine());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ClientRegistrationException("Failed to send request", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void doPut(String content, String endpoint) throws ClientRegistrationException {
|
||||
try {
|
||||
HttpPut request = new HttpPut(clientRegistrationUrl + "/" + endpoint);
|
||||
|
||||
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
|
||||
request.setHeader(HttpHeaders.ACCEPT, "application/json");
|
||||
request.setEntity(new StringEntity(content));
|
||||
|
||||
auth.addAuth(request);
|
||||
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
if (response.getEntity() != null) {
|
||||
response.getEntity().getContent().close();
|
||||
}
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new HttpErrorException(response.getStatusLine());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ClientRegistrationException("Failed to send request", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void doDelete(String endpoint) throws ClientRegistrationException {
|
||||
try {
|
||||
HttpDelete request = new HttpDelete(clientRegistrationUrl + "/" + endpoint);
|
||||
|
||||
auth.addAuth(request);
|
||||
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
if (response.getEntity() != null) {
|
||||
response.getEntity().getContent().close();
|
||||
}
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new HttpErrorException(response.getStatusLine());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ClientRegistrationException("Failed to send request", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String serialize(ClientRepresentation client) throws ClientRegistrationException {
|
||||
try {
|
||||
return JsonSerialization.writeValueAsString(client);
|
||||
} catch (IOException e) {
|
||||
throw new ClientRegistrationException("Failed to write json object", e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T deserialize(InputStream inputStream, Class<T> clazz) throws ClientRegistrationException {
|
||||
try {
|
||||
return JsonSerialization.readValue(inputStream, clazz);
|
||||
} catch (IOException e) {
|
||||
throw new ClientRegistrationException("Failed to read json object", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClientRegistrationBuilder {
|
||||
|
||||
private String realm;
|
||||
|
||||
private String authServerUrl;
|
||||
|
||||
private Auth auth;
|
||||
|
||||
private HttpClient httpClient;
|
||||
|
||||
public ClientRegistrationBuilder realm(String realm) {
|
||||
this.realm = realm;
|
||||
return this;
|
||||
}
|
||||
public ClientRegistrationBuilder authServerUrl(String authServerUrl) {
|
||||
this.authServerUrl = authServerUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientRegistrationBuilder auth(String token) {
|
||||
this.auth = new TokenAuth(token);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientRegistrationBuilder auth(String clientId, String clientSecret) {
|
||||
this.auth = new ClientIdSecretAuth(clientId, clientSecret);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientRegistrationBuilder httpClient(HttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientRegistration build() {
|
||||
ClientRegistration clientRegistration = new ClientRegistration();
|
||||
clientRegistration.clientRegistrationUrl = authServerUrl + "/realms/" + realm + "/client-registration/default";
|
||||
|
||||
clientRegistration.httpClient = httpClient != null ? httpClient : HttpClients.createDefault();
|
||||
clientRegistration.auth = auth;
|
||||
|
||||
return clientRegistration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface Auth {
|
||||
void addAuth(HttpRequest httpRequest);
|
||||
}
|
||||
|
||||
public static class AuthorizationHeaderAuth implements Auth {
|
||||
private String credentials;
|
||||
|
||||
public AuthorizationHeaderAuth(String credentials) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public void addAuth(HttpRequest httpRequest) {
|
||||
httpRequest.setHeader(HttpHeaders.AUTHORIZATION, credentials);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TokenAuth extends AuthorizationHeaderAuth {
|
||||
public TokenAuth(String token) {
|
||||
super("Bearer " + token);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClientIdSecretAuth extends AuthorizationHeaderAuth {
|
||||
private String clientId;
|
||||
|
||||
public ClientIdSecretAuth(String clientId, String clientSecret) {
|
||||
super("Basic " + Base64.encodeBytes((clientId + ":" + clientSecret).getBytes()));
|
||||
this.clientId = clientId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package org.keycloak.client.registration;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class ClientRegistrationException extends Exception {
|
||||
|
||||
public ClientRegistrationException(String s, Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
|
||||
public ClientRegistrationException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.keycloak.client.registration;
|
||||
|
||||
import org.apache.http.StatusLine;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class HttpErrorException extends IOException {
|
||||
|
||||
private StatusLine statusLine;
|
||||
|
||||
public HttpErrorException(StatusLine statusLine) {
|
||||
this.statusLine = statusLine;
|
||||
}
|
||||
|
||||
public StatusLine getStatusLine() {
|
||||
return statusLine;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-common</artifactId>
|
||||
<name>Keycloak Common</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Common library and dependencies shared with server and all adapters</description>
|
||||
|
||||
<properties>
|
||||
<timestamp>${maven.build.timestamp}</timestamp>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
|
||||
<keycloak.osgi.export>
|
||||
org.keycloak.common.*
|
||||
</keycloak.osgi.export>
|
||||
<keycloak.osgi.import>
|
||||
*;resolution:=optional
|
||||
</keycloak.osgi.import>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Adding OSGI metadata to the JAR without changing the packaging type. -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-ClassPath>.</Bundle-ClassPath>
|
||||
<Bundle-Name>${project.name}</Bundle-Name>
|
||||
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
|
||||
<Import-Package>${keycloak.osgi.import}</Import-Package>
|
||||
<Export-Package>${keycloak.osgi.export}</Export-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -1,37 +0,0 @@
|
||||
package org.keycloak.common;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class Version {
|
||||
public static final String UNKNOWN = "UNKNOWN";
|
||||
public static String VERSION;
|
||||
public static String RESOURCES_VERSION;
|
||||
public static String BUILD_TIME;
|
||||
|
||||
static {
|
||||
Properties props = new Properties();
|
||||
InputStream is = Version.class.getResourceAsStream("/keycloak-version.properties");
|
||||
try {
|
||||
props.load(is);
|
||||
Version.VERSION = props.getProperty("version");
|
||||
Version.BUILD_TIME = props.getProperty("build-time");
|
||||
Version.RESOURCES_VERSION = Version.VERSION.toLowerCase();
|
||||
if (Version.RESOURCES_VERSION.endsWith("-snapshot")) {
|
||||
Version.RESOURCES_VERSION = Version.RESOURCES_VERSION.replace("-snapshot", "-" + Time.currentTime());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Version.VERSION= Version.UNKNOWN;
|
||||
Version.BUILD_TIME= Version.UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,2 +0,0 @@
|
||||
version=${product.version}
|
||||
build-time=${product.build-time}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ import org.jboss.logging.Logger;
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.common.util.EnvUtil;
|
||||
import org.keycloak.common.util.KeystoreUtil;
|
||||
import org.keycloak.util.EnvUtil;
|
||||
import org.keycloak.util.KeystoreUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -27,6 +27,5 @@
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
-13
@@ -66,19 +66,6 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
|
||||
} else {
|
||||
initEmbedded();
|
||||
}
|
||||
|
||||
// Backwards compatibility
|
||||
if (cacheManager.getCacheConfiguration(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME) == null) {
|
||||
logger.warnf("No configuration provided for '%s' cache. Using '%s' configuration as template",
|
||||
InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME, InfinispanConnectionProvider.SESSION_CACHE_NAME);
|
||||
|
||||
Configuration sessionCacheConfig = cacheManager.getCacheConfiguration(InfinispanConnectionProvider.SESSION_CACHE_NAME);
|
||||
if (sessionCacheConfig != null) {
|
||||
ConfigurationBuilder confBuilder = new ConfigurationBuilder().read(sessionCacheConfig);
|
||||
Configuration offlineSessionConfig = confBuilder.build();
|
||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME, offlineSessionConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -11,7 +11,6 @@ public interface InfinispanConnectionProvider extends Provider {
|
||||
static final String REALM_CACHE_NAME = "realms";
|
||||
static final String USER_CACHE_NAME = "users";
|
||||
static final String SESSION_CACHE_NAME = "sessions";
|
||||
static final String OFFLINE_SESSION_CACHE_NAME = "offlineSessions";
|
||||
static final String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
|
||||
|
||||
<K, V> Cache<K, V> getCache(String name);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
<changeSet author="mposolda@redhat.com" id="1.6.0">
|
||||
|
||||
<addColumn tableName="REALM">
|
||||
<column name="OFFLINE_SESSION_IDLE_TIMEOUT" type="INT" defaultValueNumeric="0"/>
|
||||
<column name="REVOKE_REFRESH_TOKEN" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
|
||||
<addColumn tableName="KEYCLOAK_ROLE">
|
||||
<column name="SCOPE_PARAM_REQUIRED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
|
||||
<addColumn tableName="CLIENT">
|
||||
<column name="ROOT_URL" type="VARCHAR(255)"/>
|
||||
<column name="DESCRIPTION" type="VARCHAR(255)"/>
|
||||
</addColumn>
|
||||
|
||||
<createTable tableName="OFFLINE_USER_SESSION">
|
||||
<column name="USER_SESSION_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="USER_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="LAST_SESSION_REFRESH" type="INT"/>
|
||||
<column name="OFFLINE" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="DATA" type="CLOB"/>
|
||||
</createTable>
|
||||
|
||||
<createTable tableName="OFFLINE_CLIENT_SESSION">
|
||||
<column name="CLIENT_SESSION_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="USER_SESSION_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="OFFLINE" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="TIMESTAMP" type="INT"/>
|
||||
<column name="DATA" type="CLOB"/>
|
||||
</createTable>
|
||||
|
||||
<addPrimaryKey columnNames="USER_SESSION_ID, OFFLINE" constraintName="CONSTRAINT_OFFLINE_US_SES_PK" tableName="OFFLINE_USER_SESSION"/>
|
||||
<addPrimaryKey columnNames="CLIENT_SESSION_ID, OFFLINE" constraintName="CONSTRAINT_OFFLINE_CL_SES_PK" tableName="OFFLINE_CLIENT_SESSION"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -9,5 +9,4 @@
|
||||
<include file="META-INF/jpa-changelog-1.3.0.xml"/>
|
||||
<include file="META-INF/jpa-changelog-1.4.0.xml"/>
|
||||
<include file="META-INF/jpa-changelog-1.5.0.xml"/>
|
||||
<include file="META-INF/jpa-changelog-1.6.0.xml"/>
|
||||
</databaseChangeLog>
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -24,7 +24,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
|
||||
<artifactId>hibernate-jpa-2.1-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ public interface JpaUpdaterProvider extends Provider {
|
||||
|
||||
public String FIRST_VERSION = "1.0.0.Final";
|
||||
|
||||
public String LAST_VERSION = "1.6.0";
|
||||
public String LAST_VERSION = "1.5.0";
|
||||
|
||||
public String getCurrentVersionSql(String defaultSchema);
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
<class>org.keycloak.models.jpa.entities.AuthenticationExecutionEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.AuthenticatorConfigEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RequiredActionProviderEntity</class>
|
||||
<class>org.keycloak.models.jpa.session.PersistentUserSessionEntity</class>
|
||||
<class>org.keycloak.models.jpa.session.PersistentClientSessionEntity</class>
|
||||
|
||||
<!-- JpaAuditProviders -->
|
||||
<class>org.keycloak.events.jpa.EventEntity</class>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+19
-48
@@ -3,7 +3,6 @@ package org.keycloak.connections.mongo;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoClientOptions;
|
||||
import com.mongodb.MongoClientURI;
|
||||
import com.mongodb.MongoCredential;
|
||||
import com.mongodb.ServerAddress;
|
||||
|
||||
@@ -36,8 +35,6 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoClientEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoMigrationModelEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoOnlineUserSessionEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoOfflineUserSessionEntity",
|
||||
"org.keycloak.models.entities.IdentityProviderEntity",
|
||||
"org.keycloak.models.entities.ClientIdentityProviderMappingEntity",
|
||||
"org.keycloak.models.entities.RequiredCredentialEntity",
|
||||
@@ -51,8 +48,6 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||
"org.keycloak.models.entities.AuthenticationFlowEntity",
|
||||
"org.keycloak.models.entities.AuthenticatorConfigEntity",
|
||||
"org.keycloak.models.entities.RequiredActionProviderEntity",
|
||||
"org.keycloak.models.entities.PersistentUserSessionEntity",
|
||||
"org.keycloak.models.entities.PersistentClientSessionEntity",
|
||||
};
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);
|
||||
@@ -150,55 +145,31 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||
* @throws UnknownHostException
|
||||
*/
|
||||
protected MongoClient createMongoClient() throws UnknownHostException {
|
||||
operationalInfo = new LinkedHashMap<>();
|
||||
String host = config.get("host", ServerAddress.defaultHost());
|
||||
int port = config.getInt("port", ServerAddress.defaultPort());
|
||||
String dbName = config.get("db", "keycloak");
|
||||
|
||||
String uriString = config.get("uri");
|
||||
if (uriString != null) {
|
||||
MongoClientURI uri = new MongoClientURI(uriString);
|
||||
MongoClient client = new MongoClient(uri);
|
||||
String user = config.get("user");
|
||||
String password = config.get("password");
|
||||
|
||||
StringBuilder hostsBuilder = new StringBuilder();
|
||||
for (int i=0 ; i<uri.getHosts().size() ; i++) {
|
||||
if (i!=0) {
|
||||
hostsBuilder.append(", ");
|
||||
}
|
||||
hostsBuilder.append(uri.getHosts().get(i));
|
||||
}
|
||||
String hosts = hostsBuilder.toString();
|
||||
MongoClientOptions clientOptions = getClientOptions();
|
||||
|
||||
operationalInfo.put("mongoHosts", hosts);
|
||||
operationalInfo.put("mongoDatabaseName", dbName);
|
||||
operationalInfo.put("mongoUser", uri.getUsername());
|
||||
operationalInfo.put("mongoDriverVersion", client.getVersion());
|
||||
|
||||
logger.debugv("Initialized mongo model. host(s): %s, db: %s", uri.getHosts(), dbName);
|
||||
return client;
|
||||
MongoClient client;
|
||||
if (user != null && password != null) {
|
||||
MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
|
||||
client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
|
||||
} else {
|
||||
String host = config.get("host", ServerAddress.defaultHost());
|
||||
int port = config.getInt("port", ServerAddress.defaultPort());
|
||||
|
||||
String user = config.get("user");
|
||||
String password = config.get("password");
|
||||
|
||||
MongoClientOptions clientOptions = getClientOptions();
|
||||
|
||||
MongoClient client;
|
||||
if (user != null && password != null) {
|
||||
MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
|
||||
client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
|
||||
} else {
|
||||
client = new MongoClient(new ServerAddress(host, port), clientOptions);
|
||||
}
|
||||
|
||||
operationalInfo.put("mongoServerAddress", client.getAddress().toString());
|
||||
operationalInfo.put("mongoDatabaseName", dbName);
|
||||
operationalInfo.put("mongoUser", user);
|
||||
operationalInfo.put("mongoDriverVersion", client.getVersion());
|
||||
|
||||
logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
|
||||
return client;
|
||||
client = new MongoClient(new ServerAddress(host, port), clientOptions);
|
||||
}
|
||||
|
||||
operationalInfo = new LinkedHashMap<>();
|
||||
operationalInfo.put("mongoServerAddress", client.getAddress().toString());
|
||||
operationalInfo.put("mongoDatabaseName", dbName);
|
||||
operationalInfo.put("mongoUser", user);
|
||||
operationalInfo.put("mongoDriverVersion", client.getVersion());
|
||||
|
||||
logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
|
||||
return client;
|
||||
}
|
||||
|
||||
protected MongoClientOptions getClientOptions() {
|
||||
|
||||
+2
-1
@@ -9,10 +9,11 @@ import org.keycloak.connections.mongo.api.types.MapperRegistry;
|
||||
import org.keycloak.connections.mongo.impl.EntityInfo;
|
||||
import org.keycloak.connections.mongo.impl.MongoStoreImpl;
|
||||
import org.keycloak.models.utils.reflection.Property;
|
||||
import org.keycloak.common.util.reflections.Types;
|
||||
import org.keycloak.util.reflections.Types;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
</parent>
|
||||
<name>Connections Parent</name>
|
||||
<description/>
|
||||
|
||||
@@ -4,45 +4,46 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-undertow-adapter-spi</artifactId>
|
||||
<name>Keycloak Undertow Integration</name>
|
||||
<artifactId>keycloak-core-jaxrs</artifactId>
|
||||
<name>Keycloak Core JAX-RS</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<version>${jboss.logging.version}</version>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jaxrs</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-spi</artifactId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-common</artifactId>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jackson-provider</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-servlet</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
+10
-4
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.services.util;
|
||||
package org.keycloak;
|
||||
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.map.SerializationConfig;
|
||||
@@ -14,18 +14,24 @@ import javax.ws.rs.ext.Provider;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Provider
|
||||
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {
|
||||
public class SkeletonKeyContextResolver implements ContextResolver<ObjectMapper> {
|
||||
protected ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public ObjectMapperResolver(boolean indent) {
|
||||
public SkeletonKeyContextResolver() {
|
||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
|
||||
}
|
||||
|
||||
public SkeletonKeyContextResolver(boolean indent) {
|
||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
|
||||
if (indent) {
|
||||
mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ObjectMapper getContext(Class<?> type) {
|
||||
return mapper;
|
||||
if (type.getPackage() != null && type.getPackage().getName().startsWith(getClass().getPackage().getName())) return mapper;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.6.0.Final</version>
|
||||
<version>1.5.0.Final</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -21,29 +21,35 @@
|
||||
org.keycloak.*
|
||||
</keycloak.osgi.export>
|
||||
<keycloak.osgi.import>
|
||||
net.iharder;version=${base64.version},
|
||||
*;resolution:=optional
|
||||
</keycloak.osgi.import>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
<artifactId>base64</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.keycloak;
|
||||
|
||||
import org.keycloak.common.enums.RelativeUrlsUsed;
|
||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||
import org.keycloak.enums.RelativeUrlsUsed;
|
||||
import org.keycloak.util.KeycloakUriBuilder;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common;
|
||||
package org.keycloak;
|
||||
|
||||
/**
|
||||
* Information about the client connection
|
||||
@@ -2,7 +2,7 @@ package org.keycloak;
|
||||
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.IDToken;
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.util.Base64Url;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -38,12 +38,6 @@ public interface OAuth2Constants {
|
||||
// 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";
|
||||
|
||||
// http://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
||||
String OFFLINE_ACCESS = "offline_access";
|
||||
|
||||
String UI_LOCALES_PARAM = "ui_locales";
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package org.keycloak;
|
||||
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PublicKey;
|
||||
@@ -15,10 +13,10 @@ import java.security.PublicKey;
|
||||
*/
|
||||
public class RSATokenVerifier {
|
||||
public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realmUrl) throws VerificationException {
|
||||
return verifyToken(tokenString, realmKey, realmUrl, true, true);
|
||||
return verifyToken(tokenString, realmKey, realmUrl, true);
|
||||
}
|
||||
|
||||
public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realmUrl, boolean checkActive, boolean checkTokenType) throws VerificationException {
|
||||
public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realmUrl, boolean checkActive) throws VerificationException {
|
||||
JWSInput input = null;
|
||||
try {
|
||||
input = new JWSInput(tokenString);
|
||||
@@ -44,13 +42,6 @@ public class RSATokenVerifier {
|
||||
throw new VerificationException("Token audience doesn't match domain. Token issuer is " + token.getIssuer() + ", but URL from configuration is " + realmUrl);
|
||||
|
||||
}
|
||||
|
||||
if (checkTokenType) {
|
||||
String type = token.getType();
|
||||
if (type == null || !type.equalsIgnoreCase(TokenUtil.TOKEN_TYPE_BEARER)) {
|
||||
throw new VerificationException("Token type is incorrect. Expected '" + TokenUtil.TOKEN_TYPE_BEARER + "' but was '" + type + "'");
|
||||
}
|
||||
}
|
||||
if (checkActive && !token.isActive()) {
|
||||
throw new VerificationException("Token is not active.");
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common;
|
||||
package org.keycloak;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
package org.keycloak;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
import org.keycloak.util.Time;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class Version {
|
||||
public static String VERSION;
|
||||
public static String RESOURCES_VERSION;
|
||||
public static String BUILD_TIME;
|
||||
public static final String UNKNOWN = "UNKNOWN";
|
||||
public static final Version SINGLETON;
|
||||
|
||||
private final String version = VERSION;
|
||||
private final String buildTime = BUILD_TIME;
|
||||
|
||||
static {
|
||||
Properties props = new Properties();
|
||||
InputStream is = Version.class.getResourceAsStream("/keycloak-version.properties");
|
||||
try {
|
||||
props.load(is);
|
||||
VERSION = props.getProperty("version");
|
||||
BUILD_TIME = props.getProperty("build-time");
|
||||
RESOURCES_VERSION = VERSION.toLowerCase();
|
||||
if (RESOURCES_VERSION.endsWith("-snapshot")) {
|
||||
RESOURCES_VERSION = RESOURCES_VERSION.replace("-snapshot", "-" + Time.currentTime());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
VERSION=UNKNOWN;
|
||||
BUILD_TIME=UNKNOWN;
|
||||
}
|
||||
|
||||
SINGLETON = new Version();
|
||||
}
|
||||
|
||||
@JsonProperty("version")
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@JsonProperty("build-time")
|
||||
public String getBuildTime() {
|
||||
return buildTime;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.constants;
|
||||
package org.keycloak.constants;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.constants;
|
||||
package org.keycloak.constants;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.constants;
|
||||
package org.keycloak.constants;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.enums;
|
||||
package org.keycloak.enums;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package org.keycloak.common.enums;
|
||||
package org.keycloak.enums;
|
||||
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.ClientConnection;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -1,12 +1,14 @@
|
||||
package org.keycloak.jose.jwk;
|
||||
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.util.Base64Url;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.Key;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.keycloak.jose.jwk;
|
||||
|
||||
import org.codehaus.jackson.type.TypeReference;
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.util.Base64Url;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.keycloak.jose.jws;
|
||||
|
||||
import org.keycloak.jose.jws.crypto.HMACProvider;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.util.Base64Url;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.keycloak.jose.jws;
|
||||
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.util.Base64Url;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import static org.keycloak.jose.jws.Algorithm.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.keycloak.jose.jws.crypto;
|
||||
|
||||
import org.keycloak.jose.jws.Algorithm;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.util.Base64Url;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.keycloak.jose.jws.crypto;
|
||||
|
||||
import org.keycloak.jose.jws.Algorithm;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.util.PemUtils;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.codehaus.jackson.map.annotate.JsonDeserialize;
|
||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||
import org.keycloak.json.StringOrArrayDeserializer;
|
||||
import org.keycloak.json.StringOrArraySerializer;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.util.Time;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.keycloak.representations;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.util.Time;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.keycloak.representations;
|
||||
|
||||
import org.keycloak.util.TokenUtil;
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -11,8 +11,9 @@ import java.util.Map;
|
||||
*/
|
||||
public class RefreshToken extends AccessToken {
|
||||
|
||||
|
||||
private RefreshToken() {
|
||||
type(TokenUtil.TOKEN_TYPE_REFRESH);
|
||||
type("REFRESH");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package org.keycloak.representations;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
import org.keycloak.common.Version;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class VersionRepresentation {
|
||||
public static final VersionRepresentation SINGLETON;
|
||||
|
||||
private final String version = Version.VERSION;
|
||||
private final String buildTime = Version.BUILD_TIME;
|
||||
|
||||
static {
|
||||
SINGLETON = new VersionRepresentation();
|
||||
}
|
||||
|
||||
@JsonProperty("version")
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@JsonProperty("build-time")
|
||||
public String getBuildTime() {
|
||||
return buildTime;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.util.Time;
|
||||
|
||||
/**
|
||||
* Posted to managed client from admin server.
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ import java.util.Comparator;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AuthenticationExecutionRepresentation implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String authenticatorConfig;
|
||||
private String authenticator;
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ import java.util.List;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AuthenticationFlowRepresentation implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String alias;
|
||||
private String description;
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AuthenticatorConfigRepresentation implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String alias;
|
||||
private Map<String, String> config = new HashMap<String, String>();
|
||||
|
||||
@@ -11,8 +11,6 @@ public class ClientRepresentation {
|
||||
protected String id;
|
||||
protected String clientId;
|
||||
protected String name;
|
||||
protected String description;
|
||||
protected String rootUrl;
|
||||
protected String adminUrl;
|
||||
protected String baseUrl;
|
||||
protected Boolean surrogateAuthRequired;
|
||||
@@ -52,14 +50,6 @@ public class ClientRepresentation {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
@@ -84,14 +74,6 @@ public class ClientRepresentation {
|
||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||
}
|
||||
|
||||
public String getRootUrl() {
|
||||
return rootUrl;
|
||||
}
|
||||
|
||||
public void setRootUrl(String rootUrl) {
|
||||
this.rootUrl = rootUrl;
|
||||
}
|
||||
|
||||
public String getAdminUrl() {
|
||||
return adminUrl;
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package org.keycloak.representations.idm;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.util.PemUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
@@ -10,11 +10,9 @@ public class RealmRepresentation {
|
||||
protected String id;
|
||||
protected String realm;
|
||||
protected Integer notBefore;
|
||||
protected Boolean revokeRefreshToken;
|
||||
protected Integer accessTokenLifespan;
|
||||
protected Integer ssoSessionIdleTimeout;
|
||||
protected Integer ssoSessionMaxLifespan;
|
||||
protected Integer offlineSessionIdleTimeout;
|
||||
protected Integer accessCodeLifespan;
|
||||
protected Integer accessCodeLifespanUserAction;
|
||||
protected Integer accessCodeLifespanLogin;
|
||||
@@ -168,14 +166,6 @@ public class RealmRepresentation {
|
||||
this.sslRequired = sslRequired;
|
||||
}
|
||||
|
||||
public Boolean getRevokeRefreshToken() {
|
||||
return revokeRefreshToken;
|
||||
}
|
||||
|
||||
public void setRevokeRefreshToken(Boolean revokeRefreshToken) {
|
||||
this.revokeRefreshToken = revokeRefreshToken;
|
||||
}
|
||||
|
||||
public Integer getAccessTokenLifespan() {
|
||||
return accessTokenLifespan;
|
||||
}
|
||||
@@ -200,14 +190,6 @@ public class RealmRepresentation {
|
||||
this.ssoSessionMaxLifespan = ssoSessionMaxLifespan;
|
||||
}
|
||||
|
||||
public Integer getOfflineSessionIdleTimeout() {
|
||||
return offlineSessionIdleTimeout;
|
||||
}
|
||||
|
||||
public void setOfflineSessionIdleTimeout(Integer offlineSessionIdleTimeout) {
|
||||
this.offlineSessionIdleTimeout = offlineSessionIdleTimeout;
|
||||
}
|
||||
|
||||
public List<ScopeMappingRepresentation> getScopeMappings() {
|
||||
return scopeMappings;
|
||||
}
|
||||
@@ -629,14 +611,10 @@ public class RealmRepresentation {
|
||||
}
|
||||
|
||||
public Set<String> getSupportedLocales() {
|
||||
return supportedLocales;
|
||||
}
|
||||
|
||||
public void addSupportedLocales(String locale) {
|
||||
if(supportedLocales == null){
|
||||
supportedLocales = new HashSet<>();
|
||||
supportedLocales = new HashSet<String>();
|
||||
}
|
||||
supportedLocales.add(locale);
|
||||
return supportedLocales;
|
||||
}
|
||||
|
||||
public void setSupportedLocales(Set<String> supportedLocales) {
|
||||
|
||||
@@ -12,7 +12,6 @@ public class RoleRepresentation {
|
||||
protected String id;
|
||||
protected String name;
|
||||
protected String description;
|
||||
protected Boolean scopeParamRequired;
|
||||
protected boolean composite;
|
||||
protected Composites composites;
|
||||
|
||||
@@ -47,10 +46,9 @@ public class RoleRepresentation {
|
||||
public RoleRepresentation() {
|
||||
}
|
||||
|
||||
public RoleRepresentation(String name, String description, boolean scopeParamRequired) {
|
||||
public RoleRepresentation(String name, String description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.scopeParamRequired = scopeParamRequired;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -77,14 +75,6 @@ public class RoleRepresentation {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Boolean isScopeParamRequired() {
|
||||
return scopeParamRequired;
|
||||
}
|
||||
|
||||
public void setScopeParamRequired(Boolean scopeParamRequired) {
|
||||
this.scopeParamRequired = scopeParamRequired;
|
||||
}
|
||||
|
||||
public Composites getComposites() {
|
||||
return composites;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package org.keycloak.representations.idm;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
import org.keycloak.util.MultivaluedHashMap;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
|
||||
import net.iharder.Base64;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.keycloak.util;
|
||||
|
||||
import org.keycloak.common.util.Base64;
|
||||
import net.iharder.Base64;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import org.keycloak.common.constants.GenericConstants;
|
||||
import org.keycloak.constants.GenericConstants;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
/**
|
||||
* @author pedroigor
|
||||
+4
-3
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -12,12 +12,13 @@ import java.lang.reflect.Method;
|
||||
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
|
||||
import net.iharder.Base64;
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.ietf.jgss.Oid;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.common.util.reflections.Reflections;
|
||||
import org.keycloak.constants.KerberosConstants;
|
||||
import org.keycloak.util.reflections.Reflections;
|
||||
import sun.security.jgss.GSSCredentialImpl;
|
||||
import sun.security.jgss.GSSManagerImpl;
|
||||
import sun.security.jgss.krb5.Krb5InitCredential;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -6,7 +6,7 @@ import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
|
||||
import org.keycloak.common.constants.GenericConstants;
|
||||
import org.keycloak.constants.GenericConstants;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import javax.activation.MimetypesFileTypeMap;
|
||||
import java.io.File;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
|
||||
import net.iharder.Base64;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.DateFormat;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||
*/
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
@@ -3,14 +3,13 @@ package org.keycloak.util;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.io.IOContext;
|
||||
import org.codehaus.jackson.map.MappingJsonFactory;
|
||||
import org.codehaus.jackson.util.JsonParserDelegate;
|
||||
import org.keycloak.common.util.StringPropertyReplacer;
|
||||
import org.keycloak.common.util.SystemEnvProperties;
|
||||
|
||||
/**
|
||||
* Provides replacing of system properties for parsed values
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.representations.RefreshToken;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class TokenUtil {
|
||||
|
||||
public static final String TOKEN_TYPE_BEARER = "Bearer";
|
||||
|
||||
public static final String TOKEN_TYPE_ID = "ID";
|
||||
|
||||
public static final String TOKEN_TYPE_REFRESH = "Refresh";
|
||||
|
||||
public static final String TOKEN_TYPE_OFFLINE = "Offline";
|
||||
|
||||
public static boolean isOfflineTokenRequested(String scopeParam) {
|
||||
if (scopeParam == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] scopes = scopeParam.split(" ");
|
||||
for (String scope : scopes) {
|
||||
if (OAuth2Constants.OFFLINE_ACCESS.equals(scope)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return refresh token or offline token
|
||||
*
|
||||
* @param decodedToken
|
||||
* @return
|
||||
*/
|
||||
public static RefreshToken getRefreshToken(byte[] decodedToken) throws IOException {
|
||||
return JsonSerialization.readValue(decodedToken, RefreshToken.class);
|
||||
}
|
||||
|
||||
public static RefreshToken getRefreshToken(String refreshToken) throws IOException {
|
||||
byte[] encodedContent = new JWSInput(refreshToken).getContent();
|
||||
return getRefreshToken(encodedContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if given refreshToken represents offline token
|
||||
*
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
public static boolean isOfflineToken(String refreshToken) {
|
||||
try {
|
||||
RefreshToken token = getRefreshToken(refreshToken);
|
||||
return token.getType().equals(TOKEN_TYPE_OFFLINE);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util;
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util.reflections;
|
||||
package org.keycloak.util.reflections;
|
||||
|
||||
import java.beans.Introspector;
|
||||
import java.io.Serializable;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util.reflections;
|
||||
package org.keycloak.util.reflections;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.security.PrivilegedAction;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.common.util.reflections;
|
||||
package org.keycloak.util.reflections;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
Loaded 100 of 2589 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user