2

我目前正在开发一个 Web 应用程序,该应用程序需要从开发环境中使用自签名证书的 IDM 系统中检索数据(我不知道原因)。它使用 OAuth 作为授权方法,所以我目前正在使用 .Net Core 3.1 OAuth 库,它在从 IDM 成功重定向后抛出 SSL 异常。我从 IDM 获得了自签名证书(PFX 文件),但我不知道在哪里添加它。

public void ConfigureServices(IServiceCollection services)
{
    //services.Configure<KestrelServerOptions>(pConfiguration.GetSection("Kestrel"));
    services.AddControllers();
    services.AddControllersWithViews();
    services
        .AddAuthentication(authenticationOptions => {
            authenticationOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            authenticationOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            authenticationOptions.DefaultChallengeScheme = "the_scheme_challenge";
        })
        .AddCookie()
        .AddOAuth(authenticationScheme: "the_scheme", configureOptions: oauthOptions => {
            oauthOptions.ClientId = pConfiguration["the_scheme:ClientId"];
            oauthOptions.ClientSecret = pConfiguration["the_scheme:ClientSecret"];
            oauthOptions.CallbackPath = new PathString(pConfiguration["the_scheme:CallbackURL"]);
            oauthOptions.AuthorizationEndpoint = "https://the.idm.dev/idm/oauth/authorize";
            oauthOptions.TokenEndpoint = "https://the.idm.dev/idm/oauth/token";
            oauthOptions.UserInformationEndpoint = "https://the.idm.dev/idm/oauth/userinfo";
            oauthOptions.Scope.Add(pConfiguration["the_scheme:Scope"]);
            oauthOptions.SaveTokens = true;
        });
}

任何建议都会被接受,我不想用一些不安全的代码从头开始编写所有的 HTTP 请求和逻辑(比如允许接受任何证书)。

我已经针对其他 OpenID 提供程序测试了代码并且它有效。

4

3 回答 3

2

对于 .Net Core,您应该会发现 SSL 信任继承自操作系统的默认信任存储。这通常是 Windows 证书存储或 Mac OS 密钥链。

我的Developer SSL Trust写了一些关于此的注释,因为:

  • OAuth 技术在开发人员 PC 上使用自签名证书很常见
  • 不同技术之间的信任配置差异很大
  • 正如您所说,我们希望在不编写不安全代码的情况下为自己提供高效的设置
于 2020-02-24T08:24:07.493 回答
1

请检查此代码片段取自使用 HTTPS、自签名证书和 ASP.NET Core 进行本地开发

public class Program
{
    public static void Main(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddEnvironmentVariables()
            .AddJsonFile("certificate.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"certificate.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true)
            .Build();

        var certificateSettings = config.GetSection("certificateSettings");
        string certificateFileName = certificateSettings.GetValue<string>("filename");
        string certificatePassword = certificateSettings.GetValue<string>("password");

        var certificate = new X509Certificate2(certificateFileName, certificatePassword);

        var host = new WebHostBuilder()
            .UseKestrel(
                options =>
                {
                    options.AddServerHeader = false;
                    options.Listen(IPAddress.Loopback, 44321, listenOptions =>
                    {
                        listenOptions.UseHttps(certificate);
                    });
                }
            )
            .UseConfiguration(config)
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseStartup<Startup>()
            .UseUrls("https://localhost:44321")
            .Build();

        host.Run();
    }
}
于 2020-02-21T22:33:54.547 回答
1

我喜欢 Gary 的回答,安装证书似乎是最好的选择。

但是,我相信您可以使用 BackchannelHttpHandler 设置自己的证书验证。

.AddOAuth(authenticationScheme: "the_scheme", configureOptions: oauthOptions => {
    oauthOptions.ClientId = pConfiguration["the_scheme:ClientId"];
    oauthOptions.ClientSecret = pConfiguration["the_scheme:ClientSecret"];
    oauthOptions.CallbackPath = new PathString(pConfiguration["the_scheme:CallbackURL"]);
    oauthOptions.AuthorizationEndpoint = "https://the.idm.dev/idm/oauth/authorize";
    oauthOptions.TokenEndpoint = "https://the.idm.dev/idm/oauth/token";
    oauthOptions.UserInformationEndpoint = "https://the.idm.dev/idm/oauth/userinfo";
    oauthOptions.Scope.Add(pConfiguration["the_scheme:Scope"]);
    oauthOptions.SaveTokens = true;
                    
    //Handle the certificate checks yourself, 
    oauthOptions.BackchannelHttpHandler = new HttpClientHandler()
    {
        ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => {
            if (cert.Thumbprint == Configuration["TrustedCertificateThumbprint"])
            {
                      return true;
            }
                                
        }
    };
            
});
});  


    

这与您可能已经看到的其他示例类似,但您可以添加自己的检查,例如证书指纹或签名机构,而不是只返回 true。

如果您可以控制 ID 服务器,您还可以从 Letencrypt 之类的地方获得具有受信任根的证书

于 2020-02-24T14:32:01.153 回答