Exemple #1
0
        /// <summary>
        /// Create an authenticate request aimed for this idp.
        /// </summary>
        /// <param name="returnUrl">The return url where the browser should be sent after
        /// successful authentication.</param>
        /// <param name="authServicesUrls">Urls for AuthServices, used to populate fields
        /// in the created AuthnRequest</param>
        /// <param name="relayData">Aux data that should be preserved across the authentication</param>
        /// <returns>AuthnRequest</returns>
        public Saml2AuthenticationRequest CreateAuthenticateRequest(
            Uri returnUrl,
            AuthServicesUrls authServicesUrls,
            object relayData)
        {
            if (authServicesUrls == null)
            {
                throw new ArgumentNullException("authServicesUrls");
            }

            var authnRequest = new Saml2AuthenticationRequest()
            {
                DestinationUrl = SingleSignOnServiceUrl,
                AssertionConsumerServiceUrl = authServicesUrls.AssertionConsumerServiceUrl,
                Issuer = spOptions.EntityId,
                // For now we only support one attribute consuming service.
                AttributeConsumingServiceIndex = spOptions.AttributeConsumingServices.Any() ? 0 : (int?)null
            };

            var responseData = new StoredRequestState(EntityId, returnUrl, relayData);

            PendingAuthnRequests.Add(new Saml2Id(authnRequest.Id), responseData);

            return(authnRequest);
        }
        public void AuthServicesUrls_Ctor_AllowsNullAcs()
        {
            // AssertionConsumerServiceURL is optional in the SAML spec
            var subject = new AuthServicesUrls(null, new Uri("http://localhost/signin"));

            subject.AssertionConsumerServiceUrl.Should().Be(null);
            subject.SignInUrl.ToString().Should().Be("http://localhost/signin");
        }
        public void AuthServiecsUrls_Ctor_AcceptsFullUrls()
        {
            var acsUrl    = new Uri("http://localhost:73/MyApp/MyAcs");
            var signinUrl = new Uri("http://localhost:73/MyApp/MySignin");

            var subject = new AuthServicesUrls(acsUrl, signinUrl);

            subject.AssertionConsumerServiceUrl.ToString().Should().Be(acsUrl.ToString());
            subject.SignInUrl.ToString().Should().Be(signinUrl.ToString());
        }
        public void AuthServicesUrls_Ctor_HandlesApplicationInRoot()
        {
            var appUrl     = new Uri("http://localhost:42/");
            var modulePath = "/modulePath";

            var subject = new AuthServicesUrls(appUrl, modulePath);

            subject.AssertionConsumerServiceUrl.Should().Be(new Uri("http://localhost:42/modulePath/Acs"));
            subject.SignInUrl.Should().Be(new Uri("http://localhost:42/modulePath/SignIn"));
        }
Exemple #5
0
        public async Task AuthServicesUrls_Ctor_FromOwinHttpRequestData_PublicOrigin()
        {
            var ctx     = OwinTestHelpers.CreateOwinContext();
            var options = StubFactory.CreateOptionsPublicOrigin(new Uri("https://my.public.origin:8443/"));
            var subject = await ctx.ToHttpRequestData(null);

            var urls = new AuthServicesUrls(subject, options);

            urls.AssertionConsumerServiceUrl.ShouldBeEquivalentTo("https://my.public.origin:8443/AuthServices/Acs");
            urls.SignInUrl.ShouldBeEquivalentTo("https://my.public.origin:8443/AuthServices/SignIn");
        }
        public void AuthServicesUrls_Ctor_PerRequest_PublicOrigin()
        {
            var options = StubFactory.CreateOptionsPublicOrigin(new Uri("https://my.public.origin:8443/"));

            options.Notifications.GetPublicOrigin = (requestData) =>
            {
                return(new Uri("https://special.public.origin/"));
            };
            var urls = new AuthServicesUrls(new HttpRequestData("get", new Uri("http://servername/")), options);

            urls.AssertionConsumerServiceUrl.ShouldBeEquivalentTo("https://special.public.origin/AuthServices/Acs");
            urls.SignInUrl.ShouldBeEquivalentTo("https://special.public.origin/AuthServices/SignIn");
        }
        public void AuthServicesUrls_Ctor_EnsuresApplicationUrlEndsWithSlash()
        {
            var request = new HttpRequestData(
                "GET",
                new Uri("http://localhost:1234/Foo/Bar"),
                "/Foo",
                null,
                null,
                null);

            var options = StubFactory.CreateOptions();
            var subject = new AuthServicesUrls(request, options);

            subject.ApplicationUrl.OriginalString.Should().EndWith("/");
        }
