问题描述
以下问题,我可以创建一个令牌,但是当我使用它时,身份验证失败,我尝试从一个示例中进行复制,但是我遇到了问题,因为 有些方法不是“有”的。 (类似于principal.SetScopes,但它似乎存在于Github存储库和其他示例中) 我得到的唯一错误是AuthorizationFilter失败。 这里是创建令牌的方法
[HttpPost("~/connect/token"),Produces("application/json")]
public async Task<IActionResult> Exchange(OpenIdConnectRequest connectRequest)
{
if (connectRequest.IsPasswordGrantType())
{
var user = await _userManager.FindByNameAsync(connectRequest.Username);
if (user == null)
{
return Forbid(
authenticationSchemes: OpenIddictServerDefaults.AuthenticationScheme,properties: new AuthenticationProperties(new Dictionary<string,string>
{
[OpenIdConnectConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant,[OpenIdConnectConstants.Properties.ErrorDescription] = "The username/password couple is invalid."
}));
}
var result = await _signInManager.CheckPasswordSignInAsync(user,connectRequest.Password,lockoutOnFailure: true);
if (!result.Succeeded)
{
return Forbid(
authenticationSchemes: OpenIddictValidationDefaults.AuthenticationScheme,string>
{
[OpenIdConnectConstants.Properties.Error] = Errors.InvalidGrant,[OpenIdConnectConstants.Properties.ErrorDescription] = "The username/password couple is invalid."
}));
}
var principal = await _signInManager.createuserPrincipalAsync(user);
//principal.SetScopes(new[]
//{
// Scopes.OpenId,// Scopes.Email,// Scopes.Profile,// Scopes.Roles
//}.Intersect(connectRequest.GetScopes()));
//foreach (var claim in principal.Claims)
//{
// claim.SetDestinations(GetDestinations(claim,principal));
//}
var sign = SignIn(principal,OpenIddictServerDefaults.AuthenticationScheme);
return sign;
}
throw new Exception("Not supported");
}
Here is my startup
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DocumentiveContext>((provider,builder) =>
{
var configuration = provider.GetService<IConfiguration>();
builder.UsesqlServer(configuration.GetConnectionString("connectionString"));
builder.USEOpenIddict();
});
services.AddIdentity<ApplicationUser,IdentityRole>(options =>
{
})
.AddEntityFrameworkStores<DocumentiveContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToAccessDenied = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = Claims.Name;
options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
options.ClaimsIdentity.RoleClaimType = Claims.Role;
});
services.AddAuthentication(options =>
options.DefaultScheme = OpenIddictValidationDefaults.AuthenticationScheme);
services.AddOpenIddict(builder =>
{
builder.AddCore(coreBuilder => coreBuilder.UseEntityFrameworkCore().UseDbContext<DocumentiveContext>());
builder.AddServer(serverBuilder =>
{
serverBuilder.UseMvc();
//serverBuilder.EnabletokenEndpoint("/connect/token");
serverBuilder.EnableAuthorizationEndpoint("/connect/authorize")
.EnablelogoutEndpoint("/connect/logout")
.EnabletokenEndpoint("/connect/token")
.EnableuserinfoEndpoint("/connect/userinfo")
.EnableuserinfoEndpoint("/connect/verify");
serverBuilder.AllowPasswordFlow();
serverBuilder.RegisterScopes(Scopes.Email,Scopes.Profile,Scopes.Roles,"demo_api");
serverBuilder.AddDevelopmentSigningCertificate();
serverBuilder.AcceptAnonymousClients();
serverBuilder.disableHttpsRequirement();
});
builder.AddValidation(validationBuilder =>
{
});
});
services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddGrpc();
services.AddTransient<IUser@R_539_4045@ionService,User@R_539_4045@ionService>();
}
// 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.UseRouting();
app.UseAuthentication();
app.UseStaticFiles();
app.UseSerilogRequestLogging();
app.UseAuthorization();
app.UseMvcWithDefaultRoute();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
endpoints.MapGet("/",async context =>
{
await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client,visit: https://go.microsoft.com/fwlink/?linkid=2086909");
});
});
}
}
Any idea?
解决方法
更新到最新版本的Openiddict 3后,它可以工作。 另外,我需要在属性中设置身份验证方案。
[Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]