コード例 #1
0
        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);
        }