j0zeft
j0zeft

Reputation: 659

Using Keycloak as a Single Sign On solution for ASP.Net applications

I'm trying to use Keycloak as a Single Sign On server for more than one ASP.Net apps. I found a library on Github by called KeycloakOwinAuthentication and I cloned the sample code provided within twice to use as two different applications.

I configured 2 apps (App1 and App2) within the same Realm in Keycloak, created the test user with all roles and tried to log in.

Expected Behaviour: Log in from app one, refresh App2 and you're automatically logged in

Actual result: Log in from App one, refresh app 2 and get "Server Error in '/' Application. If I log out from App1 and try to refresh App2, it works back just fine!

My 2 sample apps can be found here... My ActionResult for the protected page, which shows the token in the view looks like this:

 [Authorize]
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";
        var userPrincipal = User as ClaimsPrincipal;
        ViewBag.Something = userPrincipal.Identity.ToString();
        return View(userPrincipal);

    }

and my startup page looks like this:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        const string persistentAuthType = "Keycloak_Cookies";

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = persistentAuthType
        });

        app.SetDefaultSignInAsAuthenticationType(persistentAuthType);

        app.UseKeycloakAuthentication(new KeycloakAuthenticationOptions
        {
            Realm = "MyRealm",
            ClientId = "App3",
            ClientSecret = "KeycloakClientSecret",
            KeycloakUrl = "http://localhost:8080/auth",
            SignInAsAuthenticationType = persistentAuthType
        });

Is there a specefic configuration that I have missed? I used my testing Realm as well as a working Realm with 3 different apps (not Asp) but I failed to be logged in at all clients. I was using the same Browser with two tabs to ensure that all cookies are accessible...

Error Text:

Server Error in '/' Application.
IDX10214: Audience validation failed. Audiences: 'App1'. Did not match:  validationParameters.ValidAudience: 'null' or validationParameters.ValidAudiences: 'null, App2'
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: 'App1'. Did not match:  validationParameters.ValidAudience: 'null' or validationParameters.ValidAudiences: 'null, App2'
Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Upvotes: 1

Views: 8240

Answers (2)

M. Mojrian
M. Mojrian

Reputation: 31

The newer versions of Keycloak server (>=6.x) has changed how the audience claim ("aud") is set in the access token. The library (Owin.Security.Keyclaok-3) assumes that the Keycloak Client ID is in the "aud" claim, which no longer is the case by default.

One way to fix it is in Keycloak admin UI, add a mapper in to the Keycloak Client that's being used.

Name: Audience Mapper type: Audience Included Client Audience: [Client ID] Also, make sure the .NET library is configured with option

DisableAllRefreshTokenValidation = true

in startup.cs which is required for newer Keycloak server versions (validation of refresh token is done on the server side anyways).

Upvotes: 0

j0zeft
j0zeft

Reputation: 659

I went deeper through the code of the whole library and found that there is a flag which disables the Audience check. It should be set in the Keycloak configuration in the Startup.cs file. The flag DisableAudienceValidation is false by default, but by adding it to the configuration and set its value to true, Audience validation is skipped.

            app.UseKeycloakAuthentication(new KeycloakAuthenticationOptions
        {
            Realm = "DotNetApps",
            ClientId = "TestingApp",
            ClientSecret = "Client_Secret_Goes_Here",
            KeycloakUrl = "http://localhost:8080/auth",
            SignInAsAuthenticationType = persistentAuthType,
            DisableAudienceValidation = true

        });

Upvotes: 1

Related Questions