我们正在使用IdentityServer4(" http://docs.identityserver.io/en/release/quickstarts/0_overview.html")和EntityFrameworkCore来存储操作和配置数据。要添加签名凭据,我们使用的是x509自签名证书。我们使用以下命令创建x509自签名证书:makecert -r -pe -n "CN=CertName_IdentityServer" -b 01/01/2015 -e 01/01/2039 -eku 1.3.6.1.5.5.7.3.3 -sky signature -a sha256 -len 2048 identityserver.cer
。并将此证书添加为解决方案中的嵌入式源。
这是我们的startup.cs文件:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfiguration>(Configuration);
//connection string
string connectionString = Configuration.GetConnectionString("IdentityServer");
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
ConfigureSigningCerts(services);
services.AddIdentityServer()
// this adds the config data from DB (clients, resources)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
}) // this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
});
}
private static void ConfigureSigningCerts(IServiceCollection services)
{
var assembly = typeof(Startup).GetTypeInfo().Assembly;
/*
* IdentityServer.WebApi\
* Certificates\
* identityserver.cer
*
* {assembly name}.{directory}.{file name}
*/
using (Stream resource = assembly.GetManifestResourceStream("IdentityServer.WebApi.Certificates.identityserver.cer"))
using (var reader = new BinaryReader(resource))
{
var signingCert = new X509Certificate2(reader.ReadBytes((int)resource.Length));
var keys = new List<SecurityKey>();
if (signingCert == null) throw new InvalidOperationException("No valid signing certificate could be found.");
var signingCredential = new SigningCredentials(new X509SecurityKey(signingCert), "RS256");
services.AddSingleton<ISigningCredentialStore>(new DefaultSigningCredentialsStore(signingCredential));
var validationCredential = new SigningCredentials(new X509SecurityKey(signingCert), "RS256");
keys.Add(validationCredential.Key);
services.AddSingleton<IValidationKeysStore>(new DefaultValidationKeysStore(keys));
}
}
当我们在本地主机上执行应用程序时,发现端点工作正常,但在调用connect/token
端点时,我们收到以下错误消息:
crit: IdentityServer4.Hosting.IdentityServerMiddleware[0]
Unhandled exception: System.InvalidOperationException: IDX10638: Cannot created the SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures. Key: Microsoft.IdentityModel.Tokens.X509SecurityKey.
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt) in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 209
at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__4.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 67
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Services.DefaultTokenService.<CreateSecurityTokenAsync>d__9.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenService.cs:line 210
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.<CreateAccessTokenAsync>d__14.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 313
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessTokenRequestAsync>d__13.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 249
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 84
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Endpoints.TokenEndpoint.<ProcessTokenRequestAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 98
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Endpoints.TokenEndpoint.<ProcessAsync>d__6.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 70
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\IdentityServerMiddleware.cs:line 54
crit: IdentityServer4.Hosting.IdentityServerMiddleware[0]
Unhandled exception: System.InvalidOperationException: IDX10638: Cannot created the SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures. Key: Microsoft.IdentityModel.Tokens.X509SecurityKey.
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt) in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 209
at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__4.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 67
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Services.DefaultTokenService.<CreateSecurityTokenAsync>d__9.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenService.cs:line 210
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.<CreateAccessTokenAsync>d__14.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 313
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessTokenRequestAsync>d__13.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 249
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 84
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Endpoints.TokenEndpoint.<ProcessTokenRequestAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 98
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Endpoints.TokenEndpoint.<ProcessAsync>d__6.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 70
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\IdentityServerMiddleware.cs:line 54
答案 0 :(得分:1)
如果您使用文件,您可能需要执行其他步骤并指定密码以允许访问私钥。
这应该有希望帮助:How to create a self signed certificate with the private key inside in a file in one simple step?
另一种方法是在本地计算机证书存储中生成证书,然后通过证书管理MMC管理单元将其导出。
答案 1 :(得分:0)
从Powershell(以管理员身份运行Powershell):
$cert = New-SelfSignedCertificate -DnsName yourSiteHere.com -type Custom -CertStoreLocation cert:\localmachine\my -KeyExportPolicy Exportable
使用上述命令,颁发者将成为yourSiteHere,到期日期是默认的一年。它还将具有长度为2048的RSA密钥。 然后,您可以使用certmgr实用程序导出证书(Powershell中还有更多命令可以导出,而我还没有使用过)。 有关更多信息,请参见以下链接:
https://www.petri.com/create-self-signed-certificate-using-powershell
https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
现在,在IdentityServer4中,我扩展了IIdentityServerBuilder类,以提供一种用于从该类型的文件进行证书绑定的方法-很快,如果您有一个静态类,并且它的方法采用“ this someClass”形式的参数,则这是一个“扩展”。您可以扩展任何类,甚至可以扩展C#内部的那些标准类(例如字符串等)。如果执行此操作,则在该类或该类型的变量之后键入句点时,您的方法也将带有Intellisense。这意味着我可以在启动时从构建器访问我的方法(您只需要在Startup.cs中的扩展类的名称空间中放置一个using即可)
public static class SigningCredentialExtension
{
public static IIdentityServerBuilder GetCertFromAzure(this IIdentityServerBuilder builder)
{
//Note: in order for the certificate to be visible to the app,
//an application setting "WEBSITE_LOAD_CERTIFICATES" with the value
//of your SSL cert's thumbprint must be added to your IdentityServer
//webapp on Azure.
var thumbprint = "your cert's thumbprint";
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindByThumbprint,
certThumbprint, true);
if (certs.Count > 0)
{
X509Certificate2 cert =
new X509Certificate2(certs[0].Export(X509ContentType.Pfx,
"your cert's password"));
builder.AddSigningCredential(cert);
builder.AddValidationKey(cert);
}
return builder;
}
public static IIdentityServerBuilder GetCertFromEmbeddedProjectFile(
IIdentityServerBuilder builder)
{
var assembly = Assembly.GetExecutingAssembly();
var fileName = "Your.Project.Namespace.FileName.fileExtension";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
Byte[] raw = new Byte[stream.Length];
for (Int32 i = 0; i < stream.Length; i++)
{
raw[i] = (Byte)stream.ReadByte();
}
X509Certificate2 cert = new X509Certificate2(raw, password);
builder.AddSigningCredential(cert);
builder.AddValidationKey(cert);
}
return builder;
}
}
所以-在您的项目中包括上述类,请确保Startup.cs可以看到它(如有必要,请使用),删除您的ConfigureSigningCerts()方法,并在“ services.AddIdentityServer()”行之后输入“。”然后您会在列表中看到扩展方法。使用所需的方法。您无需指定参数,该方法将自动获取构建器。生成器将在之后返回以供以后的方法使用。