/// <summary> /// Creates a JWT access token than can be used in request headers instead of an OAuth2 token. /// This is achieved by signing a special JWT using this service account's private key. /// <param name="authUri">The URI for which the access token will be valid.</param> /// <param name="issueUtc">The issue time of the JWT.</param> /// <param name="expiryUtc">The expiry time of the JWT.</param> /// </summary> private string CreateJwtAccessToken(string authUri, DateTime issueUtc, DateTime expiryUtc) { JsonWebSignature.Payload payload; if (HasExplicitScopes) { payload = new GoogleJsonWebSignature.Payload() { Scope = string.Join(" ", Scopes) }; } else { payload = new JsonWebSignature.Payload() { Audience = authUri }; } payload.Issuer = Id; payload.Subject = Id; payload.IssuedAtTimeSeconds = (long)(issueUtc - UnixEpoch).TotalSeconds; payload.ExpirationTimeSeconds = (long)(expiryUtc - UnixEpoch).TotalSeconds; return(CreateAssertionFromPayload(payload)); }
/// <summary> /// Creates a JWT access token than can be used in request headers instead of an OAuth2 token. /// This is achieved by signing a special JWT using this service account's private key. /// <param name="authUri">The URI for which the access token will be valid.</param> /// <param name="issueUtc">The issue time of the JWT.</param> /// <param name="expiryUtc">The expiry time of the JWT.</param> /// </summary> private string CreateJwtAccessToken(string authUri, DateTime issueUtc, DateTime expiryUtc) { var payload = new JsonWebSignature.Payload() { Issuer = Id, Subject = Id, Audience = authUri, IssuedAtTimeSeconds = (long)(issueUtc - UnixEpoch).TotalSeconds, ExpirationTimeSeconds = (long)(expiryUtc - UnixEpoch).TotalSeconds, }; return(CreateAssertionFromPayload(payload)); }
private string CreateJwtAccessTokenForOidc(OidcTokenOptions options, DateTime issueUtc, DateTime expiryUtc) { var payload = new JsonWebSignature.Payload { Issuer = Id, Subject = Id, Audience = GoogleAuthConsts.OidcTokenUrl, IssuedAtTimeSeconds = (long)(issueUtc - UnixEpoch).TotalSeconds, ExpirationTimeSeconds = (long)(expiryUtc - UnixEpoch).TotalSeconds, TargetAudience = options.TargetAudience }; return(CreateAssertionFromPayload(payload)); }
/// <summary> /// Creates a JWT access token than can be used in request headers instead of an OAuth2 token. /// This is achieved by signing a special JWT using this service account's private key. /// <param name="authUri">The URI for which the access token will be valid.</param> /// </summary> private string CreateJwtAccessToken(string authUri) { var issuedDateTime = Clock.UtcNow; var issued = (int)(issuedDateTime - UnixEpoch).TotalSeconds; var payload = new JsonWebSignature.Payload() { Issuer = Id, Subject = Id, Audience = authUri, IssuedAtTimeSeconds = issued, ExpirationTimeSeconds = issued + 3600, }; return(CreateAssertionFromPayload(payload)); }
/// <summary> /// Signs JWT token using the private key and returns the serialized assertion. /// </summary> /// <param name="payload">the JWT payload to sign.</param> private string CreateAssertionFromPayload(JsonWebSignature.Payload payload) { string serializedHeader = CreateSerializedHeader(); string serializedPayload = NewtonsoftJsonSerializer.Instance.Serialize(payload); var assertion = new StringBuilder(); assertion.Append(TokenEncodingHelpers.UrlSafeBase64Encode(serializedHeader)) .Append('.') .Append(TokenEncodingHelpers.UrlSafeBase64Encode(serializedPayload)); var signature = CreateSignature(Encoding.ASCII.GetBytes(assertion.ToString())); assertion.Append('.').Append(TokenEncodingHelpers.UrlSafeEncode(signature)); return(assertion.ToString()); }
/// <summary> /// Signs JWT token using the private key and returns the serialized assertion. /// </summary> /// <param name="payload">the JWT payload to sign.</param> private string CreateAssertionFromPayload(JsonWebSignature.Payload payload) { string serializedHeader = CreateSerializedHeader(); string serializedPayload = NewtonsoftJsonSerializer.Instance.Serialize(payload); StringBuilder assertion = new StringBuilder(); assertion.Append(UrlSafeBase64Encode(serializedHeader)) .Append(".") .Append(UrlSafeBase64Encode(serializedPayload)); // Sign the header and the payload. var hashAlg = new SHA256CryptoServiceProvider(); byte[] assertionHash = hashAlg.ComputeHash(Encoding.ASCII.GetBytes(assertion.ToString())); var signature = UrlSafeBase64Encode(key.SignHash(assertionHash, "2.16.840.1.101.3.4.2.1" /* SHA256 OIG */)); assertion.Append(".").Append(signature); return(assertion.ToString()); }
public async Task FetchesOidcToken_CorrectPayloadSent() { var clock = new MockClock { UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) }; var messageHandler = new OidcTokenSuccessMessageHandler(clock); var initializer = new ServiceAccountCredential.Initializer("MyId", "http://will.be.ignored") { Clock = clock, ProjectId = "a_project_id", HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var credential = new ServiceAccountCredential(initializer.FromPrivateKey(PrivateKey)); var expectedPayload = new JsonWebSignature.Payload { Issuer = "MyId", Subject = "MyId", Audience = GoogleAuthConsts.OidcAuthorizationUrl, IssuedAtTimeSeconds = (long)(clock.UtcNow - UnixEpoch).TotalSeconds, ExpirationTimeSeconds = (long)(clock.UtcNow.Add(JwtLifetime) - UnixEpoch).TotalSeconds, TargetAudience = "any_audience" }; var serializedExpectedPayload = NewtonsoftJsonSerializer.Instance.Serialize(expectedPayload); var urlSafeEncodedExpectedPayload = UrlSafeBase64Encode(serializedExpectedPayload); var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("any_audience")); await oidcToken.GetAccessTokenAsync(); var requestFormDict = messageHandler.LatestRequestContent.Split('&') .ToDictionary(entry => entry.Split('=')[0], entry => entry.Split('=')[1]); var assertion = requestFormDict["assertion"]; // Assertion format shoould be headers.payload.signature var encodedPayload = assertion.Split('.')[1]; Assert.Contains(urlSafeEncodedExpectedPayload, encodedPayload); }
/// <summary> /// Signs JWT token using the private key and returns the serialized assertion. /// </summary> /// <param name="payload">the JWT payload to sign.</param> private string CreateAssertionFromPayload(JsonWebSignature.Payload payload) { string serializedHeader = CreateSerializedHeader(); string serializedPayload = NewtonsoftJsonSerializer.Instance.Serialize(payload); StringBuilder assertion = new StringBuilder(); assertion.Append(UrlSafeBase64Encode(serializedHeader)) .Append(".") .Append(UrlSafeBase64Encode(serializedPayload)); // Sign the header and the payload. var hashAlg = SHA256.Create(); byte[] assertionHash = hashAlg.ComputeHash(Encoding.ASCII.GetBytes(assertion.ToString())); #if NETSTANDARD var sigBytes = key.SignHash(assertionHash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); #else var sigBytes = key.SignHash(assertionHash, Sha256Oig); #endif var signature = UrlSafeBase64Encode(sigBytes); assertion.Append(".").Append(signature); return(assertion.ToString()); }
/// <summary> /// Creates a JWT access token than can be used in request headers instead of an OAuth2 token. /// This is achieved by signing a special JWT using this service account's private key. /// <param name="authUri">The URI for which the access token will be valid.</param> /// </summary> private string CreateJwtAccessToken(string authUri) { var issuedDateTime = Clock.UtcNow; var issued = (int)(issuedDateTime - UnixEpoch).TotalSeconds; var payload = new JsonWebSignature.Payload() { Issuer = Id, Subject = Id, Audience = authUri, IssuedAtTimeSeconds = issued, ExpirationTimeSeconds = issued + 3600, }; return CreateAssertionFromPayload(payload); }