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); }
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; } }
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); } }
public async Task HandleResponse(SamlProtocolContext context) { await this._bindingHandler.HandleResponse(context.ResponseContext); }
public async Task HandleRequest(SamlProtocolContext context) { await this._bindingHandler.HandleRequest(context.RequestContext); }
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); }