public async Task <ClaimsIdentity> ValidateIdentity(KeycloakAuthenticationOptions options,
                                                            string authenticationType = null)
        {
            // Validate JWTs provided
            SecurityToken idToken = null, refreshToken = null, accessToken = null;
            var           tokenHandler = new KeycloakTokenHandler();

            if (_keycloakToken.IdToken != null)
            {
                idToken = tokenHandler.ValidateToken(_keycloakToken.IdToken, options);
            }
            if (_keycloakToken.RefreshToken != null)
            {
                refreshToken = tokenHandler.ValidateToken(_keycloakToken.RefreshToken, options);
            }
            if (_keycloakToken.AccessToken != null)
            {
                if (options.UseRemoteTokenValidation)
                {
                    accessToken = await KeycloakTokenHandler.ValidateTokenRemote(_keycloakToken.AccessToken, options);
                }
                else
                {
                    accessToken = tokenHandler.ValidateToken(_keycloakToken.AccessToken, options);
                }
            }

            // Create the new claims identity
            return // TODO: Convert to MS claims parsing in token handler
                   (new ClaimsIdentity(
                        GenerateJwtClaims(accessToken as JwtSecurityToken, idToken as JwtSecurityToken,
                                          refreshToken as JwtSecurityToken, options),
                        authenticationType ?? options.SignInAsAuthenticationType));
        }
        public async Task<ClaimsIdentity> ValidateIdentity(KeycloakAuthenticationOptions options,
            string authenticationType = null)
        {
            // Validate JWTs provided
            SecurityToken idToken = null, refreshToken = null, accessToken = null;
            var tokenHandler = new KeycloakTokenHandler();
            if (_keycloakToken.IdToken != null)
                idToken = tokenHandler.ValidateToken(_keycloakToken.IdToken, options);
            if (_keycloakToken.RefreshToken != null)
                refreshToken = tokenHandler.ValidateToken(_keycloakToken.RefreshToken, options);
            if (_keycloakToken.AccessToken != null)
            {
                if (options.UseRemoteTokenValidation)
                    accessToken = await KeycloakTokenHandler.ValidateTokenRemote(_keycloakToken.AccessToken, options);
                else
                    accessToken = tokenHandler.ValidateToken(_keycloakToken.AccessToken, options);
            }

            // Create the new claims identity
            return // TODO: Convert to MS claims parsing in token handler
                new ClaimsIdentity(
                    GenerateJwtClaims(accessToken as JwtSecurityToken, idToken as JwtSecurityToken,
                        refreshToken as JwtSecurityToken, options),
                    authenticationType ?? options.SignInAsAuthenticationType);
        }
Example #3
0
        private OidcDataManager(KeycloakAuthenticationOptions options)
        {
            _options = options;
            _nextCachedRefreshTime = DateTime.Now;

            Authority               = _options.KeycloakUrl + "/realms/" + _options.Realm;
            MetadataEndpoint        = new Uri(Authority + "/" + OpenIdProviderMetadataNames.Discovery);
            TokenValidationEndpoint = new Uri(Authority + "/tokens/validate");
        }
        private OidcDataManager(KeycloakAuthenticationOptions options)
        {
            _options = options;
            _nextCachedRefreshTime = DateTime.Now;

            Authority = _options.KeycloakUrl + "/realms/" + _options.Realm;
            MetadataEndpoint = new Uri(Authority + "/" + OpenIdProviderMetadataNames.Discovery);
            TokenValidationEndpoint = new Uri(Authority + "/tokens/validate");
        }
 public RequestAccessTokenMessage(IOwinRequest request, KeycloakAuthenticationOptions options,
                                  AuthorizationResponse authResponse)
     : base(request, options)
 {
     if (authResponse == null)
     {
         throw new ArgumentNullException();
     }
     AuthResponse = authResponse;
 }
Example #6
0
 public RefreshAccessTokenMessage(IOwinRequest request, KeycloakAuthenticationOptions options,
                                  string refreshToken)
     : base(request, options)
 {
     if (refreshToken == null)
     {
         throw new ArgumentNullException();
     }
     RefreshToken = refreshToken;
 }