Exemple #8
0
        public Saml2AuthenticationRequest CreateAuthenticateRequest(
            Uri returnUrl,
            AuthServicesUrls authServicesUrls,
            object relayData)
        {
            if (authServicesUrls == null)
            {
                throw new ArgumentNullException(nameof(authServicesUrls));
            }

            var authnRequest = new Saml2AuthenticationRequest()
            {
                DestinationUrl = SingleSignOnServiceUrl,
                AssertionConsumerServiceUrl = authServicesUrls.AssertionConsumerServiceUrl,
                Issuer = spOptions.EntityId,
                // For now we only support one attribute consuming service.
                AttributeConsumingServiceIndex = spOptions.AttributeConsumingServices.Any() ? 0 : (int?)null,
                NameIdPolicy          = spOptions.NameIdPolicy,
                RequestedAuthnContext = spOptions.RequestedAuthnContext
            };

            if (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.Always ||
                (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.IfIdpWantAuthnRequestsSigned &&
                 WantAuthnRequestsSigned))
            {
                if (spOptions.SigningServiceCertificate == null)
                {
                    throw new ConfigurationErrorsException(
                              string.Format(
                                  CultureInfo.InvariantCulture,
                                  "Idp \"{0}\" is configured for signed AuthenticateRequests, but ServiceCertificates configuration contains no certificate with usage \"Signing\" or \"Both\".",
                                  EntityId.Id));
                }

                authnRequest.SigningCertificate = spOptions.SigningServiceCertificate;
            }

            var requestState = new StoredRequestState(EntityId, returnUrl, authnRequest.Id, relayData);

            PendingAuthnRequests.Add(authnRequest.RelayState, requestState);

            return(authnRequest);
        }
        public void AuthServicesUrls_Ctor_FromHttpRequest_PublicOrigin()
        {
            var    url     = new Uri("http://example.com:42/ApplicationPath/Path?name=DROP%20TABLE%20STUDENTS");
            string appPath = "/ApplicationPath";
            var    request = Substitute.For <HttpRequestBase>();

            request.HttpMethod.Returns("GET");
            request.Url.Returns(url);
            request.Form.Returns(new NameValueCollection {
                { "Key", "Value" }
            });
            request.ApplicationPath.Returns(appPath);
            var options = StubFactory.CreateOptionsPublicOrigin(new Uri("https://my.public.origin:8443/OtherPath"));
            var subject = request.ToHttpRequestData();
            var urls    = new AuthServicesUrls(subject, options);

            urls.AssertionConsumerServiceUrl.ShouldBeEquivalentTo("https://my.public.origin:8443/OtherPath/AuthServices/Acs");
            urls.SignInUrl.ShouldBeEquivalentTo("https://my.public.origin:8443/OtherPath/AuthServices/SignIn");
        }
Exemple #10
0
        /// <summary>
        /// Create an authenticate request aimed for this idp.
        /// </summary>
        /// <param name="authServicesUrls">Urls for AuthServices, used to populate fields
        /// in the created AuthnRequest</param>
        /// <returns>AuthnRequest</returns>
        public Saml2AuthenticationRequest CreateAuthenticateRequest(
            AuthServicesUrls authServicesUrls)
        {
            if (authServicesUrls == null)
            {
                throw new ArgumentNullException("authServicesUrls");
            }

            var authnRequest = new Saml2AuthenticationRequest()
            {
                DestinationUrl = SingleSignOnServiceUrl,
                AssertionConsumerServiceUrl = authServicesUrls.AssertionConsumerServiceUrl,
                Issuer = spOptions.EntityId,
                // For now we only support one attribute consuming service.
                AttributeConsumingServiceIndex = spOptions.AttributeConsumingServices.Any() ? 0 : (int?)null
            };

            return(authnRequest);
        }
