protected async override Task ApplyResponseGrantAsync() { var signout = this.Helper.LookupSignOut(this.Options.AuthenticationType, this.Options.AuthenticationMode); if (signout == null) { return; } try { this._logger.WriteInformation(String.Format("Applying response grand for authenticationType: {0}, authenticationMode: {1}. Path: {2}", this.Options.AuthenticationType, this.Options.AuthenticationMode, this.Request.Path)); var logoutContextBuilder = this._resolver.Resolve <ISamlLogoutContextResolver <IOwinRequest> >(); var logoutContext = logoutContextBuilder.ResolveLogoutContext(Request); var federationPartyId = logoutContext.FederationPartyId; var configurationManager = this._resolver.Resolve <IConfigurationManager <MetadataBase> >(); var configuration = await configurationManager.GetConfigurationAsync(federationPartyId, new CancellationToken()); if (configuration == null) { throw new InvalidOperationException("Cannot obtain metadata."); } var metadataType = configuration.GetType(); var handlerType = typeof(IMetadataHandler <>).MakeGenericType(metadataType); var handler = this._resolver.Resolve(handlerType) as IMetadataHandler; if (handler == null) { throw new InvalidOperationException(String.Format("Handler must implement: {0}", typeof(IMetadataHandler).Name)); } var idp = handler.GetIdentityProviderSingleSignOnDescriptor(configuration) .Single().Roles.Single(); var federationPartyContextBuilder = this._resolver.Resolve <IAssertionPartyContextBuilder>(); var federationContext = federationPartyContextBuilder.BuildContext(federationPartyId); var signoutUrl = handler.GetIdentityProviderSingleLogoutService(idp, federationContext.OutboundBinding); var requestContext = new OwinLogoutRequestContext(Context, signoutUrl, base.Request.Uri, federationContext, logoutContext); var relayStateAppenders = this._resolver.ResolveAll <IRelayStateAppender>(); foreach (var appender in relayStateAppenders) { await appender.BuildRelayState(requestContext); } SamlOutboundContext outboundContext = null; if (federationContext.OutboundBinding == new Uri(Bindings.Http_Redirect)) { outboundContext = new HttpRedirectRequestContext { BindingContext = new RequestBindingContext(requestContext), DespatchDelegate = redirectUri => { this._logger.WriteInformation(String.Format("Redirecting to:\r\n{0}", redirectUri.AbsoluteUri)); this.Response.Redirect(redirectUri.AbsoluteUri); return(Task.CompletedTask); } }; } else { outboundContext = new HttpPostRequestContext(new SAMLForm()) { BindingContext = new RequestPostBindingContext(requestContext), DespatchDelegate = (form) => { this._logger.WriteInformation(String.Format("Writing saml form to the response.")); Response.Write(form.ToString()); return(Task.CompletedTask); }, }; } var protocolContext = new SamlProtocolContext { RequestContext = outboundContext }; var protocolFactory = this._resolver.Resolve <Func <string, IProtocolHandler> >(); var protocolHanlder = protocolFactory(federationContext.OutboundBinding.AbsoluteUri); await protocolHanlder.HandleOutbound(protocolContext); } catch (Exception ex) { this._logger.WriteError("An exception has been thrown when applying challenge", ex); throw; } }
public async Task Redirect_end_to_end_test() { //ARRANGE var isValid = false; string url = String.Empty; var builders = new List <IRedirectClauseBuilder>(); var requestUri = new Uri("http://localhost:59611/"); var federationPartyContextBuilder = new FederationPartyContextBuilderMock(); var federationContex = federationPartyContextBuilder.BuildContext("local"); var spDescriptor = federationContex.MetadataContext.EntityDesriptorConfiguration.SPSSODescriptors.First(); var certContext = spDescriptor.KeyDescriptors.Where(x => x.Use == KeyUsage.Signing && x.IsDefault) .Select(x => x.CertificateContext) .First(); var supportedNameIdentifierFormats = new List <Uri> { new Uri(NameIdentifierFormats.Transient) }; var authnRequestContext = new AuthnRequestContext(requestUri, new Uri("http://localhost"), federationContex, supportedNameIdentifierFormats); authnRequestContext.RelyingState.Add("relayState", "Test state"); var xmlSerialiser = new XMLSerialiser(); var compressor = new DeflateCompressor(); var encoder = new MessageEncoding(compressor); var logger = new LogProviderMock(); var serialiser = new RequestSerialiser(xmlSerialiser, encoder, logger); RequestHelper.GetAuthnRequestBuilders = AuthnRequestBuildersFactoryMock.GetAuthnRequestBuildersFactory(); var authnBuilder = new SamlRequestBuilder(serialiser); builders.Add(authnBuilder); //request compression builder var encodingBuilder = new RequestEncoderBuilder(encoder); builders.Add(encodingBuilder); //relay state builder var jsonSerialiser = new NSJsonSerializer(new DefaultSettingsProvider()); var relayStateSerialiser = new RelaystateSerialiser(jsonSerialiser, encoder, logger) as IRelayStateSerialiser; var relayStateBuilder = new RelayStateBuilder(relayStateSerialiser); builders.Add(relayStateBuilder); //signature builder var certificateManager = new CertificateManager(logger); var signatureBuilder = new SignatureBuilder(certificateManager, logger); builders.Add(signatureBuilder); //context var outboundContext = new HttpRedirectRequestContext { BindingContext = new RequestBindingContext(authnRequestContext), DespatchDelegate = redirectUri => { url = redirectUri.GetLeftPart(UriPartial.Path); var query = redirectUri.Query.TrimStart('?'); var cert = certificateManager.GetCertificateFromContext(certContext); isValid = this.VerifySignature(query, cert, certificateManager); return(Task.CompletedTask); } }; //dispatcher var dispatcher = new RedirectRequestDispatcher(() => builders); //ACT await dispatcher.SendAsync(outboundContext); //ASSERT Assert.AreEqual(url, requestUri.AbsoluteUri); Assert.IsTrue(isValid); }