AuthHandler.cs
4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;
using JWT;
namespace AIAHTML5.WebAPI
{
public class AuthHandler:DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
HttpResponseMessage errorResponse = null;
try
{
IEnumerable<string> authHeaderValues;
request.Headers.TryGetValues("Authorization", out authHeaderValues);
if (authHeaderValues == null)
return base.SendAsync(request, cancellationToken); // cross fingers
var bearerToken = authHeaderValues.ElementAt(0);
var token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
//var secret = ConfigurationManager.AppSettings.Get("jwtKey");
var secret = "secretKey";
Thread.CurrentPrincipal = ValidateToken(
token,
secret,
true
);
if (HttpContext.Current != null)
{
HttpContext.Current.User = Thread.CurrentPrincipal;
}
}
catch (SignatureVerificationException ex)
{
errorResponse = request.CreateErrorResponse(HttpStatusCode.Unauthorized, ex.Message);
}
catch (Exception ex)
{
errorResponse = request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
}
return errorResponse != null
? Task.FromResult(errorResponse)
: base.SendAsync(request, cancellationToken);
}
private static ClaimsPrincipal ValidateToken(string token, string secret, bool checkExpiration)
{
var jsonSerializer = new JavaScriptSerializer();
var payloadJson = JsonWebToken.Decode(token, secret);
var payloadData = jsonSerializer.Deserialize<Dictionary<string, object>>(payloadJson);
object exp;
if (payloadData != null && (checkExpiration && payloadData.TryGetValue("exp", out exp)))
{
var validTo = FromUnixTime(long.Parse(exp.ToString()));
if (DateTime.Compare(validTo, DateTime.UtcNow) <= 0)
{
throw new Exception(
string.Format("Token is expired. Expiration: '{0}'. Current: '{1}'", validTo, DateTime.UtcNow));
}
}
var subject = new ClaimsIdentity("Federation", ClaimTypes.Name, ClaimTypes.Role);
var claims = new List<Claim>();
if (payloadData != null)
foreach (var pair in payloadData)
{
var claimType = pair.Key;
var source = pair.Value as ArrayList;
if (source != null)
{
claims.AddRange(from object item in source
select new Claim(claimType, item.ToString(), ClaimValueTypes.String));
continue;
}
switch (pair.Key)
{
case "name":
claims.Add(new Claim(ClaimTypes.Name, pair.Value.ToString(), ClaimValueTypes.String));
break;
case "surname":
claims.Add(new Claim(ClaimTypes.Surname, pair.Value.ToString(), ClaimValueTypes.String));
break;
case "email":
claims.Add(new Claim(ClaimTypes.Email, pair.Value.ToString(), ClaimValueTypes.Email));
break;
case "role":
claims.Add(new Claim(ClaimTypes.Role, pair.Value.ToString(), ClaimValueTypes.String));
break;
case "userId":
claims.Add(new Claim(ClaimTypes.UserData, pair.Value.ToString(), ClaimValueTypes.Integer));
break;
default:
claims.Add(new Claim(claimType, pair.Value.ToString(), ClaimValueTypes.String));
break;
}
}
subject.AddClaims(claims);
return new ClaimsPrincipal(subject);
}
private static DateTime FromUnixTime(long unixTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
}
}