'How to connect ASP.NET Core 6 MVC web application with KeyCloak
I need to use KeyCloak as SSO server, to authorize, first, some Mvc web application and second, some Apis.
I'm at the point I need to configure Keycloak for my WebApp, so I manage to find that link :
but it is not very helpful.
I have Keycloak docker image running, I create my real, client and a user, so everything seems fine for KeyCloak, at least, I think so.
I created a basic ASP.NET Core MVC application and updated the program.cs class to setup as the example in the link so :
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System.IdentityModel.Tokens.Jwt;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddMvc();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
// Store the session to cookies
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
// OpenId authentication
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie("Cookies")
.AddOpenIdConnect(options =>
{
// URL of the Keycloak server
options.Authority = "https://localhost:8080/auth/realms/BrunoRealm";
// Client configured in the Keycloak
options.ClientId = "MonApplication";
// For testing we disable https (should be true for production)
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.ClientId = "MonApplication";
// Client secret shared with Keycloak
options.ClientSecret = "nrnsK6od01BpzJ0NTzvdC2DLt0ta72zp";
options.GetClaimsFromUserInfoEndpoint = true;
// OpenID flow to use
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
});
var app = builder.Build();
app.UseAuthentication();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
I put an [Authorize] attribute on the privacy method of home controller but when I try to access privacy page, I have an exception talking about SSL :
An unhandled exception occurred while processing the request.
IOException: Cannot determine the frame size or a corrupted frame was received.
System.Net.Security.SslStream.GetFrameSize(ReadOnlySpan buffer)HttpRequestException: The SSL connection could not be established, see inner exception.
System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, bool async, Stream stream, CancellationToken cancellationToken)
IOException: IDX20804: Unable to retrieve document from: '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken cancel)
Stack Query Cookies Headers Routing
IOException: Cannot determine the frame size or a corrupted frame was received.System.Net.Security.SslStream.GetFrameSize(ReadOnlySpan buffer)
System.Net.Security.SslStream.ReceiveBlobAsync(TIOAdapter adapter)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable+ConfiguredValueTaskAwaiter.GetResult()
System.Net.Security.SslStream.ForceAuthenticationAsync(TIOAdapter adapter, bool receiveFirst, byte[] reAuthenticationData, bool isApm)
System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, bool async, Stream stream, CancellationToken cancellationToken)Show raw exception details
HttpRequestException: The SSL connection could not be established, see inner exception.System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, bool async, Stream stream, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable+ConfiguredValueTaskAwaiter.GetResult()
System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable+ConfiguredValueTaskAwaiter.GetResult()
System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable+ConfiguredValueTaskAwaiter.GetResult()
System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request)
System.Threading.Tasks.TaskCompletionSourceWithCancellation.WaitWithCancellationAsync(CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable+ConfiguredValueTaskAwaiter.GetResult()
System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable+ConfiguredValueTaskAwaiter.GetResult()
System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, bool async, bool doRequestAuth, CancellationToken cancellationToken)
System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable+ConfiguredValueTaskAwaiter.GetResult()
System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
System.Net.Http.HttpClient.
g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, bool disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)Show raw exception details
IOException: IDX20804: Unable to retrieve document from: '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken cancel)Show raw exception details
InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
Microsoft.IdentityModel.Protocols.ConfigurationManager.GetConfigurationAsync(CancellationToken cancel)
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsyncInternal(AuthenticationProperties properties)
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsync(AuthenticationProperties properties)
Microsoft.AspNetCore.Authentication.AuthenticationHandler.ChallengeAsync(AuthenticationProperties properties)
Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I have no idea where to look at. Have I to configure SSL on my docker image. Must I implement a login page but, in that case how to call KeyCloak?
So in short what to do know?
Solution 1:[1]
Keycloak does not support HTTPS on port 8080 (by default). Change https:// to http:// in
options.Authority = "https://localhost:8080/auth/realms/BrunoRealm";
so that it reads
options.Authority = "http://localhost:8080/auth/realms/BrunoRealm";
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | sventorben |