Exemple #11
0
        protected async override Task ApplyResponseGrantAsync()
        {
            var revoke = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);

            if (revoke != null)
            {
                var request = await Context.ToHttpRequestData(Options.DataProtector.Unprotect);

                var urls = new AuthServicesUrls(request, Options.SPOptions);

                string redirectUrl = revoke.Properties.RedirectUri;
                if (string.IsNullOrEmpty(redirectUrl))
                {
                    if (Context.Response.StatusCode / 100 == 3)
                    {
                        var locationUrl = Context.Response.Headers["Location"];

                        redirectUrl = new Uri(
                            new Uri(urls.ApplicationUrl.ToString().TrimEnd('/') + Context.Request.Path),
                            locationUrl
                            ).ToString();
                    }
                    else
                    {
                        redirectUrl = new Uri(
                            urls.ApplicationUrl,
                            Context.Request.Path.ToUriComponent().TrimStart('/'))
                                      .ToString();
                    }
                }

                var result = LogoutCommand.Run(request, redirectUrl, Options);

                if (!result.HandledResult)
                {
                    result.Apply(Context, Options.DataProtector);
                }
            }

            await AugmentAuthenticationGrantWithLogoutClaims(Context);
        }
Exemple #12
0
        static CommandResult CreateResult(
            EntityId idpEntityId,
            string returnPath,
            HttpRequestData request,
            IOptions options,
            object relayData = null)
        {
            var urls = new AuthServicesUrls(request, options.SPOptions);

            IdentityProvider idp;

            if (idpEntityId == null || idpEntityId.Id == null)
            {
                //if (options.SPOptions.DiscoveryServiceUrl != null)
                //{
                //    return RedirectToDiscoveryService(returnPath, options.SPOptions, urls);
                //}

                idp = options.IdentityProviders.Default;
            }
            else
            {
                if (!options.IdentityProviders.TryGetValue(idpEntityId, out idp))
                {
                    throw new InvalidOperationException("Unknown idp");
                }
            }

            Uri returnUrl = null;

            if (!string.IsNullOrEmpty(returnPath))
            {
                Uri.TryCreate(request.Url, returnPath, out returnUrl);
            }

            var authnRequest = idp.CreateAuthenticateRequest(returnUrl, urls, relayData);

            return(idp.Bind(authnRequest));
        }
        protected async override Task ApplyResponseGrantAsync()
        {
            // Automatically sign out, even if passive because passive sign in and auto sign out
            // is typically most common scenario. Unless strict compatibility is set.
            var mode = Options.SPOptions.Compatibility.StrictOwinAuthenticationMode ?
                       Options.AuthenticationMode : AuthenticationMode.Active;

            var revoke = Helper.LookupSignOut(Options.AuthenticationType, mode);

            if (revoke != null)
            {
                var request = await Context.ToHttpRequestData(Options.DataProtector.Unprotect);

                var urls = new AuthServicesUrls(request, Options);

                string redirectUrl = revoke.Properties.RedirectUri;
                if (string.IsNullOrEmpty(redirectUrl))
                {
                    if (Context.Response.StatusCode / 100 == 3)
                    {
                        redirectUrl = Context.Response.Headers["Location"];
                    }
                    else
                    {
                        redirectUrl = Context.Request.Path.ToUriComponent();
                    }
                }

                var result = LogoutCommand.Run(request, redirectUrl, Options);

                if (!result.HandledResult)
                {
                    result.Apply(Context, Options.DataProtector);
                }
            }

            await AugmentAuthenticationGrantWithLogoutClaims(Context);
        }
        public Saml2AuthenticationRequest CreateAuthenticateRequest(
            AuthServicesUrls authServicesUrls)
        {
            if (authServicesUrls == null)
            {
                throw new ArgumentNullException(nameof(authServicesUrls));
            }

            var authnRequest = new Saml2AuthenticationRequest()
            {
                DestinationUrl = SingleSignOnServiceUrl,
                AssertionConsumerServiceUrl = authServicesUrls.AssertionConsumerServiceUrl,
                Issuer = spOptions.EntityId,
                // For now we only support one attribute consuming service.
                AttributeConsumingServiceIndex = spOptions.AttributeConsumingServices.Any() ? 0 : (int?)null,
                NameIdPolicy          = spOptions.NameIdPolicy,
                RequestedAuthnContext = spOptions.RequestedAuthnContext,
                SigningAlgorithm      = this.OutboundSigningAlgorithm
            };

            if (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.Always ||
                (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.IfIdpWantAuthnRequestsSigned &&
                 WantAuthnRequestsSigned))
            {
                if (spOptions.SigningServiceCertificate == null)
                {
                    throw new ConfigurationErrorsException(
                              string.Format(
                                  CultureInfo.InvariantCulture,
                                  "Idp \"{0}\" is configured for signed AuthenticateRequests, but ServiceCertificates configuration contains no certificate with usage \"Signing\" or \"Both\". To resolve this issue you can a) add a service certificate with usage \"Signing\" or \"Both\" (default if not specified is \"Both\") or b) Set the AuthenticateRequestSigningBehavior configuration property to \"Never\".",
                                  EntityId.Id));
                }

                authnRequest.SigningCertificate = spOptions.SigningServiceCertificate;
            }

            return(authnRequest);
        }
