We’ve developed some resources to help you work effectively from home during COVID-19 Click to learn more

Getting single-signon in webpanels using .NET Core 3.x + OpenId Connect webapps?

Hi,
I'm working on writing the basics for a new Online application, and I'm using .NET Core 3.x and OAuth2 OpenId Connect.

I've read the Security and authentication article (which uses the Implicit Grant flow).

I've also read the DevNet+Angular+OpenId+Rest example on GitHub, and the DevNet+OpenIDConnect+dotNetCore2.0 example but haven't found exactly what I'm looking for.

The essentials of my application is working. When navigating to localhost I get redirected to the SOD loginpage, and eventually get an Access Token back (using Authorization Code grant flow).

However, when I add my website as a webpanel in SuperOffice, I was hoping to get a single-signon experience, but instead I end up with the login dialog inside the webpanel. From the "Security and authentication" article I was expecting the following to just make my life easier, but alas.

The SuperOffice Login page can check its cookies (these cookies are not available to the partner domain) and see if the user is logged in. If not, then the user gets the login form again.

Here is a snippet from my ConfigureServices in startup.cs.

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.ClientId = Configuration["SuperOffice.ClientId"];
    options.ClientSecret = Configuration["SuperOffice.ClientSecret"];
    options.Authority = "https://sod.superoffice.com/login";
    options.SaveTokens = true;
    options.Scope.Add("openid");
    options.CallbackPath = new Microsoft.AspNetCore.Http.PathString("/api/callback");
    options.ResponseMode = OpenIdConnectResponseMode.FormPost;
    options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
}

Looking at the "OpenId web panel login" thread I've tried to pass the <uctx> template variable to my application, to see if I can include that into the URL to the authorization_url, but can't find a way to manipulate the URL used by .NET Core.

What am I missing here? Has anyone gotten this to work using the new OAuth2 approach?

 

RE: Getting single-signon in webpanels using .NET Core 3.x + OpenId Connect webapps?

Hi Frode,

Regarding to this documentation (scroll down to almost the bottom at paragraph "Hosting Applications in Superoffice") you have to add the ContextIdentifier (Cust12345) to your authority url:
https://community.superoffice.com/en/developer/apps-partners/develop/security-and-authentication/

If possible, add the ContextIdentifier in your configuration file just like the clientid and secret.

So, in that case, instead of using this:

options.Authority = "https://sod.superoffice.com/login";

you have to use something like this:

options.Authority = "https://sod.superoffice.com/login/" + Configuration["SuperOffice.ContextIdentifier"];

It's not a good idea to read url parameters in the startup of your application (because the startup will run only once).
If you really want to use the uctx variable from the url to use it for the authority url, I think you have to create your own authorization middleware for that instead of setting up the authorization in the application startup.

Av: Sietse Wielenga 31. des 2019

RE: Getting single-signon in webpanels using .NET Core 3.x + OpenId Connect webapps?

Hi Sietse,

yes, I've seen that part of the documentation, but I'm unsure of how to edit the just the authorization_endpoint part (not the base URL used by the entire OAuth flow).

As a test I've hardcoded the context into the Authority URL (which is not the same as URL to the Authorization endpoint), like this:

options.Authority = "https://sod.superoffice.com/login/Cust11737";

That results in an exception:

InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://sod.superoffice.com/login/Cust11737/.well-known/openid-configuration'.

If I manually open up the oauth configuration URL (without context in URL) in my browser, I get this:

Optimally, what I think I want to achieve is that the value of the <uctx> variable is inserted into the authorization_endpoint URL at runtime, but how to do that in .NET 3 core isn't exactly clear to me (yet).

I'll take a look at some of the events that occur during the OpenIDConnect process, and see if it is possible (and sensible) to manipulate the authorization_endpoint url there.

Av: Frode Lillerud 3. jan 2020

RE: Getting single-signon in webpanels using .NET Core 3.x + OpenId Connect webapps?

The Authority should not be changed to include the tenant identifier. Frode is on the right track by only altering the authorize endpoint. 

 

Av: Tony Yates 6. jan 2020

RE: Getting single-signon in webpanels using .NET Core 3.x + OpenId Connect webapps?

Think I got it working by hooking into the OnRedirectToIdentityProvider event, like this:

OnRedirectToIdentityProvider = context =>
{
    //If the URL contains &uctx=, then include that in the URL to the SuperID /authorize endpoint, so that we get a better single-signon experience. 
    //This is typically used when the webapplication is hosted as a webpanel inside SuperOffice.
    var uctx = context.HttpContext.Request.Query["uctx"];
    if (uctx.Count > 0)
    {
        // Replaces the /common/ section of the URL with the relevant SuperOffice tenant CustId
        context.ProtocolMessage.IssuerAddress = context.ProtocolMessage.IssuerAddress.Replace("/login/common", "/login/" + uctx[0]);
    }

    return Task.FromResult(0);
},
Av: Frode Lillerud 6. jan 2020