예제 #1
0
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Path.HasValue && context.Request.Path.ToUriComponent()
                .Contains(AuthenticationController.AUTHENTICATION_ROUTE_VALUE))
            {
                var existingBodyStream = context.Response.Body;

                using (var newBodyStream = new MemoryStream())
                {
                    // We set the response body to our stream so we can read after the chain of middlewares have been called.
                    context.Response.Body = newBodyStream;

                    // execute the rest of the pipeline
                    await Next(context);

                    //Now we should check the content response
                    //If it's OK then authentication was successful.
                    if (context.Response.StatusCode == StatusCodes.Status200OK)
                    {
                        newBodyStream.Seek(0, SeekOrigin.Begin);
                        ServerSidePlayerAccountJWTModel PlayerAccountJWTModel = Deserialize <ServerSidePlayerAccountJWTModel>(newBodyStream);
                        newBodyStream.Seek(0, SeekOrigin.Begin);

                        //At this point, we need to actually query PlayFab and authenticate the user.
                        GladMMOPlayFabLoginResult playAuthToken = await AuthenticateWithPlayfab(PlayerAccountJWTModel.OpenId);

                        if (String.IsNullOrWhiteSpace(playAuthToken.SessionTicket))
                        {
                            throw new InvalidOperationException($"Encountered Null PlayFab Authentication Token.");
                        }

                        PlayerAccountJWTModel jwtResponseModel = new PlayerAccountJWTModel(PlayerAccountJWTModel.AccessToken);
                        jwtResponseModel.PlayfabAuthenticationToken = playAuthToken.SessionTicket;
                        jwtResponseModel.PlayfabId = playAuthToken.PlayFabId;

                        //Now we actually have to write the new JWT model to the response stream
                        byte[] bytes = JsonConvert.SerializeObject(jwtResponseModel).Reinterpret(Encoding.ASCII);
                        newBodyStream.SetLength(bytes.Length);
                        context.Response.ContentLength = bytes.Length;
                        await newBodyStream.WriteAsync(bytes, 0, bytes.Length);

                        newBodyStream.Seek(0, SeekOrigin.Begin);
                    }

                    //Copy the contents of the new memory stream (which contains the response) to the original stream, which is then returned to the client.
                    await newBodyStream.CopyToAsync(existingBodyStream, (int)newBodyStream.Length);

                    context.Response.Body = existingBodyStream;
                }
            }
            else
            {
                //Execute like normal
                await Next(context);
            }
        }
예제 #2
0
        public static void Test_PlayerAccountJWTModel_Indicates_IsValid_When_Error_Is_Present(string error, string errorDescription)
        {
            //arrange
            PlayerAccountJWTModel model = new PlayerAccountJWTModel(error, errorDescription);

            //act
            PlayerAccountJWTModel deserializedModel = JsonConvert.DeserializeObject <PlayerAccountJWTModel>(JsonConvert.SerializeObject(model));

            //assert
            Assert.IsFalse(deserializedModel.isTokenValid);
        }
예제 #3
0
        public static void Test_PlayerAccountJWTModel_Indicates_IsValid_When_AccessToken_IsPresent(string accessToken)
        {
            //arrange
            PlayerAccountJWTModel model = new PlayerAccountJWTModel(accessToken);

            //act
            PlayerAccountJWTModel deserializedModel = JsonConvert.DeserializeObject <PlayerAccountJWTModel>(JsonConvert.SerializeObject(model));

            //assert
            Assert.IsTrue(deserializedModel.isTokenValid);
        }
예제 #4
0
        public static void Test_Can_JSON_Serialize_To_NonNull_Non_Whitespace_ErrorArgs(string error, string errorDefinition)
        {
            //arrange
            PlayerAccountJWTModel model = new PlayerAccountJWTModel(error, errorDefinition);

            //act
            string serializedModel = JsonConvert.SerializeObject(model);

            //assert
            Assert.NotNull(serializedModel);
            Assert.IsNotEmpty(serializedModel);
            Assert.True(serializedModel.Contains(error));
            Assert.True(serializedModel.Contains(errorDefinition));
        }
예제 #5
0
        public static void Test_Can_JSON_Serialize_Then_Deserialize_AccessToken(string accessToken)
        {
            //arrange
            PlayerAccountJWTModel model = new PlayerAccountJWTModel(accessToken);

            //act
            PlayerAccountJWTModel deserializedModel = JsonConvert.DeserializeObject <PlayerAccountJWTModel>(JsonConvert.SerializeObject(model));

            //assert
            Assert.NotNull(deserializedModel);
            Assert.NotNull(deserializedModel.AccessToken);
            Assert.IsNotEmpty(deserializedModel.AccessToken);
            Assert.AreEqual(accessToken, deserializedModel.AccessToken);
        }
