Esempio n. 1
0
        protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            if (Request.Path == new PathString("/api/Account/SSOLogon"))
            {
                if (string.Equals(this.Request.Method, "POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(this.Request.ContentType) && (this.Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) && this.Request.Body.CanRead))
                {
                    if (!this.Request.Body.CanSeek)
                    {
                        this._logger.WriteVerbose("Buffering request body");
                        MemoryStream memoryStream = new MemoryStream();
                        await this.Request.Body.CopyToAsync((Stream)memoryStream);

                        memoryStream.Seek(0L, SeekOrigin.Begin);
                        this.Request.Body = (Stream)memoryStream;
                    }

                    IFormCollection form = await this.Request.ReadFormAsync();

                    //ToDo: clean up get the associated request
                    var protocolFactory = this._resolver.Resolve <Func <string, IProtocolHandler> >();
                    var protocolHanlder = protocolFactory(Bindings.Http_Post);

                    var protocolContext = new SamlProtocolContext
                    {
                        ResponseContext = new HttpPostResponseContext
                        {
                            AuthenticationMethod = base.Options.AuthenticationType,
                            Form = form.ToDictionary(x => x.Key, v => form.Get(v.Key)) as IDictionary <string, string>
                        }
                    };
                    await protocolHanlder.HandleResponse(protocolContext);

                    var responseContext = protocolContext.ResponseContext as HttpPostResponseContext;
                    var identity        = responseContext.Result;
                    if (identity != null)
                    {
                        return(new AuthenticationTicket(identity, new AuthenticationProperties()));
                    }
                }
            }
            return(null);
        }
Esempio n. 2
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;
            }
        }
