Want to call SamlServiceProvider.InitiateSsoAsync but without an Http Context

Hello -

We are experience SAML developers using Component Space. We have a use case as a service provider in which we want to generate the redirect URL for the end user but not send it directly as a 301 redirect to the browser. In fact, when we want to generate the redirect Url, we are doing so on the back-end w/o a current user trying to use it.

By calling samlServiceProvider.InitiateSsoAsync, with the proper information we get an exception thrown (see below) because we are doing so not as a direct end user browser request. Is there a way to use ComponentSpace code to generate the SSO redirect URL so that it does not automatically try to return to the browser a 302 redirect w/ the URL? Please advise.

Object reference not set to an instance of an object.
**** System.NullReferenceException ****
at ComponentSpace.Saml2.Bindings.AspNetHttpRequest.get_Cookies()
at ComponentSpace.Saml2.Session.DistributedSsoSessionStore.get_SessionID()
at ComponentSpace.Saml2.Session.DistributedSsoSessionStore.CreateKey(Type type)
at ComponentSpace.Saml2.Session.DistributedSsoSessionStore.LoadAsyncT
at ComponentSpace.Saml2.SamlProvider.LoadSamlStateAsync()
at ComponentSpace.Saml2.SamlServiceProvider.LoadSamlStateAsync()
at ComponentSpace.Saml2.SamlServiceProvider.InitiateSsoAsync(String partnerName, String relayState, ISsoOptions ssoOptions)

Mike Oliver

SAML SSO is a browser based protocol. All messages between the service provider and identity provider sites are sent via the browser.

We use IHttpRequest and IHttpResponse interfaces in the ComponentSpace.Saml2.Bindings namespace to represent the HTTP request and response and the operation the applicable operations. The default implementations are AspNetHttpRequest and AspNetHttpResponse.

If required, you can implement these interfaces and register them using dependency injection.

For example, the following code extends AspNetHttpResponse to access the redirect URL.


using ComponentSpace.Saml2.Bindings;

public class ExampleHttpResponse : AspNetHttpResponse
{
public ExampleHttpResponse(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
}

public override void Redirect(string url)
{
// TODO - use the redirect URL as required.
}
}



The implementation is registered at application start-up.


// Add SAML SSO services.
builder.Services.AddTransient<IHttpResponse, ExampleHttpResponse>();
builder.Services.AddSaml(builder.Configuration.GetSection(“SAML”));



The exception you’re seeing occurs when attempting to retrieve the saml-session cookie we use in support of the SAML protocol. This is accessed through the IHttpContextAccessor interface which presumably hasn’t been setup as there isn’t an actual HTTP request.

You can implement the IHttpRequest interface to circumvent this but you’ll subsequently run into issues if the saml-session cookie isn’t present.

The basic underlying requirement is that the HTTP request and HTTP response, however they’re represented, must be accessible.

[quote]
ComponentSpace - 8/12/2023
SAML SSO is a browser based protocol. All messages between the service provider and identity provider sites are sent via the browser.

We use IHttpRequest and IHttpResponse interfaces in the ComponentSpace.Saml2.Bindings namespace to represent the HTTP request and response and the operation the applicable operations. The default implementations are AspNetHttpRequest and AspNetHttpResponse.

If required, you can implement these interfaces and register them using dependency injection.

For example, the following code extends AspNetHttpResponse to access the redirect URL.


using ComponentSpace.Saml2.Bindings;

public class ExampleHttpResponse : AspNetHttpResponse
{
public ExampleHttpResponse(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
}

public override void Redirect(string url)
{
// TODO - use the redirect URL as required.
}
}



The implementation is registered at application start-up.


// Add SAML SSO services.
builder.Services.AddTransient();
builder.Services.AddSaml(builder.Configuration.GetSection("SAML"));



The exception you're seeing occurs when attempting to retrieve the saml-session cookie we use in support of the SAML protocol. This is accessed through the IHttpContextAccessor interface which presumably hasn't been setup as there isn't an actual HTTP request.

You can implement the IHttpRequest interface to circumvent this but you'll subsequently run into issues if the saml-session cookie isn't present.

The basic underlying requirement is that the HTTP request and HTTP response, however they're represented, must be accessible.
[/quote]

Understood - thank you for your quick, technical response.

You’re welcome.