/// <summary> /// Logs the authentication result. /// </summary> /// <param name="authenticationResult"> /// The authentication result to be logged. /// </param> private void LogAuthenticationResult(AuthenticationResult authenticationResult) { }
/// <summary> /// Authenticates the request using Bearer scheme. /// </summary> /// <param name="request">The request to be authenticated.</param> /// <returns> /// An instance of AuthenticationResult which specifies if the authentication was successful or not. /// If successful, it will contain the IPrincipal. /// If not successful, it will contain the error message. /// </returns> public override AuthenticationResult Authenticate(HttpRequestMessage request) { // Validate the request first. AuthenticationResult authenticationResult; if (!this.ValidateRequest(request, out authenticationResult)) { return(authenticationResult); } // Validate the token (note that the signature is verified only further down). SimpleWebToken token; try { string tokenString = request.Headers.Authorization.Parameter; token = SimpleWebToken.Parse(tokenString); } catch (FormatException) { return (AuthenticationResult.CreateFailedAuthenticationResult( "The bearer token is not in a valid format.")); } catch (SecurityException exception) { return(AuthenticationResult.CreateFailedAuthenticationResult(exception.Message)); } catch (Exception exception) { if (exception.IsFatal()) { throw; } return (AuthenticationResult.CreateFailedAuthenticationResult( "An unexpected error occurred while parsing the token.")); } // Validate issuer. TokenIssuer tokenIssuer; if ((!Enum.TryParse(token.Issuer, true, out tokenIssuer)) || (!Enum.IsDefined(typeof(TokenIssuer), token.Issuer))) { return(AuthenticationResult.CreateFailedAuthenticationResult( "Unrecognized token issuer: '{0}'", token.Issuer)); } // Validate audience TokenAudience tokenAudience; if ((!Enum.TryParse(token.Audience, true, out tokenAudience)) || (!Enum.IsDefined(typeof(TokenAudience), token.Audience))) { return(AuthenticationResult.CreateFailedAuthenticationResult( "Unrecognized token audience: '{0}'", token.Audience)); } // Now validate the signature using the specified issuer's keys bool isSignatureValid = this.IsSignatureValidForIssuer(token, tokenIssuer); if (!isSignatureValid) { return(AuthenticationResult.CreateFailedAuthenticationResult("The token signature is not valid.")); } // Make sure the token is not expired. if (token.IsExpiredNow) { // Token expired. return(AuthenticationResult.CreateFailedAuthenticationResult( "The token expired at {0}", token.ExpiresOn.ToRoundtripFormatString())); } // Identify the roles for this principal. IEnumerable <Claim> roleClaims = GetRoleClaims(tokenIssuer, tokenAudience); if (roleClaims == null) { return(AuthenticationResult.CreateFailedAuthenticationResult( "This combination of token issuer and audience is not allowed for this service.")); } var claims = new List <Claim>(); // We wont allow the caller to specify roles, we will assign the roles here. claims.AddRange(token.Claims.Where(c => c.Type != HolMonClaimTypes.Role)); // Adding claims as we see fit. claims.AddRange(roleClaims); claims.Add(new Claim(HolMonClaimTypes.AuthenticationScheme, this.AuthenticationScheme)); claims.Add(new Claim(HolMonClaimTypes.TokenAudience, token.Audience)); claims.Add(new Claim(HolMonClaimTypes.TokenIssuer, token.Issuer)); this.LogClaims(claims); var identity = new ClaimsIdentity(claims, request.Headers.Authorization.Scheme); var principal = new ClaimsPrincipal(identity); return(AuthenticationResult.CreateSuccessfulAuthenticationResult(principal)); }