Esempio n. 3
0
        protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            if (base.Options.AssertionEndpoinds.Count > 0 && !base.Options.AssertionEndpoinds.Contains(Request.Path))
            {
                return(null);
            }

            try
            {
                if (string.Equals(this.Request.Method, "POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(this.Request.ContentType) && (this.Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) && this.Request.Body.CanRead))
                {
                    if (!this.Request.Body.CanSeek)
                    {
                        this._logger.WriteVerbose("Buffering request body");
                        MemoryStream memoryStream = new MemoryStream();
                        await this.Request.Body.CopyToAsync((Stream)memoryStream);

                        memoryStream.Seek(0L, SeekOrigin.Begin);
                        this.Request.Body = (Stream)memoryStream;
                    }

                    var form = await this.Request.ReadFormAsync();

                    if (form.Get(HttpRedirectBindingConstants.SamlResponse) == null)
                    {
                        return(null);
                    }

                    this._logger.WriteInformation(String.Format("Saml2 response received"));
                    var protocolFactory  = this._resolver.Resolve <Func <string, IProtocolHandler> >();
                    var protocolHanlder  = protocolFactory(Bindings.Http_Post);
                    var decoder          = _resolver.Resolve <IBindingDecoder <IDictionary <string, string> > >();
                    var formToDictionary = form.ToDictionary(x => x.Key, v => form.Get(v.Key)) as IDictionary <string, string>;
                    var formDecoded      = await decoder.Decode(formToDictionary);

                    var protocolContext = new SamlProtocolContext
                    {
                        ResponseContext = new HttpPostResponseInboundContext
                        {
                            RequestUri           = Request.Uri,
                            AuthenticationMethod = base.Options.AuthenticationType,
                            Message            = formDecoded,
                            DescriptorResolver = m =>
                            {
                                var factory      = this._resolver.Resolve <Func <Type, IMetadataHandler> >();
                                var metadataType = m.GetType();
                                var handlerType  = typeof(IMetadataHandler <>).MakeGenericType(metadataType);
                                var handler      = factory(handlerType);
                                if (handler == null)
                                {
                                    throw new InvalidOperationException(String.Format("Handler must implement: {0}", typeof(IMetadataHandler).Name));
                                }
                                return(handler.GetIdentityProviderSingleSignOnDescriptor(m)
                                       .Single()
                                       .Roles.Single());
                            }
                        }
                    };
                    this._logger.WriteInformation(String.Format("Handle response entering."));
                    await protocolHanlder.HandleInbound(protocolContext);

                    var responseContext = protocolContext.ResponseContext as HttpPostResponseInboundContext;
                    var identity        = responseContext.Identity;
                    if (identity != null)
                    {
                        this._logger.WriteInformation(String.Format("Authenticated. Authentication ticket issued."));
                        var    properties = new AuthenticationProperties();
                        object validFrom;
                        if (responseContext.Properties.TryGetValue("ValidFrom", out validFrom) && validFrom is DateTime)
                        {
                            properties.IssuedUtc = new DateTimeOffset((DateTime)validFrom);
                        }
                        object validTo;
                        if (responseContext.Properties.TryGetValue("ValidTo", out validTo) && validTo is DateTime)
                        {
                            properties.ExpiresUtc = new DateTimeOffset((DateTime)validTo);
                        }
                        var    state = (IDictionary <string, object>)responseContext.RelayState;
                        object redirectUri;
                        if (state.TryGetValue(RelayStateContstants.RedirectUrl, out redirectUri))
                        {
                            properties.RedirectUri = redirectUri.ToString();
                        }
                        properties.Dictionary.Add(RelayStateContstants.FederationPartyId, ((IDictionary <string, object>)responseContext.RelayState)[RelayStateContstants.FederationPartyId].ToString());
                        var ticket = new AuthenticationTicket(identity, properties);
                        return(ticket);
                    }
                    this._logger.WriteInformation(String.Format("Authentication failed. No authentication ticket issued."));
                }

                return(null);
            }
            catch (Exception ex)
            {
                this._logger.WriteError(String.Format("An exceprion has been thrown when processing the response.", ex));
                return(null);
            }
        }
Esempio n. 4
0
 public async Task HandleResponse(SamlProtocolContext context)
 {
     await this._bindingHandler.HandleResponse(context.ResponseContext);
 }
Esempio n. 5
0
 public async Task HandleRequest(SamlProtocolContext context)
 {
     await this._bindingHandler.HandleRequest(context.RequestContext);
 }
Esempio n. 6
0
        protected override async Task ApplyResponseChallengeAsync()
        {
            if (this.Response.StatusCode != 401)
            {
                return;
            }

            var challenge = this.Helper.LookupChallenge(this.Options.AuthenticationType, this.Options.AuthenticationMode);

            if (challenge == null)
            {
                return;
            }

            if (!this.Options.SSOPath.HasValue || base.Request.Path != this.Options.SSOPath)
            {
                return;
            }

            var federationPartyId = FederationPartyIdentifierHelper.GetFederationPartyIdFromRequestOrDefault(Request.Context);

            if (this._configuration == null)
            {
                var configurationManager = this._resolver.Resolve <IConfigurationManager <MetadataBase> >();
                this._configuration = await configurationManager.GetConfigurationAsync(federationPartyId, new System.Threading.CancellationToken());
            }

            Uri signInUrl    = null;
            var metadataType = this._configuration.GetType();
            var handlerType  = typeof(IMetadataHandler <>).MakeGenericType(metadataType);
            var handler      = this._resolver.Resolve(handlerType);

            //ToDo: sort this one in phase3 when implementing owin middleware.
            //no need to have two methods in the handler. use GetDelegateForIdpDescriptors
            var locationDel = IdpMetadataHandlerFactory.GetDelegateForIdpLocation(metadataType);

            signInUrl = locationDel(handler, this._configuration, new Uri(Bindings.Http_Redirect));

            //the lines below are likely to do all what we need.
            var idpDel = IdpMetadataHandlerFactory.GetDelegateForIdpDescriptors(this._configuration.GetType(), typeof(IdentityProviderSingleSignOnDescriptor));
            var idp    = idpDel(handler, this._configuration).Cast <IdentityProviderSingleSignOnDescriptor>().First();

            var federationPartyContextBuilder = this._resolver.Resolve <IFederationPartyContextBuilder>();
            var federationContext             = federationPartyContextBuilder.BuildContext(federationPartyId);

            var requestContext  = new AuthnRequestContext(signInUrl, federationContext, idp.NameIdentifierFormats);
            var protocolContext = new SamlProtocolContext
            {
                RequestContext = new HttpRedirectRequestContext
                {
                    BindingContext      = new HttpRedirectContext(requestContext),
                    RequestHanlerAction = redirectUri =>
                    {
                        this.Response.Redirect(redirectUri.AbsoluteUri);
                        return(Task.CompletedTask);
                    }
                }
            };
            var protocolFactory = this._resolver.Resolve <Func <string, IProtocolHandler> >();
            var protocolHanlder = protocolFactory(Bindings.Http_Redirect);
            await protocolHanlder.HandleRequest(protocolContext);
        }