Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class TokenAuthAttribute : AuthorizeAttribute
- {
- private readonly TokenAuth tokenAuth;
- public TokenAuthAttribute()
- {
- this.tokenAuth = Global.ObjectFactory.GetInstance<TokenAuth>();
- }
- protected override bool IsAuthorized(HttpActionContext actionContext)
- {
- IEnumerable<string> tokens;
- var found = actionContext.Request.Headers.TryGetValues("Token", out tokens);
- if (!found)
- {
- return false;
- }
- int userId;
- var valid = this.tokenAuth.ValidateToken(tokens.FirstOrDefault(), out userId);
- if (valid)
- {
- actionContext.Request.Headers.Add("UserId", userId.ToString());
- }
- return valid;
- }
- protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
- {
- actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
- {
- Content =
- new StringContent(
- "The request needs a valid token! Log in and try again.")
- };
- }
- }
- public class TokenAuth
- {
- private readonly UserDomain userDomain;
- private static readonly string StaticEncriptionPassword = "R3ally_Str0ng_PAssW0rD";
- public TokenAuth(UserDomain userDomain)
- {
- this.userDomain = userDomain;
- }
- public bool TryGenerateToken(string email, string password, out string token)
- {
- token = string.Empty;
- int userId;
- var validLogin = this.ValidateLogin(email, password, out userId);
- if (!validLogin)
- {
- return false;
- }
- token = this.GenerateToken(userId);
- return true;
- }
- public bool ValidateToken(string token, out int userId)
- {
- userId = -1;
- token = HttpContext.Current.Server.UrlDecode(token);
- if (string.IsNullOrWhiteSpace(token))
- {
- return false;
- }
- var encriptedData = Convert.FromBase64String(token);
- var data = AesDecrypt(encriptedData);
- if (data.Length < 9) //invalid
- {
- return false;
- }
- var when = DateTime.FromBinary(BitConverter.ToInt64(data, 0)); //8 bytes
- userId = BitConverter.ToInt32(data, 8); //from 9th byte
- return when >= DateTime.UtcNow.AddHours(-24);
- }
- public string RefreshToken(int userId)
- {
- return this.GenerateToken(userId);
- }
- private bool ValidateLogin(string email, string password, out int userId)
- {
- userId = -1;
- var user = this.userDomain.GetUserByEmail(email);
- if (user == null)
- {
- return false;
- }
- var correctPassword = PasswordHash.ValidatePassword(password, user.PasswordHash);
- if (correctPassword)
- {
- userId = user.UserId;
- }
- return correctPassword;
- }
- private string GenerateToken(int userId)
- {
- var time = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
- var key = Guid.NewGuid().ToByteArray();
- var userIdBits = BitConverter.GetBytes(userId);
- var tokenBytes = time.Concat(userIdBits).Concat(key).ToArray();
- var token = Convert.ToBase64String(AesEncrypt(tokenBytes));
- return HttpContext.Current.Server.UrlEncode(token);
- }
- /// <summary>
- /// Methods to encript byte arrays. Reference to the source: http://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt
- /// </summary>
- /// <param name="bytesToBeEncrypted"></param>
- /// <returns></returns>
- private static byte[] AesEncrypt(byte[] bytesToBeEncrypted)
- {
- byte[] encryptedBytes = null;
- // Set your salt here, change it to meet your flavor:
- // The salt bytes must be at least 8 bytes.
- byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
- using (var ms = new MemoryStream())
- using (var aes = new RijndaelManaged())
- {
- aes.KeySize = 256;
- aes.BlockSize = 128;
- if (StaticEncriptionPassword != null)
- {
- var key = new Rfc2898DeriveBytes(StaticEncriptionPassword, saltBytes, 1000);
- aes.Key = key.GetBytes(aes.KeySize / 8);
- aes.IV = key.GetBytes(aes.BlockSize / 8);
- }
- aes.Mode = CipherMode.CBC;
- using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
- {
- cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
- cs.Close();
- }
- encryptedBytes = ms.ToArray();
- }
- return encryptedBytes;
- }
- private static byte[] AesDecrypt(byte[] bytesToBeDecrypted)
- {
- byte[] decryptedBytes = null;
- // Set your salt here, change it to meet your flavor:
- // The salt bytes must be at least 8 bytes.
- byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
- using (MemoryStream ms = new MemoryStream())
- using (RijndaelManaged aes = new RijndaelManaged())
- {
- aes.KeySize = 256;
- aes.BlockSize = 128;
- if (StaticEncriptionPassword != null)
- {
- var key = new Rfc2898DeriveBytes(StaticEncriptionPassword, saltBytes, 1000);
- aes.Key = key.GetBytes(aes.KeySize / 8);
- aes.IV = key.GetBytes(aes.BlockSize / 8);
- }
- aes.Mode = CipherMode.CBC;
- using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
- {
- cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
- cs.Close();
- }
- decryptedBytes = ms.ToArray();
- }
- return decryptedBytes;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement