当您使用 asp.net 身份有单独的身份项目时,如何在其他项目中验证 JWT 令牌
How to validate JWT token in other project when you have separate project for Identity using asp.net identity
我有两个项目正在解决。一种是使用 asp.net 身份生成 JWT 令牌进行身份管理。在第二个项目中,有 API 是安全的,并且验证令牌是从身份项目生成的,但令牌验证不起作用。
我在邮递员中调用 api 商店路线时遇到此错误。我在授权 header.
中传递令牌
An unhandled exception occurred while processing the request.
HttpRequestException: Response status code does not indicate success:
404 (Not Found).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
IOException: IDX20804: Unable to retrieve document from: '[PII is
hidden]'.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string
address, CancellationToken cancel)
InvalidOperationException: IDX20803: Unable to obtain configuration
from: '[PII is hidden]'.
Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken
cancel)
Stack Query Cookies Headers HttpRequestException: Response status code
does not indicate success: 404 (Not Found).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string
address, CancellationToken cancel)
Show raw exception details System.Net.Http.HttpRequestException:
Response status code does not indicate success: 404 (Not Found). at
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String
address, CancellationToken cancel) IOException: IDX20804: Unable to
retrieve document from: '[PII is hidden]'.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string
address, CancellationToken cancel)
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(string
address, IDocumentRetriever retriever, CancellationToken cancel)
Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken
cancel)
Show raw exception details System.IO.IOException: IDX20804: Unable to
retrieve document from: '[PII is hidden]'. --->
System.Net.Http.HttpRequestException: Response status code does not
indicate success: 404 (Not Found). at
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String
address, CancellationToken cancel) --- End of inner exception stack
trace --- at
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String
address, CancellationToken cancel) at
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String
address, IDocumentRetriever retriever, CancellationToken cancel) at
Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken
cancel) InvalidOperationException: IDX20803: Unable to obtain
configuration from: '[PII is hidden]'.
Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken
cancel)
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
Microsoft.AspNetCore.Authentication.AuthenticationHandler.AuthenticateAsync()
Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext
context, string scheme)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext
context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext
context)
Show raw exception details System.InvalidOperationException: IDX20803:
Unable to obtain configuration from: '[PII is hidden]'. --->
System.IO.IOException: IDX20804: Unable to retrieve document from:
'[PII is hidden]'. ---> System.Net.Http.HttpRequestException: Response
status code does not indicate success: 404 (Not Found). at
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String
address, CancellationToken cancel) --- End of inner exception stack
trace --- at
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String
address, CancellationToken cancel) at
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String
address, IDocumentRetriever retriever, CancellationToken cancel) at
Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync(CancellationToken
cancel) --- End of inner exception stack trace --- at
Microsoft.IdentityModel.Protocols.ConfigurationManager
1.GetConfigurationAsync(CancellationToken
cancel) at
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at
Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at
Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext
context, String scheme) at
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext
context) at
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext
context)
这是我在 Identity 项目中的 Startup.cs class。
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cosmonaut;
using Cosmonaut.Extensions.Microsoft.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Triverse.Identity.Models;
using Triverse.Identity.Services;
using IdentityRole = Microsoft.AspNetCore.Identity.DocumentDB.IdentityRole;
namespace Triverse.Identity
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var endPointUri = Configuration.GetValue<string>("AppSettings:EndpointUri");
var primaryKey = Configuration.GetValue<string>("AppSettings:PrimaryKey");
var databaseId = Configuration.GetValue<string>("AppSettings:DatabaseId");
var collectionId = Configuration.GetValue<string>("AppSettings:CollectionId");
var client = new DocumentClient(new Uri(endPointUri), primaryKey);
services.AddSingleton<IDocumentClient>(client);
// make sure the database exists!
var db = client.CreateDatabaseQuery().Where(d => d.Id == databaseId).AsEnumerable().FirstOrDefault()
?? client.CreateDatabaseAsync(new Database { Id = databaseId }).Result;
var databaseLink = db.SelfLink;
services.AddIdentityWithDocumentDBStores<ApplicationUser, IdentityRole>(
dbOptions =>
{
dbOptions.DocumentUrl = endPointUri;
dbOptions.DocumentKey = primaryKey;
dbOptions.DatabaseId = databaseId;
dbOptions.CollectionId = collectionId;
},
identityOptions =>
{
identityOptions.User.RequireUniqueEmail = true;
});
var cosmosSettings = new CosmosStoreSettings(databaseId, endPointUri, primaryKey);
services.AddCosmosStore<ApplicationUser>(cosmosSettings);
services.AddScoped<IAccountRepository, AccountRepository>();
services.AddTransient<ITokenService, TokenService>();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Audience"],
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
ValidateLifetime = true
};
cfg.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
context.Response.Headers.Add("access-control-expose-headers", "Token-Expired");
}
return Task.CompletedTask;
}
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
}
}
这是我在 Identity 项目中的 appsettings.json。
"Tokens": {
"Key": "4343@!#ewewq",
"Issuer": "http://localhost:44376/",
"Audience": "http://localhost:44385/",
"ExpiryMinutes": "55",
"ValidateLifetime": true
}
这是我的 Startup.cs class 商店项目。
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cosmonaut;
using Cosmonaut.Extensions.Microsoft.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Store.API.Services;
namespace Store.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var endPointUri = Configuration.GetValue<string>("AppSettings:EndpointUri");
var primaryKey = Configuration.GetValue<string>("AppSettings:PrimaryKey");
var databaseId = Configuration.GetValue<string>("AppSettings:DatabaseId");
var client = new DocumentClient(new Uri(endPointUri), primaryKey);
services.AddSingleton<IDocumentClient>(client);
var db = client.CreateDatabaseQuery().Where(d => d.Id == databaseId).AsEnumerable().FirstOrDefault()
?? client.CreateDatabaseAsync(new Database {Id = databaseId}).Result;
var databaseLink = db.SelfLink;
var cosmosSettings = new CosmosStoreSettings(databaseId, endPointUri, primaryKey);
services.AddCosmosStore<Models.Store>(cosmosSettings);
services.AddScoped<IStoreRepository, StoreRepository>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = "http://localhost:44376/";
options.RequireHttpsMetadata = false;
options.Audience = "http://localhost:44385/";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
}
}
这是我在 Store 项目中的控制器方法。
[HttpGet]
[Authorize]
public async Task<IActionResult> GetStores()
{
var stores = new
{
Id = 1,
Name = "T-Shirt",
Price = "120.00"
};
return Ok(stores);
}
这是我从 Identity 项目生成的 JWT 令牌。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzaGFAZG9tYWluLmNvbSIsImp0aSI6IjFjYjNkNjA2LWI4MGQtNGNlZC1hMWFjLThlYmUzNzc1ZGViOSIsIlVuaXF1ZUlkIjoiZjU1ZTM2MWQtYjFkYy00MDg4LTlmYjQtMDg3ZTI4OTFjNWI1IiwidW5pcXVlX25hbWUiOiJzaGFAZG9tYWluLmNvbSIsImZpcnN0TmFtZSI6IlNoYXduIiwibmJmIjoxNTY0OTkwMjA1LCJleHAiOjE1NjQ5OTM1MDUsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDQzNzYvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo0NDM4NS8ifQ.ZBK8Fi14QUc9ObZx7ojg7LPcl8Qs2vrQyhZi7Dbk4Gg
Asp.NET 身份本身并不适用于此用例。您可能希望看起来像 Identity Server,它扩展了 Identity 的功能。它允许您以多种方式验证令牌,
- 它有一个用于验证令牌的端点
- 它公开了一个众所周知的配置端点,该端点提供(以及许多其他内容)用于签署令牌的 RSA 证书的 public 密钥。所以如果你愿意,你可以自己验证签名。
我有两个项目正在解决。一种是使用 asp.net 身份生成 JWT 令牌进行身份管理。在第二个项目中,有 API 是安全的,并且验证令牌是从身份项目生成的,但令牌验证不起作用。
我在邮递员中调用 api 商店路线时遇到此错误。我在授权 header.
中传递令牌An unhandled exception occurred while processing the request. HttpRequestException: Response status code does not indicate success: 404 (Not Found). System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)
InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken cancel)
Stack Query Cookies Headers HttpRequestException: Response status code does not indicate success: 404 (Not Found). System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)
Show raw exception details System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel) IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel) Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel) Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken cancel)
Show raw exception details System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel) --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel) InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken cancel) Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() Microsoft.AspNetCore.Authentication.AuthenticationHandler.AuthenticateAsync() Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, string scheme) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Show raw exception details System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel) --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.ConfigurationManager
1.GetConfigurationAsync(CancellationToken cancel) --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.ConfigurationManager
1.GetConfigurationAsync(CancellationToken cancel) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync() at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
这是我在 Identity 项目中的 Startup.cs class。
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cosmonaut;
using Cosmonaut.Extensions.Microsoft.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Triverse.Identity.Models;
using Triverse.Identity.Services;
using IdentityRole = Microsoft.AspNetCore.Identity.DocumentDB.IdentityRole;
namespace Triverse.Identity
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var endPointUri = Configuration.GetValue<string>("AppSettings:EndpointUri");
var primaryKey = Configuration.GetValue<string>("AppSettings:PrimaryKey");
var databaseId = Configuration.GetValue<string>("AppSettings:DatabaseId");
var collectionId = Configuration.GetValue<string>("AppSettings:CollectionId");
var client = new DocumentClient(new Uri(endPointUri), primaryKey);
services.AddSingleton<IDocumentClient>(client);
// make sure the database exists!
var db = client.CreateDatabaseQuery().Where(d => d.Id == databaseId).AsEnumerable().FirstOrDefault()
?? client.CreateDatabaseAsync(new Database { Id = databaseId }).Result;
var databaseLink = db.SelfLink;
services.AddIdentityWithDocumentDBStores<ApplicationUser, IdentityRole>(
dbOptions =>
{
dbOptions.DocumentUrl = endPointUri;
dbOptions.DocumentKey = primaryKey;
dbOptions.DatabaseId = databaseId;
dbOptions.CollectionId = collectionId;
},
identityOptions =>
{
identityOptions.User.RequireUniqueEmail = true;
});
var cosmosSettings = new CosmosStoreSettings(databaseId, endPointUri, primaryKey);
services.AddCosmosStore<ApplicationUser>(cosmosSettings);
services.AddScoped<IAccountRepository, AccountRepository>();
services.AddTransient<ITokenService, TokenService>();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Audience"],
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
ValidateLifetime = true
};
cfg.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
context.Response.Headers.Add("access-control-expose-headers", "Token-Expired");
}
return Task.CompletedTask;
}
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
}
}
这是我在 Identity 项目中的 appsettings.json。
"Tokens": {
"Key": "4343@!#ewewq",
"Issuer": "http://localhost:44376/",
"Audience": "http://localhost:44385/",
"ExpiryMinutes": "55",
"ValidateLifetime": true
}
这是我的 Startup.cs class 商店项目。
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cosmonaut;
using Cosmonaut.Extensions.Microsoft.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Store.API.Services;
namespace Store.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var endPointUri = Configuration.GetValue<string>("AppSettings:EndpointUri");
var primaryKey = Configuration.GetValue<string>("AppSettings:PrimaryKey");
var databaseId = Configuration.GetValue<string>("AppSettings:DatabaseId");
var client = new DocumentClient(new Uri(endPointUri), primaryKey);
services.AddSingleton<IDocumentClient>(client);
var db = client.CreateDatabaseQuery().Where(d => d.Id == databaseId).AsEnumerable().FirstOrDefault()
?? client.CreateDatabaseAsync(new Database {Id = databaseId}).Result;
var databaseLink = db.SelfLink;
var cosmosSettings = new CosmosStoreSettings(databaseId, endPointUri, primaryKey);
services.AddCosmosStore<Models.Store>(cosmosSettings);
services.AddScoped<IStoreRepository, StoreRepository>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = "http://localhost:44376/";
options.RequireHttpsMetadata = false;
options.Audience = "http://localhost:44385/";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
}
}
这是我在 Store 项目中的控制器方法。
[HttpGet]
[Authorize]
public async Task<IActionResult> GetStores()
{
var stores = new
{
Id = 1,
Name = "T-Shirt",
Price = "120.00"
};
return Ok(stores);
}
这是我从 Identity 项目生成的 JWT 令牌。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzaGFAZG9tYWluLmNvbSIsImp0aSI6IjFjYjNkNjA2LWI4MGQtNGNlZC1hMWFjLThlYmUzNzc1ZGViOSIsIlVuaXF1ZUlkIjoiZjU1ZTM2MWQtYjFkYy00MDg4LTlmYjQtMDg3ZTI4OTFjNWI1IiwidW5pcXVlX25hbWUiOiJzaGFAZG9tYWluLmNvbSIsImZpcnN0TmFtZSI6IlNoYXduIiwibmJmIjoxNTY0OTkwMjA1LCJleHAiOjE1NjQ5OTM1MDUsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDQzNzYvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo0NDM4NS8ifQ.ZBK8Fi14QUc9ObZx7ojg7LPcl8Qs2vrQyhZi7Dbk4Gg
Asp.NET 身份本身并不适用于此用例。您可能希望看起来像 Identity Server,它扩展了 Identity 的功能。它允许您以多种方式验证令牌,
- 它有一个用于验证令牌的端点
- 它公开了一个众所周知的配置端点,该端点提供(以及许多其他内容)用于签署令牌的 RSA 证书的 public 密钥。所以如果你愿意,你可以自己验证签名。