Example #1
0
    /// <summary>
    /// Validate tokens
    /// </summary>
    /// <param name="config">JwtConfig</param>
    /// <param name="token">Token value</param>
    public static Maybe <ClaimsPrincipal> ValidateToken(JwtConfig config, string token)
    {
        try
        {
            // Create validation parameters
            var parameters = new TokenValidationParameters
            {
                RequireExpirationTime = true,
                ValidIssuer           = config.Issuer,
                ValidAudience         = config.Audience ?? config.Issuer,
                IssuerSigningKey      = config.GetSigningKey()
            };

            _ = config.GetEncryptingKey().IfSome(encryptingKey => parameters.TokenDecryptionKey = encryptingKey);

            // Create handler to validate token
            var handler = new JwtSecurityTokenHandler();

            // Validate token and return principal
            return(handler.ValidateToken(token, parameters, out var validatedToken));
        }
        catch (SecurityTokenNotYetValidException)
        {
            return(F.None <ClaimsPrincipal, M.TokenIsNotValidYetMsg>());
        }
        catch (Exception e) when(e.Message.Contains("IDX10223"))
        {
            return(F.None <ClaimsPrincipal, M.TokenHasExpiredMsg>());
        }
        catch (Exception e)
        {
            return(F.None <ClaimsPrincipal, M.ValidatingTokenExceptionMsg>(e));
        }
    }
Example #2
0
    /// <summary>
    /// <para>Generate a new JSON Web Token for the specified user</para>
    /// <para>See <see cref="JwtSecurity"/> for default signing and encrypting algorithms</para>
    /// </summary>
    /// <param name="config">JwtConfig</param>
    /// <param name="principal">ClaimsPrincipal</param>
    /// <param name="notBefore">The earliest date / time from which this token is valid</param>
    /// <param name="expires">The latest date / time before which this token is valid</param>
    internal static Maybe <string> CreateToken(
        JwtConfig config,
        ClaimsPrincipal principal,
        DateTime notBefore,
        DateTime expires
        )
    {
        // Ensure there is a current user
        if (principal.Identity is null)
        {
            return(F.None <string, M.NullIdentityMsg>());
        }

        // Ensure the current user is authenticated
        var identity = principal.Identity;

        if (!identity.IsAuthenticated)
        {
            return(F.None <string, M.IdentityNotAuthenticatedMsg>());
        }

        // Ensure the JwtConfig is valid
        if (!config.IsValid)
        {
            return(F.None <string, M.ConfigInvalidMsg>());
        }

        // Ensure the signing key is a valid length
        if (config.SigningKey.Length < JwtSecurity.SigningKeyBytes)
        {
            return(F.None <string, M.SigningKeyNotLongEnoughMsg>());
        }

        // Ensure the encrypting key is a valid length
        if (config.EncryptingKey is string key && key.Length < JwtSecurity.EncryptingKeyBytes)
        {
            return(F.None <string, M.EncryptingKeyNotLongEnoughMsg>());
        }

        try
        {
            // Create token values
            var descriptor = new SecurityTokenDescriptor
            {
                Issuer             = config.Issuer,
                Audience           = config.Audience ?? config.Issuer,
                Subject            = new ClaimsIdentity(identity),
                NotBefore          = notBefore,
                Expires            = expires,
                IssuedAt           = DateTime.UtcNow,
                SigningCredentials = new SigningCredentials(config.GetSigningKey(), JwtSecurity.SigningAlgorithm)
            };

            _ = config.GetEncryptingKey().IfSome(encryptingKey2 =>
                                                 descriptor.EncryptingCredentials = new EncryptingCredentials(
                                                     encryptingKey2,
                                                     JwtSecurity.KeyWrapAlgorithm,
                                                     JwtSecurity.EncryptingAlgorithm
                                                     )
                                                 );

            // Create handler to create and write token
            var handler = new JwtSecurityTokenHandler();
            var token   = handler.CreateJwtSecurityToken(descriptor);
            return(handler.WriteToken(token));
        }
        catch (ArgumentOutOfRangeException e) when(e.Message.Contains("IDX10653"))
        {
            return(F.None <string, M.KeyNotLongEnoughMsg>());
        }
        catch (Exception e)
        {
            return(F.None <string>(new M.CreatingJwtSecurityTokenExceptionMsg(e)));
        }
    }