身份服务器 4 邮递员请求令牌不起作用
Identity Server 4 Postman Request Token not working
我有一个 API 并且我正在使用 IdentityServer4 进行身份验证。因此,我有一个解决方案,其中包含我的 API 和我的 Identity Server 项目。到目前为止,一切都很好。我已经在没有身份验证的情况下测试了 API,它工作正常。现在我正在尝试使用 Postman 通过身份验证对其进行测试,但我 运行 遇到了问题。我正在尝试使用授权码授权类型请求令牌,并输入所有需要的信息。我在控制台中不断收到的错误是
09:51:31信息]IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator
显示登录:用户未通过身份验证
我在网上查找了有关如何设置 API 和 Identity Server4 的教程,但所有教程都想创建客户端并显示登录屏幕。我不需要为此 API 登录,而且我不知道我的客户要做什么。我想要的只是让客户端能够使用 clientID 和客户端 Secret 进行授权。然后获取他们可用于其余 API 调用的访问令牌。我怎样才能做到这一点?下面是我的 API 和 IDP
的启动
API 启动
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.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHttpContextAccessor();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:5001";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
// adds an authorization policy to make sure the token is for scope 'api1'
services.AddAuthorization(options =>
{
options.AddPolicy("ApiScope", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("scope", "URCSAPI");
});
});
}
// 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.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
IDP 启动
public class Startup
{
public IWebHostEnvironment Environment { get; }
public Startup(IWebHostEnvironment environment)
{
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
var URCSIDPDataDBConnectionString =
"Server=localhost;Database=URCSIDP;Trusted_Connection=True;MultipleActiveResultSets=true";
// uncomment, if you want to add an MVC-based UI
services.AddControllersWithViews();
var builder = services.AddIdentityServer();
//.AddInMemoryIdentityResources(Config.Ids)
//.AddInMemoryApiResources(Config.Apis)
//.AddInMemoryClients(Config.Clients)
//.AddTestUsers(TestUsers.Users);
// not recommended for production - you need to store your key material somewhere secure
builder.AddDeveloperSigningCredential();
//builder.AddSigningCredential(LoadCertificateFromStore());
var migrationsAssembly = typeof(Startup)
.GetTypeInfo().Assembly.GetName().Name;
builder.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(URCSIDPDataDBConnectionString,
options => options.MigrationsAssembly(migrationsAssembly));
});
builder.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(URCSIDPDataDBConnectionString,
options => options.MigrationsAssembly(migrationsAssembly));
});
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//InitializeDatabase(app);
// uncomment if you want to add MVC
//app.UseStaticFiles();
//app.UseRouting();
app.UseIdentityServer();
// uncomment, if you want to add MVC
//app.UseAuthorization();
//app.UseEndpoints(endpoints =>
//{
// endpoints.MapDefaultControllerRoute();
//});
}
public X509Certificate2 LoadCertificateFromStore()
{
string thumbPrint = "d4d681b3de4cd26fc030292aeea170e553810bdb";
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates.Find(X509FindType.FindByThumbprint,
thumbPrint, true);
if (certCollection.Count == 0)
{
throw new Exception("The specified certificate wasn't found.");
}
return certCollection[0];
}
}
}
更新:添加我用来将信息添加到数据库的配置文件:
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Address()
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{
new ApiResource(
"URCSAPI",
"Unit Rate ContractSystem API")
{
ApiSecrets = { new Secret("apisecret".Sha256()) }
}
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
AccessTokenType = AccessTokenType.Reference,
AccessTokenLifetime = 120,
AllowOfflineAccess = true,
UpdateAccessTokenClaimsOnRefresh = true,
ClientName = "Tesla",
ClientId = "Tesla",
AllowedGrantTypes = GrantTypes.ClientCredentials,
RequirePkce = false,
RedirectUris = new List<string>()
{
"https://localhost:6001/signin-oidc"
},
PostLogoutRedirectUris = new List<string>()
{
"https://localhost:6001/signout-callback-oidc"
},
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Address,
"URCSAPI"
},
ClientSecrets =
{
new Secret("secret".Sha256())
}
}
};
}
如果您尝试保护未与交互式界面一起使用的 API(例如,用户在浏览器中的网站),那么授权码流程不是您想要使用的方法。授权代码流程是一种“交互式”流程,这意味着用户通过浏览器或表单上的移动应用程序登录。如果您的 API 是为机器对机器使用而设计的,或者其他人正在编写代码以直接访问您的 API,那么您应该使用客户端凭据流程。此流程简单地传递 clientId 和 clientSecret 以获取用于 API.
的访问令牌
在 ID4 网站上查看此页面:https://docs.identityserver.io/en/latest/quickstarts/1_client_credentials.html
查看您的 IdentityServer Config.cs 并确保其中的所有内容都是正确的。对于测试,使用 InMemory 存储(取消注释“AddInMemory”行)比数据库中基于 EF 的存储更容易(您可以更快地进行调整,然后稍后移动到基于数据库的存储)。
您将需要一个类型为“ClientCredentials”的客户端(请参阅上文 URL 中的“定义客户端”部分)。他们提供的基本示例如下所示:
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
ClientId = "client",
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api1" }
}
};
我有一个 API 并且我正在使用 IdentityServer4 进行身份验证。因此,我有一个解决方案,其中包含我的 API 和我的 Identity Server 项目。到目前为止,一切都很好。我已经在没有身份验证的情况下测试了 API,它工作正常。现在我正在尝试使用 Postman 通过身份验证对其进行测试,但我 运行 遇到了问题。我正在尝试使用授权码授权类型请求令牌,并输入所有需要的信息。我在控制台中不断收到的错误是
09:51:31信息]IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator 显示登录:用户未通过身份验证
我在网上查找了有关如何设置 API 和 Identity Server4 的教程,但所有教程都想创建客户端并显示登录屏幕。我不需要为此 API 登录,而且我不知道我的客户要做什么。我想要的只是让客户端能够使用 clientID 和客户端 Secret 进行授权。然后获取他们可用于其余 API 调用的访问令牌。我怎样才能做到这一点?下面是我的 API 和 IDP
的启动API 启动
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.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHttpContextAccessor();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:5001";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
// adds an authorization policy to make sure the token is for scope 'api1'
services.AddAuthorization(options =>
{
options.AddPolicy("ApiScope", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("scope", "URCSAPI");
});
});
}
// 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.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
IDP 启动
public class Startup
{
public IWebHostEnvironment Environment { get; }
public Startup(IWebHostEnvironment environment)
{
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
var URCSIDPDataDBConnectionString =
"Server=localhost;Database=URCSIDP;Trusted_Connection=True;MultipleActiveResultSets=true";
// uncomment, if you want to add an MVC-based UI
services.AddControllersWithViews();
var builder = services.AddIdentityServer();
//.AddInMemoryIdentityResources(Config.Ids)
//.AddInMemoryApiResources(Config.Apis)
//.AddInMemoryClients(Config.Clients)
//.AddTestUsers(TestUsers.Users);
// not recommended for production - you need to store your key material somewhere secure
builder.AddDeveloperSigningCredential();
//builder.AddSigningCredential(LoadCertificateFromStore());
var migrationsAssembly = typeof(Startup)
.GetTypeInfo().Assembly.GetName().Name;
builder.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(URCSIDPDataDBConnectionString,
options => options.MigrationsAssembly(migrationsAssembly));
});
builder.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(URCSIDPDataDBConnectionString,
options => options.MigrationsAssembly(migrationsAssembly));
});
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//InitializeDatabase(app);
// uncomment if you want to add MVC
//app.UseStaticFiles();
//app.UseRouting();
app.UseIdentityServer();
// uncomment, if you want to add MVC
//app.UseAuthorization();
//app.UseEndpoints(endpoints =>
//{
// endpoints.MapDefaultControllerRoute();
//});
}
public X509Certificate2 LoadCertificateFromStore()
{
string thumbPrint = "d4d681b3de4cd26fc030292aeea170e553810bdb";
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates.Find(X509FindType.FindByThumbprint,
thumbPrint, true);
if (certCollection.Count == 0)
{
throw new Exception("The specified certificate wasn't found.");
}
return certCollection[0];
}
}
}
更新:添加我用来将信息添加到数据库的配置文件:
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Address()
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{
new ApiResource(
"URCSAPI",
"Unit Rate ContractSystem API")
{
ApiSecrets = { new Secret("apisecret".Sha256()) }
}
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
AccessTokenType = AccessTokenType.Reference,
AccessTokenLifetime = 120,
AllowOfflineAccess = true,
UpdateAccessTokenClaimsOnRefresh = true,
ClientName = "Tesla",
ClientId = "Tesla",
AllowedGrantTypes = GrantTypes.ClientCredentials,
RequirePkce = false,
RedirectUris = new List<string>()
{
"https://localhost:6001/signin-oidc"
},
PostLogoutRedirectUris = new List<string>()
{
"https://localhost:6001/signout-callback-oidc"
},
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Address,
"URCSAPI"
},
ClientSecrets =
{
new Secret("secret".Sha256())
}
}
};
}
如果您尝试保护未与交互式界面一起使用的 API(例如,用户在浏览器中的网站),那么授权码流程不是您想要使用的方法。授权代码流程是一种“交互式”流程,这意味着用户通过浏览器或表单上的移动应用程序登录。如果您的 API 是为机器对机器使用而设计的,或者其他人正在编写代码以直接访问您的 API,那么您应该使用客户端凭据流程。此流程简单地传递 clientId 和 clientSecret 以获取用于 API.
的访问令牌在 ID4 网站上查看此页面:https://docs.identityserver.io/en/latest/quickstarts/1_client_credentials.html
查看您的 IdentityServer Config.cs 并确保其中的所有内容都是正确的。对于测试,使用 InMemory 存储(取消注释“AddInMemory”行)比数据库中基于 EF 的存储更容易(您可以更快地进行调整,然后稍后移动到基于数据库的存储)。
您将需要一个类型为“ClientCredentials”的客户端(请参阅上文 URL 中的“定义客户端”部分)。他们提供的基本示例如下所示:
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
ClientId = "client",
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials,
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
// scopes that client has access to
AllowedScopes = { "api1" }
}
};