748 lines
25 KiB
C#
748 lines
25 KiB
C#
using System;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Security.Claims;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityModels.Extensions {
|
|
public static class XTokenExtensions {
|
|
//
|
|
#region Identity Token Extensions ...
|
|
/// <summary>
|
|
/// Convert a SecurityToken to it's Token String
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <returns></returns>
|
|
public static string ToTokenString (
|
|
this SecurityToken source,
|
|
JwtSecurityTokenHandler tokenHandler
|
|
) {
|
|
return tokenHandler.WriteToken (source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Token
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenValidationParams"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateToken (
|
|
this string token,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
TokenValidationParameters tokenValidationParams) {
|
|
//
|
|
if (token.IsNullOrEmpty ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
SecurityToken tokenObj = null;
|
|
try {
|
|
tokenHandler.ValidateToken (token, tokenValidationParams, out tokenObj);
|
|
} catch {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
return tokenObj != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a token string to Security Token
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenValidationParams"></param>
|
|
/// <returns></returns>
|
|
public static SecurityToken ToSecurityToken (
|
|
this string token,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
TokenValidationParameters tokenValidationParams) {
|
|
//
|
|
if (token.IsNullOrEmpty () ||
|
|
!token.ValidateToken (tokenHandler, tokenValidationParams)) {
|
|
//
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// convert token from String to JWTSecurity Token ...
|
|
try {
|
|
return tokenHandler.ReadToken (token);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse Action Token and return Corresponding RegistrationRequestDto
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenValidationParams"></param>
|
|
/// <returns></returns>
|
|
public static XActionRequestToken ParseActionRequestToken (
|
|
this string token,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
TokenValidationParameters tokenValidationParams) {
|
|
//
|
|
if (token.IsNullOrEmpty () ||
|
|
!token.ValidateToken (tokenHandler, tokenValidationParams)) {
|
|
//
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// convert token from String to JWTSecurity Token ...
|
|
JwtSecurityToken tokenObj = null;
|
|
try {
|
|
tokenObj = tokenHandler.ReadToken (token) as JwtSecurityToken;
|
|
} catch {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
if (tokenObj == null) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// Extract Registered Payload Claims ...
|
|
var mCurrentStepClaim = tokenObj.Claims
|
|
.FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Action));
|
|
var mContextClaim = tokenObj.Claims
|
|
.FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Context));
|
|
var mTokenClaim = tokenObj.Claims
|
|
.FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Token));
|
|
|
|
//
|
|
// Check All Claims to be NotNull ...
|
|
if (mCurrentStepClaim == null ||
|
|
mContextClaim == null ||
|
|
mTokenClaim == null) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// Reading all Claims Values ...
|
|
var mCurrentStepStr = mCurrentStepClaim.Value;
|
|
var mCurrentStep = 0;
|
|
try {
|
|
int.TryParse (mCurrentStepStr, out mCurrentStep);
|
|
} catch { }
|
|
|
|
//
|
|
var mContext = mContextClaim.Value.IsNullOrEmpty () ?
|
|
null : mContextClaim.Value.FromJSON<XActionRequestContext> ();
|
|
var mToken = mTokenClaim.Value;
|
|
|
|
//
|
|
// Create Instance of UserInvite ...
|
|
var result = new XActionRequestToken {
|
|
Action = (XAction) mCurrentStep,
|
|
Context = mContext,
|
|
Token = mToken
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check to ActionRequestContext object is same or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="dest"></param>
|
|
/// <returns></returns>
|
|
public static bool IsSameAs (
|
|
this XActionRequestContext source,
|
|
XActionRequestContext dest
|
|
) {
|
|
//
|
|
if (source == null ||
|
|
dest == null) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = source.ToJSON () == dest.ToJSON ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a RegistrationRequestDto object to it's jwt token Claims
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Claim[] ToJwtClaims (this XActionRequestToken source) {
|
|
//
|
|
// Generate Required Fields ...
|
|
var action = source.Action;
|
|
var context = source.Context;
|
|
var token = source.Token;
|
|
|
|
//
|
|
// Generate Claims Array ...
|
|
var claims = new Claim[] {
|
|
new Claim (nameof (XActionRequestToken.Action), ((int) action).ToString (), ClaimValueTypes.Integer),
|
|
new Claim (nameof (XActionRequestToken.Context), context == null ? "" : context.ToJSON (), ClaimValueTypes.String),
|
|
new Claim (nameof (XActionRequestToken.Token), token.IsNullOrEmpty () ? "" : token, ClaimValueTypes.String)
|
|
};
|
|
|
|
//
|
|
// Return Result ...
|
|
return claims;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a SecurityToken based on RegistrationRequestDto object
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenDescriptor"></param>
|
|
/// <returns></returns>
|
|
public static SecurityToken ToJwtToken (
|
|
this XActionRequestToken source,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
SecurityTokenDescriptor tokenDescriptor) {
|
|
//
|
|
// Getting Claims ...
|
|
var claims = source.ToJwtClaims ();
|
|
tokenDescriptor.Subject = new ClaimsIdentity (claims);
|
|
|
|
//
|
|
// Generate Token Object ...
|
|
var tokenObject = tokenHandler.CreateToken (tokenDescriptor);
|
|
|
|
//
|
|
// Return Result ...
|
|
return tokenObject;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region IdentityServer Token Extensions ...
|
|
/// <summary>
|
|
/// Retrieve Tokens From Headers
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse RetrieveTokens (this HttpRequest source) {
|
|
//
|
|
var accessToken = source.Headers[XAuthorization.Header].ToString ();
|
|
var refreshToken = source.Headers[XAuthorization.RefreshToken].ToString ();
|
|
|
|
//
|
|
var expiresAtStr = source.Headers[XAuthorization.ExpiresAt].ToString ();
|
|
long expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
return new XTokenResponse {
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From HttpContext
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static async Task<XTokenResponse> RetrieveTokens (this HttpContext source) {
|
|
//
|
|
var accessToken = await source.GetTokenAsync (XAuthorization.AccessToken);
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
var refreshToken = await source.GetTokenAsync (XAuthorization.RefreshToken);
|
|
var expiresAtStr = await source.GetTokenAsync (XAuthorization.ExpiresAt);
|
|
long expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
var headerRequestTokens = source.Request.RetrieveTokens ();
|
|
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = accessToken ?? headerRequestTokens.AccessToken,
|
|
RefreshToken = refreshToken ?? headerRequestTokens.RefreshToken,
|
|
ExpiresAt = expiresAt != 0 ? expiresAt : headerRequestTokens.ExpiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From ActionExecutingContext
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static async Task<XTokenResponse> RetrieveTokens (this ActionExecutingContext source) {
|
|
//
|
|
var result = await source.HttpContext.RetrieveTokens ();
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From XUserInfo instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse RetrieveTokens (this XUserClaimsInfoDto source) {
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = source.ExpiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From IHeader Dictionary
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse RetrieveTokens (this IHeaderDictionary source) {
|
|
//
|
|
var accessToken = source[XAuthorization.Header].ToString () ?? "";
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
var refreshToken = source[XAuthorization.RefreshToken].ToString () ?? "";
|
|
|
|
//
|
|
var expiresAtStr = source[XAuthorization.ExpiresAt].ToString () ?? "";
|
|
var expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate XTokenResponse instance based on TokenResponse
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XLoginResponse CreateXLoginResponse (this TokenResponse source) {
|
|
//
|
|
if (source.IsNull () ||
|
|
source.IsError) {
|
|
XException.InvalidToken.Throw ();
|
|
}
|
|
|
|
//
|
|
var expiresAt = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds () +
|
|
source.ExpiresIn;
|
|
|
|
//
|
|
var result = new XLoginResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate XTokenResponse instance based on TokenResponse
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse CreateXTokenResponse (this TokenResponse source) {
|
|
//
|
|
if (source.IsNull () ||
|
|
source.IsError) {
|
|
XException.InvalidToken.Throw ();
|
|
}
|
|
|
|
//
|
|
var expiresAt = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds () +
|
|
source.ExpiresIn;
|
|
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert XLoginResponse to XTokenResponse
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse ToXTokenResponse (this XLoginResponse source) {
|
|
//
|
|
if (source.IsNull ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
return new XTokenResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = source.ExpiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this IHeaderDictionary source,
|
|
XLoginResponse model,
|
|
string secret = null
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
|
|
//
|
|
if (!secret.IsNullOrEmpty ()) {
|
|
var revisionChecksum = model.GetRevisionChecksum (secret);
|
|
source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this IHeaderDictionary source,
|
|
XTokenResponse model,
|
|
string secret = null
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
|
|
//
|
|
if (!secret.IsNullOrEmpty ()) {
|
|
var revisionChecksum = model.GetRevisionChecksum (secret);
|
|
source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestHeaders source,
|
|
XLoginResponse model
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestHeaders source,
|
|
XTokenResponse model
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequest source,
|
|
XLoginResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequest source,
|
|
XTokenResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestMessage source,
|
|
XLoginResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestMessage source,
|
|
XTokenResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add ReNewed Authorization Tokens in Headers of
|
|
/// Specific Response.
|
|
/// Later in HttpInterceptors we can Look for AccessToken-ReNewed
|
|
/// header Value and Renew User Tokens based on it
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpResponse source,
|
|
XLoginResponse model,
|
|
string secret
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model, secret);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add ReNewed Authorization Tokens in Headers of
|
|
/// Specific Response.
|
|
/// Later in HttpInterceptors we can Look for AccessToken-ReNewed
|
|
/// header Value and Renew User Tokens based on it
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpResponse source,
|
|
XTokenResponse model,
|
|
string secret
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model, secret);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Token Can Refrsh or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsRefreshable (this XLoginResponse source) {
|
|
//
|
|
var containsTokenData = !source.IsNull () &&
|
|
!source.AccessToken.IsNullOrEmpty () &&
|
|
!source.RefreshToken.IsNullOrEmpty ();
|
|
if (!containsTokenData) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var current = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds ();
|
|
|
|
//
|
|
// var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Token Can Refrsh or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsRefreshable (this XTokenResponse source) {
|
|
//
|
|
var containsTokenData = !source.IsNull () &&
|
|
!source.AccessToken.IsNullOrEmpty () &&
|
|
!source.RefreshToken.IsNullOrEmpty ();
|
|
if (!containsTokenData) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var current = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds ();
|
|
|
|
//
|
|
// var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a Revision Checksum for new Tokens
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static string GetRevisionChecksum (
|
|
this XLoginResponse source,
|
|
string secret
|
|
) {
|
|
return (source.AccessToken +
|
|
secret +
|
|
source.RefreshToken +
|
|
secret +
|
|
source.ExpiresAt.ToString ()
|
|
)
|
|
.ToMd5String ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a Revision Checksum for new Tokens
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static string GetRevisionChecksum (
|
|
this XTokenResponse source,
|
|
string secret
|
|
) {
|
|
return (source.AccessToken +
|
|
secret +
|
|
source.RefreshToken +
|
|
secret +
|
|
source.ExpiresAt.ToString ()
|
|
)
|
|
.ToMd5String ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an XLoginResponse instance is Valid with it's revision
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="checksum"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateRevisionChecksum (
|
|
this XLoginResponse source,
|
|
string checksum,
|
|
string secret
|
|
) {
|
|
//
|
|
var xChecksum = source.GetRevisionChecksum (secret);
|
|
return checksum == xChecksum;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an XTokenResponse instance is Valid with it's revision
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="checksum"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateRevisionChecksum (
|
|
this XTokenResponse source,
|
|
string checksum,
|
|
string secret
|
|
) {
|
|
//
|
|
var xChecksum = source.GetRevisionChecksum (secret);
|
|
return checksum == xChecksum;
|
|
}
|
|
#endregion
|
|
}
|
|
} |