Exemple #15
0
        public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls)
        {
            var ed = new ExtendedEntityDescriptor
            {
                EntityId      = spOptions.EntityId,
                Organization  = spOptions.Organization,
                CacheDuration = spOptions.MetadataCacheDuration
            };

            foreach (var contact in spOptions.Contacts)
            {
                ed.Contacts.Add(contact);
            }

            var spsso = new ExtendedServiceProviderSingleSignOnDescriptor();

            spsso.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol"));

            spsso.AssertionConsumerServices.Add(0, new IndexedProtocolEndpoint()
            {
                Index     = 0,
                IsDefault = true,
                Binding   = Saml2Binding.HttpPostUri,
                Location  = urls.AssertionConsumerServiceUrl
            });

            spsso.AssertionConsumerServices.Add(1, new IndexedProtocolEndpoint()
            {
                Index     = 1,
                IsDefault = false,
                Binding   = Saml2Binding.HttpArtifactUri,
                Location  = urls.AssertionConsumerServiceUrl
            });

            foreach (var attributeService in spOptions.AttributeConsumingServices)
            {
                spsso.AttributeConsumingServices.Add(attributeService);
            }

            if (spOptions.ServiceCertificates != null)
            {
                var publishCertificates = spOptions.MetadataCertificates;
                foreach (var serviceCert in publishCertificates)
                {
                    using (var securityToken = new X509SecurityToken(serviceCert.Certificate))
                    {
                        spsso.Keys.Add(
                            new KeyDescriptor
                        {
                            Use     = (KeyType)(byte)serviceCert.Use,
                            KeyInfo = new SecurityKeyIdentifier(securityToken.CreateKeyIdentifierClause <X509RawDataKeyIdentifierClause>())
                        }
                            );
                    }
                }
            }

            if (spOptions.DiscoveryServiceUrl != null &&
                !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString))
            {
                spsso.Extensions.DiscoveryResponse = new IndexedProtocolEndpoint
                {
                    Binding   = Saml2Binding.DiscoveryResponseUri,
                    Index     = 0,
                    IsDefault = true,
                    Location  = urls.SignInUrl
                };
            }

            ed.RoleDescriptors.Add(spsso);

            return(ed);
        }
 /// <summary>
 /// Create an authenticate request aimed for this idp.
 /// </summary>
 /// <param name="returnUrl">The return url where the browser should be sent after
 /// successful authentication.</param>
 /// <param name="authServicesUrls">Urls for AuthServices, used to populate fields
 /// in the created AuthnRequest</param>
 /// <returns>AuthnRequest</returns>
 public Saml2AuthenticationRequest CreateAuthenticateRequest(
     Uri returnUrl,
     AuthServicesUrls authServicesUrls)
 {
     return(CreateAuthenticateRequest(returnUrl, authServicesUrls, null));
 }
        public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls)
        {
            var ed = new ExtendedEntityDescriptor
            {
                EntityId      = spOptions.EntityId,
                Organization  = spOptions.Organization,
                CacheDuration = spOptions.MetadataCacheDuration
            };

            foreach (var contact in spOptions.Contacts)
            {
                ed.Contacts.Add(contact);
            }

            var spsso = new ExtendedServiceProviderSingleSignOnDescriptor();

            spsso.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol"));

            spsso.AssertionConsumerServices.Add(0, new IndexedProtocolEndpoint()
            {
                Index     = 0,
                IsDefault = true,
                Binding   = Saml2Binding.HttpPostUri,
                Location  = urls.AssertionConsumerServiceUrl
            });

            foreach (var attributeService in spOptions.AttributeConsumingServices)
            {
                spsso.AttributeConsumingServices.Add(attributeService);
            }

            ed.RoleDescriptors.Add(spsso);

            if (spOptions.DiscoveryServiceUrl != null &&
                !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString))
            {
                ed.Extensions.DiscoveryResponse = new IndexedProtocolEndpoint
                {
                    Binding   = Saml2Binding.DiscoveryResponseUri,
                    Index     = 0,
                    IsDefault = true,
                    Location  = urls.SignInUrl
                };
            }

            return(ed);
        }