Mojtaba
Mojtaba

Reputation: 3512

User is not authenticated in Middleware, but authenticated in Controller

I am using OpenIddict package to handle authentication in my .net core Api app. Inside my controllers, I can see User, its claims, roles, etc. However in Middleware, I don't have access to the user, as if the user is not authenticated.

I think I am missing something in ConfigureServices or Configure methods in Startup.cs.

public void ConfigureServices(IServiceCollection services)
        {

            // Add framework services.
            services.AddMvc(
                    config =>
                    {
                        //We are adding a default policy required for all requests
                        var policyBuilder =
                            new AuthorizationPolicyBuilder(OpenIddictValidationDefaults.AuthenticationScheme);
                        
                        var policy = policyBuilder.RequireAuthenticatedUser()
                            .Build();
                        config.Filters.Add(new AuthorizeFilter(policy));
                    }
                );


            services.AddDbContext<TGDbContext>((ctx, options) =>
            {
                options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
                options.UseOpenIddict();
            }, ServiceLifetime.Scoped, ServiceLifetime.Scoped);

            
            // Register the OpenIddict services.
            services.AddOpenIddict()
                .AddCore(options =>
                {
                    options.UseEntityFrameworkCore()
                        .UseDbContext<TGDbContext>();
                })
                .AddServer(options =>
                {
                    options.UseMvc();
                    options.EnableTokenEndpoint( "/connect/token");
                    options.AllowPasswordFlow();
                    options.AllowRefreshTokenFlow();
                    options.AcceptAnonymousClients();
                    options.AllowCustomFlow("GuestLogin");
                    options.RegisterScopes("Booking");
                    if (this._env.IsDevelopment())
                        options.DisableHttpsRequirement(); // Note: Requires Https in production
                    options.RegisterScopes(
                        OpenIdConnectConstants.Scopes.OpenId,
                        OpenIdConnectConstants.Scopes.Email,
                        OpenIdConnectConstants.Scopes.Phone,
                        OpenIdConnectConstants.Scopes.Profile,
                        OpenIdConnectConstants.Scopes.OfflineAccess,
                        OpenIddictConstants.Scopes.Roles);
                })
                .AddValidation();

            // add identity
            services.AddIdentity<ApplicationUser, ApplicationRole>()
                .AddEntityFrameworkStores<TGDbContext>()
                .AddDefaultTokenProviders();

            // Configure Identity options and password complexity here
            services.Configure<IdentityOptions>(options =>
            {
                // User settings
                options.User.RequireUniqueEmail = false;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequireLowercase = false;
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
                options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
                options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy(.....);
             ....
             ....
             ....           
            });
  .....
  .....
  .....

}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ....
            ....
            ....

            app.UseAuthentication();

            app.Use(async (context, next) =>
            {
                var isAuthenticated = context.User.Identity.IsAuthenticated;
                // isAuthenticated is false here
                // also context.User.Claims is empty
                Console.WriteLine(isAuthenticated);
                await next.Invoke();
            });

           ....
           ....
           ....
          app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });
}

I am targeting .Net Core 2.2 using OpenIddict 2.0.1 and OpenIddict.EntityFramework 2.0.1.

Upvotes: 0

Views: 1040

Answers (1)

K&#233;vin Chalet
K&#233;vin Chalet

Reputation: 42000

The behavior you're seeing is expected (and not specific to OpenIddict): by registering an AuthorizeFilter pointing to the OpenIddict validation handler, you're only configuring MVC to validate bearer tokens, but not the rest of your app, including middleware.

To configure OpenIddict as the default authentication scheme, call

services.AddAuthentication(options =>
{
    // When targeting OpenIddict 3.0, OpenIddictValidationAspNetCoreDefaults
    // must be used instead of OpenIddictValidationDefaults.
    options.DefaultAuthenticateScheme = OpenIddictValidationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIddictValidationDefaults.AuthenticationScheme;
});

Upvotes: 1

Related Questions