6

THE PROBLEM

I have a problem using OpenID Connect 3 to provide authorisation for a website I am developing.

The problem goes like this:

  1. I visit a protected page and am redirected to the IdentityServer (OpenID Connect 3)
  2. The Identity server asks for my username and password
  3. These credentials are deemed to be OK and I am then forwarded back to the MVC site.
  4. This is where is goes wrong. For some reason the site remains unauthenticated and there for redirects back to the Identityserver.
  5. As far as the identity server is concerned i'm already logged in so it redirects me back to the mvc application

Steps 4 and 5 carry on for ever... Well they would except a limit to the maximum number of cookies is reached which brings everything to an end.

TRIED SOLUTIONS

After days of googling I have tried the following but so far nothing is working for me.

  1. Kentor Owin Cookie Fix in the Startup class.. ConfigureAuth function

    app.UseKentorOwinCookieSaver();
    
  2. A variation on 1

    app.UseKentorOwinCookieSaver(PipelineStage.Authenticate);
    
  3. Alternative cookie Manager SystemWebCookieManager

           app.UseCookieAuthentication(new CookieAuthenticationOptions
           {
                AuthenticationType = "Cookies",
               CookieManager = new SystemWebCookieManager()
    
           });
    
  4. A variation on 3 SystemWebChunkingCookieManager

           app.UseCookieAuthentication(new CookieAuthenticationOptions
           {
                AuthenticationType = "Cookies",
                CookieManager = new SystemWebChunkingCookieManager()
    
            });
    
  5. Session stubs in Global.asa file

        protected void Session_Start()
        {
    
        }
    
        protected void Session_End()
        {
    
        }
    

I did try a few other things where other developer had written there own code to try and fix. I'm going a little crazy as nothing seems to be working. Has anybody else been here that could give me a clue on what I can do next. Below is the relevant code from my OpenIdServer and MVC app.

Identity Server Config

    using Microsoft.Owin;
    using Owin;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using IDServer.Config;
    using IdentityServer3.Core.Configuration;
    using System.Security.Cryptography.X509Certificates;

    [assembly: OwinStartup(typeof(IDServer.Startup))]

    namespace IDServer
    {
        public class Startup
        {

            public void Configuration(IAppBuilder app)
            {

                app.Map("", idsrvApp =>
                {
                    idsrvApp.UseIdentityServer(new IdentityServer3.Core.Configuration.IdentityServerOptions
                    {
                        SiteName = "Identity Server",
                        IssuerUri = "https://localhost:44398/embedded",
                        Factory = new IdentityServerServiceFactory()
                            .UseInMemoryClients(Clients.Get())
                            .UseInMemoryScopes(Scopes.Get())
                            .UseInMemoryUsers(Users.Get()),

                        SigningCertificate = LoadCertificate(),
                       RequireSsl = true,


                    });

                });


            }

            X509Certificate2 LoadCertificate()
            {
                return new X509Certificate2(
                    string.Format(@"{0}\Certificates\idsrv3test.pfx", 
                    AppDomain.CurrentDomain.BaseDirectory), "idsrv3test");
            }
        }
    }

Client regestration config on server

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using IdentityServer3.Core.Models;

    namespace IDServer.Config
    {
        public static class Clients
        {
            public static IEnumerable<Client> Get()
            {

                return new[]
                {
                    new Client
                    {
                        Enabled=true,
                        ClientName = "My Application",
                        ClientId = "MyApp",
                        Flow = Flows.Hybrid,
                        //Flow=Flows.Implicit,
                        RequireConsent = true,
                        RedirectUris = new List<string> { "https://localhost:44362/" },
                        AllowedScopes = new List<string> {"openid"}

                    }

                };
            }
        }
    }

Web App Config

 using Microsoft.Owin.Security;
 using Microsoft.Owin.Security.Cookies; 
 using Microsoft.Owin.Security.OpenIdConnect;
 using Owin;
 using System;
 using System.Diagnostics; 
 using System.Web; 
 using Microsoft.Owin.Host.SystemWeb;
 using Microsoft.Owin.Infrastructure;

 [assembly: OwinStartup(typeof(MyApp.Startup))]

 namespace MyApp {
     public partial class Startup
     {
         public void ConfigureAuth(IAppBuilder app)
         {
             app.UseKentorOwinCookieSaver();
             //app.UseKentorOwinCookieSaver(PipelineStage.Authenticate);




app.SetDefaultSignInAsAuthenticationTypeCookieAuthenticationDefaults
.AuthenticationType);

             ICookieManager c = new SystemWebCookieManager();


             app.UseCookieAuthentication(new CookieAuthenticationOptions
             {
                 AuthenticationType = "Cookies",
                 //CookieManager = new SystemWebChunkingCookieManager()
                 //CookieManager = new SystemWebCookieManager()
                 CookieManager = c
             });

             app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
             {

                 ClientId = "MyApp",
                 Authority = "https://localhost:44398/",
                 RedirectUri = "https://localhost:44362/",
                 SignInAsAuthenticationType = "Cookies",
                 ResponseType = "code id_token",
                 Scope = "openid",
                 RequireHttpsMetadata = true,
                 CallbackPath = new PathString("/home/contact/"),

                 Notifications = new OpenIdConnectAuthenticationNotifications()
                 {
                     MessageReceived = async n =>
                     {
                         Debug.Print(n.ProtocolMessage.IdToken);
                     }

                 }

         }
     }
Leonardo Henriques
  • 784
  • 1
  • 7
  • 22

2 Answers2

4

I finally managed to get it to work by setting AutheticationType to Active. See the snippet below.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = "Cookies",
    AuthenticationMode = AuthenticationMode.Active            
});
johnny 5
  • 19,893
  • 50
  • 121
  • 195
1

This is a known issue with ASP.NET (Framework projects). You can check this link for more information: https://github.com/aspnet/AspNetKatana/wiki/System.Web-response-cookie-integration-issues

Basically, the cause of the issue is that the implementation of System.Web cookies and OwinResponse cookies clash with each other. Causing it to overwrite the cookies sometimes.

There are 3 workarounds mentioned in the above explanation. I found it the easiest to use the 3rd one which reads as follows:

Reconfigure the CookieAuthenticationMiddleware to write directly to System.Web's cookie collection. You may also need to do this for other components that write cookies such as OpenIdConnectAuthenticationOptions.CookieManager.

Basically, all you need to do is this:

app.UseCookieAuthentication(new CookieAuthenticationOptions
   {
      // ...
      CookieManager = new SystemWebCookieManager()
   });

You may need to do the same in the OpenIdConnectAuthenticationOptions, like this:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
   {
      // ....
      CookieManager = new SystemWebCookieManager()
   }

The SystemWebCookieManager class exists in the OWIN packages, more specifically in Microsoft.Owin.Host.SystemWeb

Newteq Developer
  • 2,257
  • 1
  • 26
  • 32