UseOpenIdConnectServer is not working

5k views Asked by At

I just updated my dotnet core webapi application from netcoreapp1.0 to netcoreapp2.0. I am using openiddict for authentication and authorization based on this sample.

ConfigureServices method :

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddMvc().AddJsonOptions(options =>
               {
                   options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
               });

            services.AddDbContext<ApplicationDbContext>(options =>
            {                
                options.UseSqlServer(@"Server=SERVER1;Database=DB1;User Id=BLAHBLAH;Password=BLAHBLAHBLAH;");                
                options.UseOpenIddict();
            });

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.Configure<IdentityOptions>(options =>
            {
                options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
                options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
                options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;                
            });

            services.AddOpenIddict(options =>
            {                
                options.AddEntityFrameworkCoreStores<ApplicationDbContext>();                
                options.AddMvcBinders();
                options.EnableTokenEndpoint("/connect/token");
                options.AllowPasswordFlow();
                options.DisableHttpsRequirement();
                options.SetAccessTokenLifetime(TimeSpan.FromMinutes(5));
            });

            services.AddAuthentication()
                .AddOAuthValidation();

        }

Configure method :

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseCors(b => b.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());    

            app.UseOpenIdConnectServer(configuration => {                
                configuration.AllowInsecureHttp = true;                                    
                configuration.Provider = new AuthorizationProvider();
            });               
            app.UseAuthentication();                
            app.UseMvc();
        }

The AuthorizationProvider class :

    public sealed class AuthorizationProvider : OpenIdConnectServerProvider
    {            
        public AuthorizationProvider()
        {

        }

        public override async Task ApplyTokenResponse(ApplyTokenResponseContext context)
        {        
            if (string.IsNullOrEmpty(context.Error))
            {
                var role = context.Ticket.Principal.Claims.FirstOrDefault(q => q.Type == OpenIdConnectConstants.Claims.Role).Value;
                var userName = context.Ticket.Principal.Claims.FirstOrDefault(q => q.Type == OpenIdConnectConstants.Claims.Name).Value;
                context.Response["role"] = role;
                context.Response["userName"] = userName;
                context.Response[".issued"] = DateTime.Now.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss 'GMT'");
                context.Response[".expires"] = DateTime.Now.AddHours(8).ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss 'GMT'");    
            }

            return;
        }
    }

The following code is not working :

app.UseOpenIdConnectServer(configuration => {                
    configuration.AllowInsecureHttp = true;                
    configuration.Provider = new AuthorizationProvider();
});

It says 'IApplicationBuilder' does not contain a definition for 'UseOpenIdConnectServer' and no extension method 'UseOpenIdConnectServer' accepting a first argument of type 'IApplicationBuilder' could be found (are you missing a using directive or an assembly reference?)

How do I resolve it? What is the alternative method to add a custom provider?

3

There are 3 answers

2
Sriram On

ASP.NET Core 2.0 has a new model for authentication and Identity which simplifies configuration by using services and below is the migration guide

Migrating Authentication and Identity to ASP.NET Core 2.0

in Configure method change this

app.UseOpenIdConnectServer(configuration => {                
    configuration.AllowInsecureHttp = true;                
    configuration.Provider = new AuthorizationProvider();
});

To this

app.UseAuthentication();

and in ConfigureServices add the below code

