ASP.NET Core WebAPI で SSL/TLSの自己証明書をMacに組み込む方法をご紹介します。
なお、ASP.NET Core MVC でも違いはないので心配ないです。
これを行っていないと、ASP.NET Core WebAPI プロジェクト実行時、いきなり以下のエラーが発生して実行できないという問題が起きます。これはなかなかつらいです。
fail: Microsoft.AspNetCore.Server.Kestrel[0] Uncaught exception from the OnConnectionAsync method of an IConnectionAdapter. System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> Interop+AppleCrypto+SslException: Internal error --- End of inner exception stack trace --- at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception) at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslStream.BeginAuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, Object asyncState) at System.Net.Security.SslStream.<>c.<AuthenticateAsServerAsync>b__51_0(SslServerAuthenticationOptions arg1, CancellationToken arg2, AsyncCallback callback, Object state) at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl[TArg1,TArg2](Func`5 beginMethod, Func`2 endFunction, Action`1 endAction, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func`5 beginMethod, Action`1 endMethod, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func`5 beginMethod, Action`1 endMethod, TArg1 arg1, TArg2 arg2, Object state) at System.Net.Security.SslStream.AuthenticateAsServerAsync(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.HttpConnection.ApplyConnectionAdaptersAsync()
この問題を解決するには、Mac に SSL/TLS 自己証明書を組み込む必要があります。
これには以下の手順で証明書を作成していきます。
$ openssl genrsa -out key.pem 2048 $ openssl req -new -sha256 -key key.pem -out csr.csr
以下のように設定します。Common Name に localhost、password に password を指定しています。
Country Name (2 letter code) []: State or Province Name (full name) []: Locality Name (eg, city) []: Organization Name (eg, company) []: Organizational Unit Name (eg, section) []: Common Name (eg, fully qualified host name) []:localhost Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:password
さらに以下のコマンドを実行します。
$ openssl req -x509 -sha256 -days 365 -key key.pem -in csr.csr -out certificate.pem $ openssl pkcs12 -export -out localhost.pfx -inkey key.pem -in certificate.pem
次に、Visual Studio Code のプロジェクトで、Kestrel Https Extension Package をインストールします。
$ dotnet add package Microsoft.AspNetCore.Server.Kestrel.Https $ dotnet restore
しかし、以下のようにエラーが表示されてしまう場合があります。
/Users/xxxxx/Projects/myapi/myapi.csproj : warning NU1608: 依存関係の制約外で検出されたパッケージのバージョン: Microsoft.AspNetCore.App 2.1.0 では Microsoft.AspNetCore.Server.Kestrel.Https (= 2.1.0) が必要ですが、バージョン Microsoft.AspNetCore.Server.Kestrel.Https 2.1.3 は解決されました。 /Users/xxxxx/Projects/myapi/myapi.csproj : error NU1107: Microsoft.AspNetCore.Connections.Abstractions でバージョンの競合が検出されました。この問題を解決するには、プロジェクトから直接パッケージを参照してください。 /Users/xxxxx/Projects/myapi/myapi.csproj : error NU1107: myapi -> Microsoft.AspNetCore.Server.Kestrel.Https2.1.3 -> Microsoft.AspNetCore.Server.Kestrel.Core 2.1.3 -> Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions 2.1.3 -> Microsoft.AspNetCore.Connections.Abstractions (>= 2.1.3) /Users/xxxxx/Projects/myapi/myapi.csproj : error NU1107: myapi -> Microsoft.AspNetCore.App 2.1.0 -> Microsoft.AspNetCore.Connections.Abstractions (= 2.1.0).
エラーメッセージを確認し、.csproj の Kestrel Https Extension Package のバージョンを 2.1.0 にして再度、dotnet resote
を実行するとエラーが表示されなくなります。
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.1.0" /> </ItemGroup>
最後に Program.cs を以下のように SSL/TLS 証明書を読み込むように設定します。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Server.Kestrel.Https; using System.Net; namespace myapi { public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseKestrel(options => { options.Listen(IPAddress.Loopback,5001, ListenOptions => { ListenOptions.UseHttps("localhost.pfx","password"); }); } ) .UseStartup<Startup>(); } }
これで WebAPI を HTTPS で表示できるようになりました。
・参考サイト