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.