public async Task ValidateAsync_InvalidAudience_ThrowSecurityTokenInvalidAudienceException() { var client = CreateValidFakeAppleHttpClient(); var verifier = new AppleVerifier(client); await FluentActions.Invoking(() => verifier.ValidateAsync(_settings.ValidJwtToken, "badAud")).Should().ThrowAsync <SecurityTokenInvalidAudienceException>(); }
public async Task ValidateAsync_Valid_ReturnSecurityToken() { #region arrange var var jwtToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFiYyJ9.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiYS5iLmMiLCJleHAiOjIxNDc0ODM2NDcsImlhdCI6MzMzODI1MjMwLCJzdWIiOiIwMDAwMDAueHh4eC4xMTExIiwiY19oYXNoIjoieHh4eCIsImVtYWlsIjoieHh4eEBwcml2YXRlcmVsYXkuYXBwbGVpZC5jb20iLCJlbWFpbF92ZXJpZmllZCI6InRydWUiLCJpc19wcml2YXRlX2VtYWlsIjoidHJ1ZSIsImF1dGhfdGltZSI6MzMzODI1MjMwLCJub25jZV9zdXBwb3J0ZWQiOnRydWV9.Dmm0_tSmjT4DEXtMprCmP3oDoThZJqVmNh1tcsdqRpkt7-V0jqVrYFaqkiLK8W6293MJhKma-blwkscNdcw4zUQxhP1JeHrByFopQqXp-COY_lR4QjzKZU1qyIKdHkCkvODwxWP3bLDeG8GVFue3OzK8IpeRrV5ad7IZOoSFKJpXnTInRvHGx_B1XJdCLjXDgo9DrwsICL5IP1GLa1dWl0NnenaQzoijwsxaTERxSOLaA0uCIrXAq0QM5RREqBFV-uDkE-4JwF0jXVYnnmNtammOW79zZE9ylWzXdioyNcP4dbOHgi4wWfXIlJw2v8Iswx9HcbtoM-R_D__83-7lCg"; var jsonKey = "{'kty':'RSA','e':'AQAB','use':'sig','kid':'abc','alg':'RS256','n':'k7al_Uc5ld-2nv7Nn9V9oSeOEsxOT32wXBsUDV3aIJktZxJ58RFkX7LvFckHjFt8Du7R1jkV5jzZP2YBD6GzX5pPwAagL6t0PCvKs23bGfzxwweYf5llO483Gp7wZkpfTItIfiz0fAqOR-NKNweiJ0SaIk1hRUwCdwbUCOXFnDVa6l5MABRIKfjRmuhljSYeqnCYRZepVIaybJR8DdGTByJdgTl_1H91P_ySLCulA4B-7fVY2u_E93avbRyrOqxX6QXw1DjVIZpzPBRXmC1WlZNwbL770P-Y0IKs2Hsl791S6CIO2ax8X3LZBieLFOGYOOVVHGCzH4-Cpd0FOTUVEQ'}"; var expected = "{\"alg\":\"RS256\",\"typ\":\"JWT\",\"kid\":\"abc\"}.{\"iss\":\"https://appleid.apple.com\",\"aud\":\"a.b.c\",\"exp\":2147483647,\"iat\":333825230,\"sub\":\"000000.xxxx.1111\",\"c_hash\":\"xxxx\",\"email\":\"[email protected]\",\"email_verified\":\"true\",\"is_private_email\":\"true\",\"auth_time\":333825230,\"nonce_supported\":true}"; #endregion var appleResponse = new AppleKeysResponse { Keys = new[] { new JsonWebKey(jsonKey) } }; var handlerStub = new DelegatingHandlerStub(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(appleResponse, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })), }); var client = new HttpClient(handlerStub); var verifier = new AppleVerifier(client); var result = await verifier.ValidateAsync(jwtToken); result.Should().NotBeNull(); result.ToString().Should().Be(expected); }
public async Task ValidateAsync_NotValidSignature_ThrowSecurityTokenInvalidSignatureException() { var jwtToken = _settings.InvalidJwtToken; var client = CreateValidFakeAppleHttpClient(); var verifier = new AppleVerifier(client); await FluentActions.Invoking(() => verifier.ValidateAsync(jwtToken, _settings.Audience)).Should().ThrowAsync <SecurityTokenInvalidSignatureException>(); }
public async Task ValidateAsync_Valid_CanBypassAudienceValidation() { var client = CreateValidFakeAppleHttpClient(); var verifier = new AppleVerifier(client); var result = await verifier.ValidateAsync(_settings.ValidJwtToken); result?.ToString().Should().Be(_settings.ValidAppleResponse); }
public async Task ValidateAsync_AppleReturnError_ThrowAppleAuthException() { var responseData = "error"; var jwtToken = _settings.InvalidJwtToken; var handlerStub = new DelegatingHandlerStub(new HttpResponseMessage() { StatusCode = HttpStatusCode.BadRequest, Content = new StringContent(responseData) }); var client = new HttpClient(handlerStub); var verifier = new AppleVerifier(client); await FluentActions.Invoking(() => verifier.ValidateAsync(jwtToken, _settings.Audience)).Should().ThrowAsync <AppleAuthException>().WithMessage(responseData); }
public async Task ValidateAsync_AppleDoenstReturnKid_ThrowAppleAuthException() { var jwtToken = _settings.InvalidJwtToken; var appleResponse = new AppleKeysResponse(); var handlerStub = new DelegatingHandlerStub(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(appleResponse, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })), }); var client = new HttpClient(handlerStub); var verifier = new AppleVerifier(client); await FluentActions.Invoking(() => verifier.ValidateAsync(jwtToken, _settings.Audience)).Should().ThrowAsync <AppleAuthException>(); }
public async Task ValidateAsync_InvalidAudience_ThrowSecurityTokenInvalidAudienceException() { var appleResponse = new AppleKeysResponse { Keys = new[] { new JsonWebKey(AppleJsonKey) } }; var handlerStub = new DelegatingHandlerStub(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(appleResponse, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })), }); var client = new HttpClient(handlerStub); var verifier = new AppleVerifier(client); await FluentActions.Invoking(() => verifier.ValidateAsync(ValidJwtToken, "badAud")).Should().ThrowAsync <SecurityTokenInvalidAudienceException>(); }
static async Task Main() { #region Check config var p8Path = "Files/key.p8"; if (!File.Exists(p8Path)) { WriteError("Add your key in the 'Files' folder (https://developer.apple.com/account/resources/authkeys)"); return; } var appSettingsPath = "appsettings.json"; if (!File.Exists(appSettingsPath)) { WriteError("Create your 'appsettings.json' file from 'appsettings.template.json'"); return; } #endregion ConfigureSettings(appSettingsPath); // create clients _verifier = new AppleVerifier(); _client = await CreateAppleClient(p8Path); // create login url to receive the code and id_token var appleCode = GetAppleCode(); // generate a token with an apple code var accessToken = await GetAccessTokenAsync(appleCode); // an apple code cannot be reuse await CheckAppleCodeReusabilityAsync(appleCode); // refresh a token with a refresh token await RefreshTokenAsync(accessToken.RefreshToken); }
public async Task ValidateAsync_Valid_ReturnSecurityToken() { var expected = $"{{\"alg\":\"RS256\",\"typ\":\"JWT\",\"kid\":\"abc\"}}.{{\"iss\":\"https://appleid.apple.com\",\"aud\":\"{Audience}\",\"exp\":2147483647,\"iat\":333825230,\"sub\":\"000000.xxxx.1111\",\"c_hash\":\"xxxx\",\"email\":\"[email protected]\",\"email_verified\":\"true\",\"is_private_email\":\"true\",\"auth_time\":333825230,\"nonce_supported\":true}}"; var appleResponse = new AppleKeysResponse { Keys = new[] { new JsonWebKey(AppleJsonKey) } }; var handlerStub = new DelegatingHandlerStub(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(appleResponse, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })), }); var client = new HttpClient(handlerStub); var verifier = new AppleVerifier(client); var result = await verifier.ValidateAsync(ValidJwtToken, Audience); result.Should().NotBeNull(); result.ToString().Should().Be(expected); }