services.AddAuthentication(options => {
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options => {
    options.Authority = Configuration["auth:oidc:authority"];
    options.ClientId = Configuration["auth:oidc:clientid"];
});
0
TheKingPinMirza On

As per github page with examples

The correct way of doing this in Startup.cs is as follow. (pasting my sample code for your reference. You can re-factor based on your need) It should be inside ConfigureServices method

services.AddAuthentication(options =>
    {
        options.DefaultScheme = "ServerCookie";
    })
    .AddCookie("ServerCookie", options =>
    {
        options.Cookie.Name = CookieAuthenticationDefaults.CookiePrefix + "ServerCookie";
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
        options.LoginPath = new PathString("/login");
        options.LogoutPath = new PathString("/logout");
    })
    .AddOAuthValidation()
    .AddOpenIdConnectServer(options =>
    {
        options.ProviderType = typeof(AuthorizationProvider);

        // Enable the authorization, logout, token and userinfo endpoints.
        options.AuthorizationEndpointPath = "/connect/authorize";
        options.LogoutEndpointPath = "/connect/logout";
        options.TokenEndpointPath = new PathString("/Login");//"/connect/token";
        options.UserinfoEndpointPath = "/connect/userinfo";

        // Note: see AuthorizationController.cs for more
        // information concerning ApplicationCanDisplayErrors.
        options.ApplicationCanDisplayErrors = true;
        options.AllowInsecureHttp = true;

        // Note: to override the default access token format and use JWT, assign AccessTokenHandler:
        //
        // options.AccessTokenHandler = new JwtSecurityTokenHandler
        // {
        //     InboundClaimTypeMap = new Dictionary<string, string>(),
        //     OutboundClaimTypeMap = new Dictionary<string, string>()
        // };
        //
        // Note: when using JWT as the access token format, you have to register a signing key.
        //
        // You can register a new ephemeral key, that is discarded when the application shuts down.
        // Tokens signed using this key are automatically invalidated and thus this method
        // should only be used during development:
        //
        // options.SigningCredentials.AddEphemeralKey();
        //
        // On production, using a X.509 certificate stored in the machine store is recommended.
        // You can generate a self-signed certificate using Pluralsight's self-cert utility:
        // https://s3.amazonaws.com/pluralsight-free/keith-brown/samples/SelfCert.zip
        //
        // options.SigningCredentials.AddCertificate("7D2A741FE34CC2C7369237A5F2078988E17A6A75");
        //
        // Alternatively, you can also store the certificate as an embedded .pfx resource
        // directly in this assembly or in a file published alongside this project:
        //
        // options.SigningCredentials.AddCertificate(
        //     assembly: typeof(Startup).GetTypeInfo().Assembly,
        //     resource: "Mvc.Server.Certificate.pfx",
        //     password: "Owin.Security.OpenIdConnect.Server");
    });
    services.AddScoped<AuthorizationProvider>();   

Then inside your configure method

app.UseAuthentication();

where app is IApplicationBuilder

0
Dominic On

Look here

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFrameworkInMemoryDatabase()
            .AddDbContext<ApplicationContext>(options =>
            {
                options.UseInMemoryDatabase(nameof(ApplicationContext));
            });

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = "ServerCookie";
        })

        .AddCookie("ServerCookie", options =>
        {
            options.Cookie.Name = CookieAuthenticationDefaults.CookiePrefix + "ServerCookie";
            options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
            options.LoginPath = new PathString("/signin");
            options.LogoutPath = new PathString("/signout");
        })

        .AddGoogle(options =>
        {
            options.ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com";
            options.ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f";
        })

        .AddTwitter(options =>
        {
            options.ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g";
            options.ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI";
        })

        .AddOAuthValidation()

        .AddOpenIdConnectServer(options =>
        {
            options.ProviderType = typeof(AuthorizationProvider);

            // Enable the authorization, logout, token and userinfo endpoints.
            options.AuthorizationEndpointPath = "/connect/authorize";
            options.LogoutEndpointPath = "/connect/logout";
            options.TokenEndpointPath = "/connect/token";
            options.UserinfoEndpointPath = "/connect/userinfo";

            // Note: see AuthorizationController.cs for more
            // information concerning ApplicationCanDisplayErrors.
            options.ApplicationCanDisplayErrors = true;
            options.AllowInsecureHttp = true;

            // Note: to override the default access token format and use JWT, assign AccessTokenHandler:
            //
            // options.AccessTokenHandler = new JwtSecurityTokenHandler
            // {
            //     InboundClaimTypeMap = new Dictionary<string, string>(),
            //     OutboundClaimTypeMap = new Dictionary<string, string>()
            // };
            //
            // Note: when using JWT as the access token format, you have to register a signing key.
            //
            // You can register a new ephemeral key, that is discarded when the application shuts down.
            // Tokens signed using this key are automatically invalidated and thus this method
            // should only be used during development:
            //
            // options.SigningCredentials.AddEphemeralKey();
            //
            // On production, using a X.509 certificate stored in the machine store is recommended.
            // You can generate a self-signed certificate using Pluralsight's self-cert utility:
            // https://s3.amazonaws.com/pluralsight-free/keith-brown/samples/SelfCert.zip
            //
            // options.SigningCredentials.AddCertificate("7D2A741FE34CC2C7369237A5F2078988E17A6A75");
            //
            // Alternatively, you can also store the certificate as an embedded .pfx resource
            // directly in this assembly or in a file published alongside this project:
            //
            // options.SigningCredentials.AddCertificate(
            //     assembly: typeof(Startup).GetTypeInfo().Assembly,
            //     resource: "Mvc.Server.Certificate.pfx",
            //     password: "Owin.Security.OpenIdConnect.Server");
        });

        services.AddScoped<AuthorizationProvider>();

        services.AddMvc();

        services.AddDistributedMemoryCache();
    }

https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/dev/samples/Mvc/Mvc.Server/Startup.cs#L29