Example #7
0
 public bool TryValidateToken(string jwt, KeycloakAuthenticationOptions options, out SecurityToken rToken)
 {
     try
     {
         rToken = ValidateToken(jwt, options);
         return(true);
     }
     catch (Exception)
     {
         rToken = null;
         return(false);
     }
 }
 public bool TryValidateToken(string jwt, KeycloakAuthenticationOptions options, out SecurityToken rToken)
 {
     try
     {
         rToken = ValidateToken(jwt, options);
         return true;
     }
     catch (Exception)
     {
         rToken = null;
         return false;
     }
 }
Example #9
0
 protected GenericMessage(IOwinRequest request, KeycloakAuthenticationOptions options)
 {
     if (request == null)
     {
         throw new ArgumentNullException();
     }
     if (options == null)
     {
         throw new ArgumentNullException();
     }
     Request = request;
     Options = options;
 }
Example #10
0
    public static void Validate_Does_Not_Throw_If_ClientSecret_Is_Not_Provided_For_Public_Access_Type(string clientSecret)
    {
        // Arrange
        var options = new KeycloakAuthenticationOptions()
        {
            AccessType   = KeycloakAuthenticationAccessType.Public,
            ClientId     = "my-client-id",
            ClientSecret = clientSecret,
        };

        // Act (no Assert)
        options.Validate();
    }
Example #11
0
    public static void Validate_Throws_If_CallbackPath_Is_Null(KeycloakAuthenticationAccessType accessType)
    {
        // Arrange
        var options = new KeycloakAuthenticationOptions()
        {
            AccessType   = accessType,
            CallbackPath = null,
            ClientId     = "my-client-id",
            ClientSecret = "my-client-secret",
        };

        // Act and Assert
        Assert.Throws <ArgumentException>("CallbackPath", () => options.Validate());
    }
Example #12
0
        public static Task <OidcDataManager> CreateCachedContext(KeycloakAuthenticationOptions options,
                                                                 bool preload = true)
        {
            Task <OidcDataManager> preloadTask = null;
            var newContext = new OidcDataManager(options);

            if (preload)
            {
                preloadTask = newContext.ValidateCachedContextAsync();
            }
            HttpRuntime.Cache.Insert(options.AuthenticationType + CachedContextPostfix, newContext, null,
                                     Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
            return(preload ? preloadTask : Task.FromResult(newContext));
        }
 public static async Task<SecurityToken> ValidateTokenRemote(string jwt, KeycloakAuthenticationOptions options)
 {
     // This should really only be used on access tokens...
     var uriManager = OidcDataManager.GetCachedContext(options);
     var uri = new Uri(uriManager.TokenValidationEndpoint, "?access_token=" + jwt);
     try
     {
         var client = new HttpClient();
         var response = await client.GetAsync(uri);
         if (!response.IsSuccessStatusCode) throw new Exception();
         return new JwtSecurityToken(jwt); // TODO: Get this from returned JSON
     }
     catch (Exception)
     {
         throw new SecurityTokenValidationException("Remote Token Validation Failed");
     }
 }
        public SecurityToken ValidateToken(string jwt, KeycloakAuthenticationOptions options)
        {
            var uriManager = OidcDataManager.GetCachedContext(options);
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateLifetime = true,
                RequireExpirationTime = true,
                ValidateIssuer = !options.DisableIssuerValidation,
                ValidateAudience = !options.DisableAudienceValidation,
                ValidateIssuerSigningKey = !options.DisableTokenSignatureValidation,
                RequireSignedTokens = !options.AllowUnsignedTokens,
                ValidIssuer = uriManager.GetIssuer(),
                ClockSkew = options.TokenClockSkew,
                ValidAudiences = new List<string> {"null", options.ClientId},
                IssuerSigningTokens = uriManager.GetJsonWebKeys().GetSigningTokens(),
                AuthenticationType = options.AuthenticationType // Not used
            };

            return ValidateToken(jwt, tokenValidationParameters);
        }
        static void Main(string[] args)
        {
            var options = new KeycloakAuthenticationOptions
            {
                ClientId           = "KeycloakOwinAuthenticationSample",     // *Required*
                ClientSecret       = "9adf6cd2-3cb4-4c27-925e-780fca464443", // If using public authentication, delete this line
                VirtualDirectory   = "",                                     // Set this if you use a virtual directory when deploying to IIS
                AutomaticChallenge = true,
                // Instance-Specific Settings
                Realm                = "mdserver",                      // Don't change this unless told to do so
                KeycloakUrl          = "http://192.168.0.46:8080/auth", // Enter your Keycloak URL here
                AuthenticationScheme = "KeycloakOwinAuthenticationSample_keycloak_auth",
                // Template-Specific Settings
                SignInAsAuthenticationSchema = "MyCookieMiddlewareInstance" // Sets the above cookie with the Keycloak data
            };

            KeycloakHelper.SetOptions(options);
            var identity = KeycloakHelper.GetKeycloakIdentity("user1", "user1");

            Console.ReadLine();
        }
