PreferencesUserFactory.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using System;
  2. using System.Net;
  3. using System.Net.Http;
  4. using System.Net.Http.Headers;
  5. using System.Security.Claims;
  6. using System.Text.Json;
  7. using System.Threading.Tasks;
  8. using Microsoft.AspNetCore.Components;
  9. using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
  10. using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
  11. namespace Wasm.Authentication.Client
  12. {
  13. public class PreferencesUserFactory : AccountClaimsPrincipalFactory<OidcAccount>
  14. {
  15. private readonly HttpClient _httpClient;
  16. public PreferencesUserFactory(NavigationManager navigationManager, IAccessTokenProviderAccessor accessor)
  17. : base(accessor)
  18. {
  19. _httpClient = new HttpClient { BaseAddress = new Uri(navigationManager.BaseUri) };
  20. }
  21. public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
  22. OidcAccount account,
  23. RemoteAuthenticationUserOptions options)
  24. {
  25. var initialUser = await base.CreateUserAsync(account, options);
  26. if (initialUser.Identity.IsAuthenticated)
  27. {
  28. foreach (var value in account.AuthenticationMethod)
  29. {
  30. ((ClaimsIdentity)initialUser.Identity).AddClaim(new Claim("amr", value));
  31. }
  32. var tokenResponse = await TokenProvider.RequestAccessToken();
  33. if (tokenResponse.TryGetToken(out var token))
  34. {
  35. var request = new HttpRequestMessage(HttpMethod.Get, "Preferences/HasCompletedAdditionalInformation");
  36. request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Value);
  37. var response = await _httpClient.SendAsync(request);
  38. if (response.StatusCode != HttpStatusCode.OK)
  39. {
  40. throw new InvalidOperationException("Error accessing additional user info.");
  41. }
  42. var hasInfo = JsonSerializer.Deserialize<bool>(await response.Content.ReadAsStringAsync());
  43. if (!hasInfo)
  44. {
  45. // The actual pattern would be to cache this info to avoid constant queries to the server per auth update.
  46. // (By default once every minute)
  47. ((ClaimsIdentity)initialUser.Identity).AddClaim(new Claim("NewUser", "true"));
  48. }
  49. }
  50. }
  51. return initialUser;
  52. }
  53. }
  54. }