예제 #6
0
        //TODO: Simplified async event firing/handling
        /// <inheritdoc />
        protected override void OnEventFired(object source, EventArgs args)
        {
            //We should not do async OnEventFired because we will get silent failures.
            UnityAsyncHelper.UnityMainThreadContext.PostAsync(async() =>
            {
                PlayerAccountJWTModel PlayerAccountJWTModel = null;

                //TODO: Validate username and password
                //We can't do error code supression with refit anymore, so we have to do this crap.
                try
                {
                    PlayerAccountJWTModel = await AuthService.TryAuthenticate(BuildAuthRequestModel())
                                            .ConfigureAwaitFalse();
                }
                catch (ApiException e)
                {
                    PlayerAccountJWTModel = await e.GetContentAsAsync <PlayerAccountJWTModel>();

                    if (Logger.IsErrorEnabled)
                    {
                        Logger.Error($"Encountered Auth Error: {e.Message}");
                    }

                    //failed and null response.
                    //Non-null response but failed.
                    ErrorPublisher.PublishEvent(this, new GeneralErrorEncounteredEventArgs("Login Failed", $"Error Code {(int)e.StatusCode}. Reason: {e.ReasonPhrase}. {e.Message}", null));
                }
                catch (Exception e)
                {
                    if (Logger.IsErrorEnabled)
                    {
                        Logger.Error($"Encountered Auth Error: {e.Message}\n\nStack: {e.StackTrace}");
                    }

                    //failed and null response.
                    //Non-null response but failed.
                    ErrorPublisher.PublishEvent(this, new GeneralErrorEncounteredEventArgs("Login Failed", $"Reason: Unknown Server Error", null));
                }
                finally
                {
                    if (Logger.IsDebugEnabled)
                    {
                        Logger.Debug($"Auth Response for User: {UsernameText.Text} Result: {PlayerAccountJWTModel?.isTokenValid} OptionalError: {PlayerAccountJWTModel?.Error} OptionalErrorDescription: {PlayerAccountJWTModel?.ErrorDescription}");
                    }

                    //Even if it's null, we should broadcast the event.
                    OnAuthenticationResultRecieved?.Invoke(this, new AuthenticationResultEventArgs(PlayerAccountJWTModel));
                }
            });
        }
예제 #7
0
        public static void Test_Can_JSON_Serialize_Then_Deserialize_ErrorArgs(string error, string errorDefinition)
        {
            //arrange
            PlayerAccountJWTModel model = new PlayerAccountJWTModel(error, errorDefinition);

            //act
            PlayerAccountJWTModel deserializedModel = JsonConvert.DeserializeObject <PlayerAccountJWTModel>(JsonConvert.SerializeObject(model));

            //assert
            Assert.NotNull(deserializedModel);
            Assert.NotNull(deserializedModel.Error);
            Assert.NotNull(deserializedModel.ErrorDescription);
            Assert.AreEqual(error, deserializedModel.Error);
            Assert.AreEqual(errorDefinition, deserializedModel.ErrorDescription);
        }
예제 #8
0
        public static void Test_Can_JSON_Serialize_To_NonNull_Non_Whitespace_AccessToken(string accessToken)
        {
            //arrange
            PlayerAccountJWTModel model = new PlayerAccountJWTModel(accessToken);

            //act
            string serializedModel = JsonConvert.SerializeObject(model);

            //assert
            Assert.NotNull(serializedModel);
            Assert.True(!serializedModel.Contains(nameof(model.isTokenValid)), $"JSON modle contains what should be unlisted field {nameof(model.isTokenValid)}. JSON: {serializedModel}");
            Assert.True(!serializedModel.Contains("_isTokenValid"), $"JSON modle contains what should be unlisted field _isTokenValid. JSON: {serializedModel}");
            Assert.IsNotEmpty(serializedModel);
            Assert.True(serializedModel.Contains(accessToken));
        }
예제 #9
0
        public async Task <IActionResult> RegisterDev([FromQuery] string username, [FromQuery] string password)
        {
            if (string.IsNullOrWhiteSpace(username))
            {
                return(BadRequest("Invalid username"));
            }

            if (string.IsNullOrWhiteSpace(password))
            {
                return(BadRequest("Invalid password."));
            }

            //We want to log this out for information purposes whenever an auth request begins
            if (Logger.IsEnabled(LogLevel.Information))
            {
                Logger.LogInformation($"Register Request: {username} {HttpContext.Connection.RemoteIpAddress}:{HttpContext.Connection.RemotePort}");
            }

            GuardiansApplicationUser user = new GuardiansApplicationUser()
            {
                UserName = username,
                Email    = "*****@*****.**"
            };

            IdentityResult identityResult = await UserManager.CreateAsync(user, password);

            if (identityResult.Succeeded)
            {
                PlayerAccountJWTModel PlayerAccountJWTModel = await AuthenticationServiceClient.TryAuthenticate(new AuthenticationRequestModel(username, password));

                await UserManager.AddClaimAsync(user, new Claim(GladMMOPlayfabConstants.PLAYFAB_JWT_CLAIM_TYPE, PlayerAccountJWTModel.PlayfabId));

                //At this point, the account has the PlayFab id claim so it's ready for use.
                return(Ok());
            }
            else
            {
                return(BadRequest(identityResult.Errors.Aggregate("", (s, error) => $"{s} {error.Code}:{error.Description}")));
            }
        }
예제 #10
0
 /// <inheritdoc />
 public AuthenticationResultEventArgs(PlayerAccountJWTModel tokenResult)
 {
     TokenResult = tokenResult;
 }