Example #16
0
        public static async Task <SecurityToken> ValidateTokenRemote(string jwt, KeycloakAuthenticationOptions options)
        {
            // This should really only be used on access tokens...
            var uriManager = OidcDataManager.GetCachedContext(options);
            var uri        = new Uri(uriManager.TokenValidationEndpoint, "?access_token=" + jwt);

            try
            {
                var client   = new HttpClient();
                var response = await client.GetAsync(uri);

                if (!response.IsSuccessStatusCode)
                {
                    throw new Exception();
                }
                return(new JwtSecurityToken(jwt)); // TODO: Get this from returned JSON
            }
            catch (Exception)
            {
                throw new SecurityTokenValidationException("Remote Token Validation Failed");
            }
        }
Example #17
0
        public SecurityToken ValidateToken(string jwt, KeycloakAuthenticationOptions options)
        {
            var uriManager = OidcDataManager.GetCachedContext(options);
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateLifetime         = true,
                RequireExpirationTime    = true,
                ValidateIssuer           = !options.DisableIssuerValidation,
                ValidateAudience         = !options.DisableAudienceValidation,
                ValidateIssuerSigningKey = !options.DisableTokenSignatureValidation,
                RequireSignedTokens      = !options.AllowUnsignedTokens,
                ValidIssuer    = uriManager.GetIssuer(),
                ClockSkew      = options.TokenClockSkew,
                ValidAudiences = new List <string> {
                    "null", options.ClientId
                },
                IssuerSigningTokens = uriManager.GetJsonWebKeys().GetSigningTokens(),
                AuthenticationType  = options.AuthenticationType // Not used
            };

            return(ValidateToken(jwt, tokenValidationParameters));
        }
        protected IEnumerable<Claim> GenerateJwtClaims(JwtSecurityToken accessToken, JwtSecurityToken idToken,
            JwtSecurityToken refreshToken, KeycloakAuthenticationOptions options)
        {
            // Add generic claims
            yield return new Claim(Constants.ClaimTypes.AuthenticationType, options.AuthenticationType);
            yield return new Claim(Constants.ClaimTypes.Version, Global.GetVersion());

            // Save the recieved tokens as claims
            if (options.SaveTokensAsClaims)
            {
                if (_keycloakToken.IdToken != null)
                    yield return new Claim(Constants.ClaimTypes.IdToken, _keycloakToken.IdToken);
                if (_keycloakToken.AccessToken != null)
                    yield return new Claim(Constants.ClaimTypes.AccessToken, _keycloakToken.AccessToken);
                if (_keycloakToken.RefreshToken != null)
                    yield return new Claim(Constants.ClaimTypes.RefreshToken, _keycloakToken.RefreshToken);
            }

            // Add OIDC token claims
            var jsonId = options.ClientId;
            if (_keycloakToken.IdToken != null)
                foreach (
                    var claim in ProcessOidcToken(idToken.GetPayloadJObject(), ClaimMappings.IdTokenMappings, jsonId))
                    yield return claim;
            if (_keycloakToken.AccessToken != null)
                foreach (
                    var claim in
                        ProcessOidcToken(accessToken.GetPayloadJObject(), ClaimMappings.AccessTokenMappings, jsonId)
                    )
                    yield return claim;
            if (_keycloakToken.RefreshToken != null)
                foreach (
                    var claim in
                        ProcessOidcToken(refreshToken.GetPayloadJObject(), ClaimMappings.RefreshTokenMappings, jsonId))
                    yield return claim;
        }
