// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using IdentityServer4;
using IdentityServerAspNetIdentity.Data;
using IdentityServerAspNetIdentity.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using System.IO;
using System;
using System.Security.Cryptography;
using System.Xml.Serialization;
using Newtonsoft.Json;
using System.Security.Cryptography.X509Certificates;
using IdentityServerAspNetIdentity.Securitys;
using System.Runtime.ConstrainedExecution;
using System.Reflection.Emit;
namespace IdentityServerAspNetIdentity
{
public class Startup
{
public IWebHostEnvironment Environment { get; }
public IConfiguration Configuration { get; }
public Startup(IWebHostEnvironment environment, IConfiguration configuration)
{
Environment = environment;
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
// see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
options.EmitStaticAudienceClaim = true;
})
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients)
.AddAspNetIdentity<ApplicationUser>();
//X509Certificate2 certificate2 = new X509Certificate2("server2023.pfx");
//RSA privateKey = certificate2.GetRSAPrivateKey();
// var key = certificate2.GetRSAPrivateKey() ?? certificate2.GetRSAPublicKey();
//var rsakey2 = LoadRsaKey();
//Microsoft.IdentityModel.Tokens.SigningCredentials
// RsaKeyService rsk=new RsaKeyService(TimeSpan.FromDays(1));
// var k1= rsk.GetKey();
builder.AddSigningCredential(CreateSigningCredentials());
services.AddAuthentication()
.AddGoogle(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
// register your IdentityServer with Google at https://console.developers.google.com
// enable the Google+ API
// set the redirect URI to https://localhost:5001/signin-google
options.ClientId = "copy client ID from Google here";
options.ClientSecret = "copy client secret from Google here";
});
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
private static SecurityKey LoadRsaKey()
{
var rsaCert = new X509Certificate2("server2023.pfx");
SecurityKey rsaPrivateKey = new RsaSecurityKey(rsaCert.GetRSAPrivateKey());
return rsaPrivateKey;
}
private SigningCredentials CreateSigningCredentials()
{
// return new SigningCredentials(GetSecurityKey(), SecurityAlgorithms.RsaSha256Signature);
return new SigningCredentials(GetSecurityKey(), SecurityAlgorithms.RsaSha256);
}
private SecurityKey GetSecurityKey()
{
return new RsaSecurityKey(GetRSAParameters());
}
private RSAParameters GetRSAParameters()
{
var generator = new RsaKeyGenerator();
RsaSecurityKey key = generator.GenerateKey(2048, "my_key_id");
JsonWebKey jwk = JsonWebKeyConverter.ConvertFromRSASecurityKey(key);
return new RSAParameters
{
D = Base64UrlEncoder.DecodeBytes(jwk.D),
DP = Base64UrlEncoder.DecodeBytes(jwk.DP),
DQ = Base64UrlEncoder.DecodeBytes(jwk.DQ),
Exponent = Base64UrlEncoder.DecodeBytes(jwk.E),
InverseQ = Base64UrlEncoder.DecodeBytes(jwk.QI),
Modulus = Base64UrlEncoder.DecodeBytes(jwk.N),
P = Base64UrlEncoder.DecodeBytes(jwk.P),
Q = Base64UrlEncoder.DecodeBytes(jwk.Q)
};
}
}
}
https://stackoverflow.com/questions/5244129/use-rsa-private-key-to-generate-public-key
https://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php
https://www.scottbrady91.com/c-sharp/rsa-key-loading-dotnet
생성
https://web3auth.io/community/t/how-to-create-jwks-from-pem-format/2718/2
https://onecellboy.tistory.com/341
https://connect2id.com/products/nimbus-jose-jwt/examples/jwk-generation
https://www.siakabaro.com/how-to-generate-an-rsa-json-web-key-jwk-in-net/
Local 테스트
https://localhost:7200/ProjModel/SC6122/UPV/999U/UPV_S3DTrain_All_1___/
UPV 에서 URL
ID4 자격증명 추가
https://copyprogramming.com/howto/addsigningcredential-for-identityserver4
단일 프로젝트
https://copyprogramming.com/howto/identityserver4-and-api-in-single-project
강제 로그인 이동
https://stackoverflow.com/questions/48411620/force-login-page-on-token-expiry
리후레쉬가 널이
https://stackoverflow.com/questions/40630353/identityserver4-refresh-token-is-null?rq=3
OIDC Client
https://github.com/IdentityModel/IdentityModel.OidcClient
ID4 인증서 연동
https://stackoverflow.com/questions/70547314/certificate-for-addsigningcredential
jwsk
https://stackoverflow.com/questions/60772007/how-to-generate-and-add-a-signing-key-for-identity-server-4
https://stackoverflow.com/questions/71898390/identity-server-how-to-override-jwks-file-manually
https://github.com/IdentityServer/IdentityServer4/issues/4977