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); } }
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); }
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); }
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)); }
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); }
//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)); } }); }
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); }
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)); }
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}"))); } }
/// <inheritdoc /> public AuthenticationResultEventArgs(PlayerAccountJWTModel tokenResult) { TokenResult = tokenResult; }