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>();
        }
Example #2
0
        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>();
        }
Example #8
0
        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);
        }