use of org.opensaml.saml.common.SignableSAMLObject in project cas by apereo.
the class AbstractSamlProfileHandlerController method decodeSamlContextFromHttpRequest.
/**
* Decode authentication request saml object.
*
* @param request the request
* @param decoder the decoder
* @param clazz the clazz
* @return the saml object
*/
protected Pair<? extends SignableSAMLObject, MessageContext> decodeSamlContextFromHttpRequest(final HttpServletRequest request, final BaseHttpServletRequestXMLMessageDecoder decoder, final Class<? extends SignableSAMLObject> clazz) {
LOGGER.info("Received SAML profile request [{}]", request.getRequestURI());
try {
decoder.setHttpServletRequest(request);
decoder.setParserPool(this.parserPool);
decoder.initialize();
decoder.decode();
final MessageContext messageContext = decoder.getMessageContext();
final SignableSAMLObject object = (SignableSAMLObject) messageContext.getMessage();
if (object == null) {
throw new SAMLException("No " + clazz.getName() + " could be found in this request context. Decoder has failed.");
}
if (!clazz.isAssignableFrom(object.getClass())) {
throw new ClassCastException("SAML object [" + object.getClass().getName() + " type does not match " + clazz);
}
LOGGER.debug("Decoded SAML object [{}] from http request", object.getElementQName());
return Pair.of(object, messageContext);
} catch (final Exception e) {
throw Throwables.propagate(e);
}
}
use of org.opensaml.saml.common.SignableSAMLObject in project ddf by codice.
the class IdpEndpoint method continueLogout.
private Response continueLogout(LogoutState logoutState, Cookie cookie, SamlProtocol.Binding incomingBinding) throws IdpException {
if (logoutState == null) {
throw new IdpException("Cannot continue a Logout that doesn't exist!");
}
try {
SignableSAMLObject logoutObject;
String relay = "";
String entityId = "";
SamlProtocol.Type samlType;
Optional<String> nextTarget = logoutState.getNextTarget();
if (nextTarget.isPresent()) {
// Another target exists, log them out
entityId = nextTarget.get();
if (logoutState.getOriginalIssuer().equals(entityId)) {
return continueLogout(logoutState, cookie, incomingBinding);
}
LogoutRequest logoutRequest = logoutMessage.buildLogoutRequest(logoutState.getNameId(), SystemBaseUrl.constructUrl("/idp/logout", true));
logoutState.setCurrentRequestId(logoutRequest.getID());
logoutObject = logoutRequest;
samlType = SamlProtocol.Type.REQUEST;
relay = "";
} else {
// No more targets, respond to original issuer
entityId = logoutState.getOriginalIssuer();
String status = logoutState.isPartialLogout() ? StatusCode.PARTIAL_LOGOUT : StatusCode.SUCCESS;
logoutObject = logoutMessage.buildLogoutResponse(SystemBaseUrl.constructUrl("/idp/logout", true), status, logoutState.getOriginalRequestId());
relay = logoutState.getInitialRelayState();
LogoutState decode = logoutStates.decode(cookie.getValue(), true);
samlType = SamlProtocol.Type.RESPONSE;
}
LOGGER.debug("Responding to [{}] with a [{}] and relay state [{}]", entityId, samlType, relay);
EntityInformation.ServiceInfo entityServiceInfo = serviceProviders.get(entityId).getLogoutService(incomingBinding);
if (entityServiceInfo == null) {
LOGGER.info("Could not find entity service info for {}", entityId);
return continueLogout(logoutState, cookie, incomingBinding);
}
switch(entityServiceInfo.getBinding()) {
case HTTP_REDIRECT:
return getSamlRedirectResponse(logoutObject, entityServiceInfo.getUrl(), relay, samlType);
case HTTP_POST:
return getSamlPostResponse(logoutObject, entityServiceInfo.getUrl(), relay, samlType);
default:
LOGGER.debug("No supported binding available for SP [{}].", entityId);
logoutState.setPartialLogout(true);
return continueLogout(logoutState, cookie, incomingBinding);
}
} catch (WSSecurityException | SimpleSign.SignatureException | IOException e) {
LOGGER.debug("Error while processing logout", e);
}
throw new IdpException("Server error while processing logout");
}
use of org.opensaml.saml.common.SignableSAMLObject in project cas by apereo.
the class IdPInitiatedProfileHandlerController method handleIdPInitiatedSsoRequest.
/**
* Handle idp initiated sso requests.
*
* @param response the response
* @param request the request
* @throws Exception the exception
*/
@GetMapping(path = SamlIdPConstants.ENDPOINT_SAML2_IDP_INIT_PROFILE_SSO)
protected void handleIdPInitiatedSsoRequest(final HttpServletResponse response, final HttpServletRequest request) throws Exception {
// The name (i.e., the entity ID) of the service provider.
final String providerId = CommonUtils.safeGetParameter(request, SamlIdPConstants.PROVIDER_ID);
if (StringUtils.isBlank(providerId)) {
LOGGER.warn("No providerId parameter given in unsolicited SSO authentication request.");
throw new MessageDecodingException("No providerId parameter given in unsolicited SSO authentication request.");
}
final SamlRegisteredService registeredService = verifySamlRegisteredService(providerId);
final Optional<SamlRegisteredServiceServiceProviderMetadataFacade> adaptor = getSamlMetadataFacadeFor(registeredService, providerId);
if (!adaptor.isPresent()) {
throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, "Cannot find metadata linked to " + providerId);
}
// The URL of the response location at the SP (called the "Assertion Consumer Service")
// but can be omitted in favor of the IdP picking the default endpoint location from metadata.
String shire = CommonUtils.safeGetParameter(request, SamlIdPConstants.SHIRE);
final SamlRegisteredServiceServiceProviderMetadataFacade facade = adaptor.get();
if (StringUtils.isBlank(shire)) {
LOGGER.warn("Resolving service provider assertion consumer service URL for [{}] and binding [{}]", providerId, SAMLConstants.SAML2_POST_BINDING_URI);
@NonNull final AssertionConsumerService acs = facade.getAssertionConsumerService(SAMLConstants.SAML2_POST_BINDING_URI);
shire = acs.getLocation();
}
if (StringUtils.isBlank(shire)) {
LOGGER.warn("Unable to resolve service provider assertion consumer service URL for AuthnRequest construction for entityID: [{}]", providerId);
throw new MessageDecodingException("Unable to resolve SP ACS URL for AuthnRequest construction");
}
// The target resource at the SP, or a state token generated by an SP to represent the resource.
final String target = CommonUtils.safeGetParameter(request, SamlIdPConstants.TARGET);
// A timestamp to help with stale request detection.
final String time = CommonUtils.safeGetParameter(request, SamlIdPConstants.TIME);
final SAMLObjectBuilder builder = (SAMLObjectBuilder) configBean.getBuilderFactory().getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
final AuthnRequest authnRequest = (AuthnRequest) builder.buildObject();
authnRequest.setAssertionConsumerServiceURL(shire);
final SAMLObjectBuilder isBuilder = (SAMLObjectBuilder) configBean.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
final Issuer issuer = (Issuer) isBuilder.buildObject();
issuer.setValue(providerId);
authnRequest.setIssuer(issuer);
authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
final SAMLObjectBuilder pBuilder = (SAMLObjectBuilder) configBean.getBuilderFactory().getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
final NameIDPolicy nameIDPolicy = (NameIDPolicy) pBuilder.buildObject();
nameIDPolicy.setAllowCreate(Boolean.TRUE);
authnRequest.setNameIDPolicy(nameIDPolicy);
if (NumberUtils.isCreatable(time)) {
authnRequest.setIssueInstant(new DateTime(TimeUnit.SECONDS.convert(Long.parseLong(time), TimeUnit.MILLISECONDS), ISOChronology.getInstanceUTC()));
} else {
authnRequest.setIssueInstant(new DateTime(DateTime.now(), ISOChronology.getInstanceUTC()));
}
authnRequest.setForceAuthn(Boolean.FALSE);
if (StringUtils.isNotBlank(target)) {
request.setAttribute(SamlProtocolConstants.PARAMETER_SAML_RELAY_STATE, target);
}
final MessageContext ctx = new MessageContext();
ctx.setAutoCreateSubcontexts(true);
if (facade.isAuthnRequestsSigned()) {
samlObjectSigner.encode(authnRequest, registeredService, facade, response, request, SAMLConstants.SAML2_POST_BINDING_URI);
}
ctx.setMessage(authnRequest);
ctx.getSubcontext(SAMLBindingContext.class, true).setHasBindingSignature(false);
final Pair<SignableSAMLObject, MessageContext> pair = Pair.of(authnRequest, ctx);
initiateAuthenticationRequest(pair, response, request);
}
use of org.opensaml.saml.common.SignableSAMLObject in project cas by apereo.
the class DefaultSSOSamlHttpRequestExtractor method extract.
@Audit(action = AuditableActions.SAML2_REQUEST, actionResolverName = AuditActionResolvers.SAML2_REQUEST_ACTION_RESOLVER, resourceResolverName = AuditResourceResolvers.SAML2_REQUEST_RESOURCE_RESOLVER)
@Override
@SneakyThrows
public Optional<Pair<? extends SignableSAMLObject, MessageContext>> extract(final HttpServletRequest request, final BaseHttpServletRequestXMLMessageDecoder decoder, final Class<? extends SignableSAMLObject> clazz) {
LOGGER.trace("Received SAML profile request [{}]", request.getRequestURI());
decoder.setHttpServletRequest(request);
decoder.setParserPool(this.parserPool);
decoder.initialize();
decoder.decode();
val messageContext = decoder.getMessageContext();
LOGGER.trace("Locating SAML object from message context...");
val object = (SignableSAMLObject) messageContext.getMessage();
if (object == null) {
LOGGER.debug("SAML object cannot be determined from the decoder [{}]", decoder.getClass().getSimpleName());
return Optional.empty();
}
if (!clazz.isAssignableFrom(object.getClass())) {
LOGGER.debug("SAML object [{}] type does not match [{}]", object.getClass().getName(), clazz);
return Optional.empty();
}
LOGGER.debug("Decoded SAML object [{}] from http request", object.getElementQName());
return Optional.of(Pair.of(object, messageContext));
}
use of org.opensaml.saml.common.SignableSAMLObject in project ddf by codice.
the class LogoutMessageImpl method sendSamlLogoutRequest.
@Override
public String sendSamlLogoutRequest(LogoutWrapper request, String targetUri, boolean isSoap, @Nullable Cookie cookie) throws IOException, LogoutSecurityException {
XMLObject xmlObject = isSoap ? SamlProtocol.createSoapMessage((SignableSAMLObject) request.getMessage()) : (XMLObject) request;
Element requestElement = getElementFromSaml(new LogoutWrapperImpl(xmlObject));
String requestMessage = DOM2Writer.nodeToString(requestElement);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost post = new HttpPost(targetUri);
post.addHeader("Cache-Control", "no-cache, no-store");
post.addHeader("Pragma", "no-cache");
post.addHeader("SOAPAction", SAML_SOAP_ACTION);
post.addHeader("Content-Type", "application/soap+xml");
post.setEntity(new StringEntity(requestMessage, "utf-8"));
ResponseHandler<String> responseHandler = new BasicResponseHandler();
BasicHttpContext context = new BasicHttpContext();
if (cookie != null) {
BasicClientCookie basicClientCookie = new BasicClientCookie(cookie.getName(), cookie.getValue());
basicClientCookie.setDomain(cookie.getDomain());
basicClientCookie.setPath(cookie.getPath());
BasicCookieStore cookieStore = new BasicCookieStore();
cookieStore.addCookie(basicClientCookie);
context.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
}
return httpClient.execute(post, responseHandler, context);
}
}
Aggregations