I’m trying to use keycloak with a dotnet 5 MVC app. It’s basically just 1 page I want to protect.
After a few hours of testing stuff I now get it to work with localhost, if I try to access the resource I go to the keycloak login and after a successful login I go back to the same URL I tried to access originally. But when I host it on IIS it doesn’t work anymore, after a successful login I get redirected to the same URL but with /signin-oidc appended and a status 500.
Keycloak is behind a nginx reverse proxy so maybe that has to do with it?
IIS eventlog shows the following error.
Category: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
EventId: 1
SpanId: 7eafa51ac49c4546
TraceId: bfceaf44d2f5fd438b04aaf4bdf93170
ParentId: 0000000000000000
RequestId: 8000010a-0000-f300-b63f-84710c7967bb
RequestPath: /signin-oidc
An unhandled exception has occurred while executing the request.
Exception:
System.Exception: An error was encountered while handling the remote login.
---> System.Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
This is my code at the moment.
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
//options.Cookie.SameSite = SameSiteMode.None;
//options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
//options.Cookie.IsEssential = true;
})
.AddOpenIdConnect(options =>
{
options.ClientId = clientId;
options.Authority = keylcoakUrl;
options.ClientSecret = clientSecret;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
if (Environment.IsDevelopment())
{ // to make sure this is only used during development
options.RequireHttpsMetadata = false;
}
});
Thanks a lot!
2
Answers
Regarding your message, State is empty. In accordance with Oauth2, the state is the parameter of proving initiated authorization request.
So, firstly your server sends client_id (where to authenticate) and a state, in return it gets a login page. After exchanging your username and password to code, the server must return the state as well, for a reason of preventing XSRF attacks. So, possibly somehow, the server does not send a state or don’t get it from Keycloak.
I was getting this error System.Exception: An error was encountered while handling the remote login; in my case, it was because I lacked the code below. Add it in the Startup > ConfigureServices().
Because the app is behind an Nginx proxy, I guess it needs some help regarding the ForwardedHeadersOptions.