'How to sign-in .NET 5 MVC webapp with KeyCloak using OpenIdConnect

I have configured my OpenIdConnect within KeyCloak and now I am trying to connect to it using .NET 5 MVC application.

How to sign-in correctly?

This is what I have so far

  1. When I try to access protected resource I get redirected to KeyCloak for a correct "relm" to sign in.

enter image description here

The user can sign in and the application flows through the OpenIDConnect to the method OnTokenValidated.

  1. In this event, I can see that the user has successfully logged in and while debugging see the authentication details

    string firstName = idToken.Claims.SingleOrDefault(c => c.Type == JwtRegisteredClaimNames.GivenName)?.Value;

where firstName gets populated to the correct user.

  1. Redirect issue

The redirection to my application keeps going into OnTokenValidated as a loop but the application does not register that the user is signed in

My code looks like thus:

 public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        const string clientId = "demoClient";
        const string clientSecret = "4342abf9-CC85-4cf2-ba83-316c56a523b9";  // representative
        const string authority = "http://localhost:8080/auth/realms/demo";   // name of authority

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddAuthentication(options =>
                {
                    options.DefaultScheme = OpenIdConnectDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                    options.DefaultAuthenticateScheme = "oidc";
                    options.DefaultSignInScheme = "Cookies";
                })
                 .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.CallbackPath = "/home/index";
                options.Authority = authority;
                options.ClientId = clientId;
                options.ClientSecret = clientSecret;
                options.SaveTokens = true;
                options.ResponseType = OpenIdConnectResponseType.IdTokenToken;
                options.RequireHttpsMetadata = false; // dev only
                options.GetClaimsFromUserInfoEndpoint = true;

                //options.Scope.Add("openid");  // TODO: not sure how to configure

                options.Scope.Add("profile");
                options.Scope.Add("email");

                options.SaveTokens = true;

                options.Events = new OpenIdConnectEvents
                {
                    OnAuthorizationCodeReceived = context =>
                    {
                        // short lived code used to authorise the application on back channel
                        return Task.CompletedTask;
                    },
                    OnRedirectToIdentityProvider = async n =>
                    {
                        //save url to state
                       //  n.ProtocolMessage.State = n.HttpContext.Request.Path.Value.ToString();
                    },
                    OnTokenValidated = context =>
                    {

                        return Task.CompletedTask;
                    },
                    OnTicketReceived = context =>
                    {
                        return Task.CompletedTask;
                    },
                    OnAuthenticationFailed = context =>
                    {
                        context.Response.Redirect("/Home/Error?errormessage = " + context.Exception.Message);
                        // context.HandleResponse(); // Suppress the exception
                        return Task.CompletedTask;
                    },
                    OnRemoteFailure = context =>
                    {
                        context.Response.Redirect("/Home/Error");
                        context.HandleResponse();
                        return Task.FromResult(0);
                    },
                };

            });


Solution 1:[1]

To configure an ASP.NET MVC web application client to authenticate with Keycloak use the following configuration:

  • Add your client in the realm and set the access type as "confidential"
  • Make sure that the authorization is enabled
  • If it is a strongly trusted client, you could also enable the Direct Access Grants, but this is optional.

enter image description here

In the field "Valid Redirect URI" set "https://your.app.uri/signin-oidc" and "https://your.app.uri/signout-callback-oidc"

In the field "Web Origins" set "*" In the field "Backchannel Logout URL" you may set "https://your.app.uri/signin-oidc"

enter image description here

Then configure your client-Id, Authority and Client Secret as you did in the code that you provided in the question.

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 antoprd