我使用的是OpenIdDict 3.0,它工作得很好,但是我有一个使用AllowAnonymous属性的控制器,而且我仍然收到“请求被拒绝,因为缺少访问令牌”。我假设这可能是与我的启动命令,这使它不会在管道中被击中,但我不确定。这是我的创业课:
public async void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseMvcWithDefaultRoute();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
}).AddNewtonsoftJson();
services.AddAutoMapper(typeof(Startup));
services.AddDbContext<MyDbContext>(options =>
{
options.UseSqlServer(WebConfig.ConnectionString, x => x.MigrationsAssembly("X.Api.DataAccess"));
options.UseLazyLoadingProxies();
options.UseOpenIddict();
});
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Password.RequireLowercase = true;
})
.AddEntityFrameworkStores<MyDbContext>()
.AddUserStore<ApplicationUserStore>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = Claims.Name;
options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
options.ClaimsIdentity.RoleClaimType = Claims.Role;
});
services.AddOpenIddict()
.AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<MyDbContext>();
})
.AddServer(options =>
{
options.SetAuthorizationEndpointUris("/connect/authorize")
.SetLogoutEndpointUris("/connect/logout")
.SetTokenEndpointUris("/connect/token");
options.AllowAuthorizationCodeFlow()
.AllowRefreshTokenFlow();
scopes.
options.RegisterScopes(Scopes.Email, Scopes.OpenId, Scopes.OfflineAccess);
// Register the signing and encryption credentials.
options.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate();
options.UseAspNetCore()
.EnableTokenEndpointPassthrough();
})
.AddValidation(options =>
{
// Import the configuration from the local OpenIddict server instance.
options.UseLocalServer();
// Register the ASP.NET Core host.
options.UseAspNetCore();
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
});
}任何帮助都将不胜感激!
发布于 2020-05-12 00:14:53
您所看到的行为实际上是“正常的”:当您设置DefaultAuthenticateScheme时,身份验证中间件(也称为app.UseAuthentication()) --通常在ASP.NET核心管道中很早就添加--会自动调用相应的身份验证处理程序来填充HttpContext.User。
无论您的MVC操作是用[Authorize]修饰还是用[AllowAnonymous]修饰,这种机制的发生总是独立的。如果OpenIddict无法在Authorization头中找到访问令牌,它会记录一个错误,并告诉身份验证堆栈它无法提供它请求的AuthenticateResult。
如果您的MVC操作是用[Authorize]修饰的,身份验证堆栈将要求OpenIddict返回401挑战(除非使用[AllowAnonymous] )。
这就是说,虽然它不能阻止正常工作,但我同意这可能是一个重要的噪音来源,所以我会考虑删除这条日志消息。我打开https://github.com/openiddict/openiddict-core/issues/941来追踪它。
干杯。
发布于 2020-11-27 17:01:58
在我的例子中,我想使用[AllowAnonymous]属性消除DB上下文创建。但不是这样的。因此,我不得不为AuthenticationMiddleware创建自己的替代品,并为异常添加必要的路径。
现在一步一步地。
First.创建中间件:
public class CustomAuthenticationMiddleware
{
private readonly RequestDelegate _nextWithoutAuth;
private readonly AuthenticationMiddleware _nextWithAuth;
private List<PathString> _withoutAuth = new List<PathString>
{
"/url/1", "/url/2"
};
public CustomAuthenticationMiddleware(RequestDelegate next,
IServiceProvider sp)
{
_nextWithoutAuth = next;
_nextWithAuth = ActivatorUtilities
.CreateInstance<AuthenticationMiddleware>(sp, next);
}
public async Task Invoke(HttpContext context)
{
var path = context.Request.Path.HasValue ?
context.Request.Path.Value : null;
var withoutAuth = context.Request.Path.HasValue
&& _withoutAuth.Any(it => path.StartsWith(it, StringComparison.OrdinalIgnoreCase));
if (withoutAuth)
{
await _nextWithoutAuth.Invoke(context);
}
else
{
await _nextWithAuth.Invoke(context);
}
}
}第二.用所需的值填充数组_withoutAuth。
第三.在Startup.cs中,用app.UseMiddleware<CustomAuthenticationMiddleware>();代替app.UseAuthentication();。
附注:我使用.net核心2.1
p.s.s.如果使用[AllowAnonymous]属性获取所有控制器及其方法并将它们添加到_withoutAuth数组中,则可以改进我的解决方案。
https://stackoverflow.com/questions/61740467
复制相似问题