Example #19
0
 public static OidcDataManager GetCachedContext(KeycloakAuthenticationOptions options)
 {
     return(GetCachedContext(options.AuthenticationType));
 }
Example #20
0
        public static Task <OidcDataManager> ValidateCachedContextAsync(KeycloakAuthenticationOptions options)
        {
            var context = GetCachedContext(options.AuthenticationType);

            return(context.ValidateCachedContextAsync());
        }
 public static Task<OidcDataManager> ValidateCachedContextAsync(KeycloakAuthenticationOptions options)
 {
     var context = GetCachedContext(options.AuthenticationType);
     return context.ValidateCachedContextAsync();
 }
Example #22
0
 public static void SetOptions(KeycloakAuthenticationOptions options)
 {
     Options = options;
     ValidateOptions();
 }
 public static OidcDataManager GetCachedContext(KeycloakAuthenticationOptions options)
 {
     return GetCachedContext(options.AuthenticationType);
 }
        protected IEnumerable <Claim> GenerateJwtClaims(JwtSecurityToken accessToken, JwtSecurityToken idToken,
                                                        JwtSecurityToken refreshToken, KeycloakAuthenticationOptions options)
        {
            // Add generic claims
            yield return(new Claim(Constants.ClaimTypes.AuthenticationType, options.AuthenticationType));

            yield return(new Claim(Constants.ClaimTypes.Version, Global.GetVersion()));

            // Save the recieved tokens as claims
            if (options.SaveTokensAsClaims)
            {
                if (_keycloakToken.IdToken != null)
                {
                    yield return(new Claim(Constants.ClaimTypes.IdToken, _keycloakToken.IdToken));
                }
                if (_keycloakToken.AccessToken != null)
                {
                    yield return(new Claim(Constants.ClaimTypes.AccessToken, _keycloakToken.AccessToken));
                }
                if (_keycloakToken.RefreshToken != null)
                {
                    yield return(new Claim(Constants.ClaimTypes.RefreshToken, _keycloakToken.RefreshToken));
                }
            }

            // Add OIDC token claims
            var jsonId = options.ClientId;

            if (_keycloakToken.IdToken != null)
            {
                foreach (
                    var claim in ProcessOidcToken(idToken.GetPayloadJObject(), ClaimMappings.IdTokenMappings, jsonId))
                {
                    yield return(claim);
                }
            }
            if (_keycloakToken.AccessToken != null)
            {
                foreach (
                    var claim in
                    ProcessOidcToken(accessToken.GetPayloadJObject(), ClaimMappings.AccessTokenMappings, jsonId)
                    )
                {
                    yield return(claim);
                }
            }
            if (_keycloakToken.RefreshToken != null)
            {
                foreach (
                    var claim in
                    ProcessOidcToken(refreshToken.GetPayloadJObject(), ClaimMappings.RefreshTokenMappings, jsonId))
                {
                    yield return(claim);
                }
            }
        }
 public static Task<OidcDataManager> CreateCachedContext(KeycloakAuthenticationOptions options,
     bool preload = true)
 {
     Task<OidcDataManager> preloadTask = null;
     var newContext = new OidcDataManager(options);
     if (preload) preloadTask = newContext.ValidateCachedContextAsync();
     HttpRuntime.Cache.Insert(options.AuthenticationType + CachedContextPostfix, newContext, null,
         Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
     return preload ? preloadTask : Task.FromResult(newContext);
 }