Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

TokenValidationHandler.cs 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using System;
  2. using System.Configuration;
  3. using System.IdentityModel.Tokens;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Net.Http;
  7. using System.Security.Claims;
  8. using System.ServiceModel.Security.Tokens;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using iiie.Authentication.DBO;
  12. using iiie.Logs.DataAccess;
  13. using iiie.Logs.DBO;
  14. using Newtonsoft.Json;
  15. namespace iiie.Authentication.Business.JWT
  16. {
  17. /// <summary>
  18. /// Handler for token authentication
  19. /// </summary>
  20. public abstract class TokenValidationHandler
  21. : DelegatingHandler
  22. {
  23. /// <summary>
  24. /// Gets the token from the HTTP AUthorization header
  25. /// </summary>
  26. /// <param name="request">The HTTP request</param>
  27. /// <param name="token">The variable to store the token</param>
  28. /// <returns>True if the token has been found, false otherwise</returns>
  29. private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
  30. {
  31. token = null;
  32. var auth = request.Headers.Authorization;
  33. if (auth == null || auth.Scheme != "Bearer")
  34. return false;
  35. token = auth.Parameter;
  36. return true;
  37. }
  38. /// <summary>
  39. /// Contructs a user dbo from the specified username and salt
  40. /// </summary>
  41. /// <param name="username">The username of the verified token</param>
  42. /// <param name="salt">The salt in the token</param>
  43. /// <returns>The user dbo, or null if user is not valid</returns>
  44. protected abstract BasicUserDbo GetUserDbo(string username, string salt);
  45. /// <summary>
  46. /// Attempts to verify user token
  47. /// </summary>
  48. /// <param name="request">The HTTP request</param>
  49. /// <param name="cancellationToken">Token used for cancelation</param>
  50. /// <returns>The HTTP response</returns>
  51. protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
  52. {
  53. OpResult<bool> error;
  54. string token;
  55. if (!TryRetrieveToken(request, out token))
  56. {
  57. return base.SendAsync(request, cancellationToken);
  58. }
  59. try
  60. {
  61. var claim = TokenManager.ParseToken(token);
  62. Thread.CurrentPrincipal = claim;
  63. var name = ((ClaimsIdentity)claim.Identity).Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name);
  64. var salt = ((ClaimsIdentity)claim.Identity).Claims.FirstOrDefault(x => x.Type == ClaimTypes.Authentication);
  65. var data = ((ClaimsIdentity)claim.Identity).Claims.FirstOrDefault(x => x.Type == ClaimTypes.UserData);
  66. if (name == null || salt == null)
  67. {
  68. error = OpResult<bool>.Error(ResultStatus.LoginError, string.Format("Incomplete token; username is present: {0}; salt is present {1}", name != null, salt != null), "Incomplete token").Log();
  69. }
  70. else
  71. {
  72. var user = GetUserDbo(name.Value, salt.Value);
  73. if (user == null)
  74. {
  75. error = OpResult<bool>.Error(ResultStatus.LoginError,
  76. string.Format("Username {0} not found", name.Value), "").Log();
  77. }
  78. else
  79. {
  80. if (data != null)
  81. {
  82. user.TokenData = JsonConvert.DeserializeObject(data.Value);
  83. }
  84. UserStorage.BasicUserDbo = user;
  85. return base.SendAsync(request, cancellationToken);
  86. }
  87. }
  88. }
  89. catch (Exception e)
  90. {
  91. error = OpResult<bool>.Error(ResultStatus.LoginError, e, "Failed to validate token").Log();
  92. }
  93. var resp = request.CreateErrorResponse(HttpStatusCode.Unauthorized, error.PublicDetails);
  94. return Task<HttpResponseMessage>.Factory.StartNew(() => resp, cancellationToken);
  95. }
  96. }
  97. }