简体   繁体   中英

API not returning 401 instead returning Identity Login page

I have an api and a web app on the same application. I try to access a resource which is located at the API, but when authorization fails, it redirects to the Identity page. I have checked up on other solutions but their approach is different from my own approach. I'm injecting it into the services container. When I put a break-point over the code, it doesn't even reach the point at all

services.AddAuthentication()
.AddJwtBearer(x =>
            {
                x.Events = new JwtBearerEvents
                {
                    OnTokenValidated = context =>
                    {
                        var userService = context.HttpContext.RequestServices.GetRequiredService<SchoolAuthenticationManager>();
                        var userName = context.Principal.Identity.Name;
                        var user = userService.FindByNameAsync(userName);
                        if (user == null)
                        {
                            // return unauthorized if user no longer exists
                            context.Fail("Unauthorized user access.");
                        }
                        return Task.CompletedTask;
                    },
                    OnAuthenticationFailed = failed =>
                    {
                        failed.Fail("Unauthorized user access.");
                        return Task.CompletedTask;
                    }
                };

            });

This is my full ConfigureServices method

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<IdentityOptions>(options =>
            {
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz" +
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                options.User.RequireUniqueEmail = false;

                options.Password.RequireUppercase = false;
                options.Password.RequiredUniqueChars = 0;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireDigit = false;

                options.Lockout.AllowedForNewUsers = true;
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(60);
                options.Lockout.MaxFailedAccessAttempts = 4;

                options.SignIn.RequireConfirmedEmail = false;
                options.SignIn.RequireConfirmedPhoneNumber = false;

            });

            services.AddCors();
            services.AddDbContext<ElectDbContext>(x => x.UseSqlServer(Configuration.GetConnectionString("ElectDatabase"))
            .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));

            services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddJsonOptions(options=>
                {
                    options.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
                    //options.SerializerSettings.Culture.DateTimeFormat.ShortDatePattern = DateTimeFormatInfo.CurrentInfo.ShortDatePattern;
                    options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                });

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.Events = new JwtBearerEvents
                {
                    OnTokenValidated = context =>
                    {
                        var userService = context.HttpContext.RequestServices.GetRequiredService<ElectAuthenticationManager>();
                        var userName = context.Principal.Identity.Name;
                        var user = userService.FindByNameAsync(userName);
                        if (user == null)
                        {
                            // return unauthorized if user no longer exists
                            context.Fail("Unauthorized user access.");
                        }
                        return Task.CompletedTask;
                    },
                    OnAuthenticationFailed = failed =>
                    {
                        failed.Fail("Unauthorized user access.");
                        return Task.CompletedTask;
                    }
                };
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidIssuer = (string)Configuration.GetSection("JwtIssuerOptions").GetValue(typeof(string), "Issuer"),
                    ValidAudience = (string)Configuration.GetSection("JwtIssuerOptions").GetValue(typeof(string), "Audience"),
                    TokenDecryptionKey = new SymmetricSecurityKey(key),
                    ClockSkew = TimeSpan.FromMinutes(0),
                };
            });
            services.AddIdentityCore<ElectUser>()
                .AddRoles<ElectRole>()
                .AddDefaultTokenProviders()
                .AddEntityFrameworkStores<ElectDbContext>()
                .AddDefaultUI(Microsoft.AspNetCore.Identity.UI.UIFramework.Bootstrap4);

        }

Ive also tried this but still does not work

 services.ConfigureApplicationCookie(options =>
            {
                options.Events = new CookieAuthenticationEvents()
                {
                    OnRedirectToReturnUrl = (response) =>
                    {
                        if(response.Request.Path.StartsWithSegments("/api") && response.RedirectUri == "https://localhost:44307/Identity/Account/Login")
                        {
                            response.Response.StatusCode = 401;
                        }
                        return Task.CompletedTask;
                    },
                    OnRedirectToLogin = (response) =>
                    {
                        if (response.Request.Path.StartsWithSegments("/api") && response.Response.StatusCode == 200)
                        {
                            response.Response.StatusCode = 401;
                        }
                        return Task.CompletedTask;
                    },
                    OnRedirectToAccessDenied = (response) =>
                    {
                        if (response.Request.Path.StartsWithSegments("/api") && response.Response.StatusCode == 200)
                        {
                            response.Response.StatusCode = 403;
                        }
                        return Task.CompletedTask;
                    }
                };
            });

我已经按照https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1 上的@KirkLarkin 建议解决了这个问题我已将我的应用程序更改为使用两个身份验证方案,我还在控制器的Authroize属性中指定了身份验证方案。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM