我在ASP.NET Core 3上具有IdentityServer4的基本设置-基本上,我们具有简单的注册方法和完整的OAuth 2.0协议。目前,用户可以从/connect/token
获取授权令牌,服务器可以使用数据库以某种方式完成整个身份验证过程。
我的问题是-如何自定义身份验证过程?如何授予访问权限,例如,仅授予用户名中带有“ admin”的用户,或者授予仅具有“ p”字母,或出生于68'或仅具有服务器上活动文件夹的密码的用户?
我的Startup.cs
代码:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace AuthServer
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppUserDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Default")));
services.AddIdentity<AppUser, IdentityRole>(
options =>
{
options.Password.RequiredLength = 6;
options.Password.RequireLowercase = true;
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
}
)
.AddEntityFrameworkStores<AppUserDbContext>()
.AddDefaultTokenProviders();
services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.Ids)
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryClients(Config.Clients)
.AddDeveloperSigningCredential()
.AddAspNetIdentity<AppUser>();
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
app.UseCors(options => options.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
app.UseIdentityServer();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
答案 0 :(得分:1)
您可以为此目的实现 IResourceOwnerPasswordValidator 接口。 然后将其注册到您的startup.cs
services.AddIdentityServer()
.AddResourceOwnerValidator<**PasswordAuthentication**>()
有关更多信息,请阅读Resource Owner Password Validation。
这是default implementation,因此您可以了解想法并实现自己的想法。
public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
var clientId = context.Request?.Client?.ClientId;
var user = await _userManager.FindByNameAsync(context.UserName);
if (user != null)
{
var result = await _signInManager.CheckPasswordSignInAsync(user, context.Password, true);
if (result.Succeeded)
{
var sub = await _userManager.GetUserIdAsync(user);
_logger.LogInformation("Credentials validated for username: {username}", context.UserName);
await _events.RaiseAsync(new UserLoginSuccessEvent(context.UserName, sub, context.UserName, false, clientId));
context.Result = new GrantValidationResult(sub, AuthenticationMethods.Password);
return;
}
else if (result.IsLockedOut)
{
_logger.LogInformation("Authentication failed for username: {username}, reason: locked out", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "locked out", false, clientId));
}
else if (result.IsNotAllowed)
{
_logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "not allowed", false, clientId));
}
else
{
_logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", false, clientId));
}
}
else
{
_logger.LogInformation("No user found matching username: {username}", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", false, clientId));
}
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
}