Asp.Net核心,智威汤逊和OpenIdConnectServer
我想了解所有关于JWT令牌在Asp.Net核心的东西。出血后的工作与大量的missunderstandings我卡住了。我的任务是使WebApi服务器具有两个控制器(受保护而不受保护)。我应该从服务器授予令牌并能够获得受保护的资源。当我运行服务器并尝试从邮递员获取受保护的资源时,一切似乎都很顺利。但是当我在我的角度做同样的事情时,从另一个领域我有奇怪的事情。我可以得到无保护资源,我不能与这样的错误得到保护资源:Asp.Net核心,智威汤逊和OpenIdConnectServer
XMLHttpRequest cannot load http://localhost:10450/api/prvalues. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:10377' is therefore not allowed access.
要清楚我告诉我所有的attemts。我project.json看起来像
"dependencies": {
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4",
"EntityFramework.Core": "7.0.0-rc1-final",
"EntityFramework.InMemory": "7.0.0-rc1-final",
"Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final",
"Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
"Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
"NWebsec.Middleware": "1.0.0-gamma-39",
"Microsoft.AspNet.Mvc.Cors": "6.0.0-rc1-final",
"Microsoft.AspNet.Cors": "6.0.0-rc1-final"
},
我Startup.ConfigureServices()
看起来像
公共无效ConfigureServices(IServiceCollection服务) {
services.AddCors(options =>
{
options.AddPolicy("AllowAllOrigins",
builder =>
{
builder.AllowAnyOrigin();
builder.AllowAnyHeader();
});
});
services.AddEntityFramework()
.AddInMemoryDatabase()
.AddDbContext<ApplicationDbContext<ApplicationUser, Application, IdentityRole, string>>(options => {
options.UseInMemoryDatabase();
});
services.AddScoped<IAuthStore<ApplicationUser,Application>, AuthStore<ApplicationUser, Application, IdentityRole,
ApplicationDbContext<ApplicationUser, Application, IdentityRole, string>, string>>();
services.AddScoped<AuthManager<ApplicationUser, Application>>();
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Password = new PasswordOptions()
{
RequiredLength = 1,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
RequireNonLetterOrDigit = false
};
}).AddEntityFrameworkStores<ApplicationDbContext<ApplicationUser, Application, IdentityRole, string>>().AddDefaultTokenProviders();
services.AddAuthentication();
// Add framework services.
services.AddCaching();
services.AddMvc();
}
AuthManager和AuthStore从OpenIddict被盗。我会晚些时候给他们看。我Startup.Configure()
样子:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseCors("AllowAllOrigins");
app.UseIISPlatformHandler();
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
// Create a new branch where the registered middleware will be executed only for API calls.
app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch =>
{
branch.UseJwtBearerAuthentication(options =>
{
options.AutomaticAuthenticate = true;
options.AutomaticChallenge = true;
options.RequireHttpsMetadata = false;
// Thisi is test, if I uncomment this and SetResource in AuthorizationProvider everything works in postman
//options.Audience = "http://localhost:10450/";
// My Angular client
options.Audience = "http://localhost:10377/";
// My Api
options.Authority = "http://localhost:10450/";
});
});
// Note: visit https://docs.nwebsec.com/en/4.2/nwebsec/Configuring-csp.html for more information.
app.UseCsp(options => options.DefaultSources(configuration => configuration.Self())
.ImageSources(configuration => configuration.Self().CustomSources("data:"))
.ScriptSources(configuration => configuration.UnsafeInline())
.StyleSources(configuration => configuration.Self().UnsafeInline()));
app.UseXContentTypeOptions();
app.UseXfo(options => options.Deny());
app.UseXXssProtection(options => options.EnabledWithBlockMode());
app.UseOpenIdConnectServer(options =>
{
options.Provider = new AuthorizationProvider();
// Note: see AuthorizationController.cs for more
// information concerning ApplicationCanDisplayErrors.
options.ApplicationCanDisplayErrors = true;
options.AllowInsecureHttp = true;
options.AuthorizationEndpointPath = PathString.Empty;
options.TokenEndpointPath = "/token";
// Note: by default, tokens are signed using dynamically-generated
// RSA keys but you can also use your own certificate:
// options.SigningCredentials.AddCertificate(certificate);
});
app.UseMvc();
var hasher = new PasswordHasher<Application>();
using (var database = app.ApplicationServices.GetService<ApplicationDbContext<ApplicationUser, Application, IdentityRole, string>>())
{
database.Applications.Add(new Application
{
Id = "myPublicClient",
DisplayName = "My client application",
Type = ApplicationTypes.Public
});
database.Applications.Add(new Application
{
Id = "myConfidentialClient",
DisplayName = "My client application",
Secret = hasher.HashPassword(null, "secret_secret_secret"),
Type = ApplicationTypes.Confidential
});
database.SaveChanges();
CreateUser(app).Wait();
}
}
最后,我AthorizationProvider.GrantResourceOwnerCredentials()
(我用AspNet.Security.OpenIdConnect.Server)是:
public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context)
{
#region UserChecking
var manager = context.HttpContext.RequestServices.GetRequiredService<AuthManager<ApplicationUser, Application>>();
var user = await manager.FindByNameAsync(context.UserName);
if (user == null)
{
context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Invalid credentials.");
return;
}
// Ensure the user is not already locked out.
if (manager.SupportsUserLockout && await manager.IsLockedOutAsync(user))
{
context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Account locked out.");
return;
}
// Ensure the password is valid.
if (!await manager.CheckPasswordAsync(user, context.Password))
{
context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Invalid credentials.");
if (manager.SupportsUserLockout)
{
await manager.AccessFailedAsync(user);
// Ensure the user is not locked out.
if (await manager.IsLockedOutAsync(user))
{
context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Account locked out.");
}
}
return;
}
if (manager.SupportsUserLockout)
{
await manager.ResetAccessFailedCountAsync(user);
}
if (context.Request.ContainsScope(OpenIdConnectConstants.Scopes.Profile) &&
!context.Request.ContainsScope(OpenIdConnectConstants.Scopes.Email) &&
string.Equals(await manager.GetUserNameAsync(user),
await manager.GetEmailAsync(user),
StringComparison.OrdinalIgnoreCase))
{
context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "The 'email' scope is required.");
return;
}
#endregion
var identity = await manager.CreateIdentityAsync(user, context.Request.GetScopes());
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Options.AuthenticationScheme);
//ticket.SetResources(context.Request.GetResources());
// When I tested with postman
//ticket.SetResources(new[] { "http://localhost:10450/" });
ticket.SetResources(new[] { "http://localhost:10377" });
ticket.SetScopes(context.Request.GetScopes());
context.Validated(ticket);
}
我已经表明的所有代码,我认为可能会导致问题。对不起,如果它长,但我不知道女巫部分导致问题。
访问My protecetd资源(简单装饰的[Authorize]
)我使用这些虚拟代码从我的角度客户
$http.defaults.headers.common['Authorization'] = 'Bearer ' + 'token here';
return $http.get('http://localhost:10450/' + 'api/prvalues');
正如我所说的,我有这样的要求CORS错误。但是,如果我试图得到不受保护的资源(从控制器删除[Authorize]
属性),一切正常。
我找到了解决方案。当我在我的AthorizationProvider.GrantResourceOwnerCredentials()
中设置资源时,我设置了“http://localhost:10377”,但在UseJwtBearerAuthentication
中间件中,我在权限选项(末尾包含斜杠)中设置了“http://localhost:10377/”。这是非常愚蠢的错误。
你有没有尝试使用'AllowCredentials()'和'AllowAnyMethod()'一起在github上的Cors例子中? https://github.com/aspnet/Mvc/blob/5b805bb12db3e47b380038cf6aa5d149f9f02421/test/WebSites/CorsWebSite/Startup.cs#L52-L60 – Tseng
是的。它没有效果 – Stalso