forked from PeterWaher/IoTGateway
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJwtAuthentication.cs
More file actions
86 lines (78 loc) · 2.47 KB
/
JwtAuthentication.cs
File metadata and controls
86 lines (78 loc) · 2.47 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
using System;
using System.Threading.Tasks;
using Waher.Networking.HTTP;
using Waher.Networking.HTTP.HeaderFields;
using Waher.Security.LoginMonitor;
namespace Waher.Security.JWT
{
/// <summary>
/// Use JWT tokens for authentication. The Bearer scheme defined in RFC 6750 is used:
/// https://tools.ietf.org/html/rfc6750
/// </summary>
public class JwtAuthentication : HttpAuthenticationScheme
{
private readonly IUserSource users;
private readonly JwtFactory factory;
private readonly string realm;
/// <summary>
/// Use JWT tokens for authentication. The Bearer scheme defined in RFC 6750 is used:
/// https://tools.ietf.org/html/rfc6750
/// </summary>
/// <param name="Realm">Realm.</param>
/// <param name="Users">Collection of users to authenticate against.</param>
/// <param name="Factory">JWT token factory.</param>
public JwtAuthentication(string Realm, IUserSource Users, JwtFactory Factory)
{
this.realm = Realm;
this.users = Users;
this.factory = Factory;
}
/// <summary>
/// Gets a challenge for the authenticating client to respond to.
/// </summary>
/// <returns>Challenge string.</returns>
public override string GetChallenge()
{
return "Bearer realm=\"" + this.realm + "\"";
}
/// <summary>
/// Checks if the request is authorized.
/// </summary>
/// <param name="Request">Request object.</param>
/// <returns>User object, if authenticated, or null otherwise.</returns>
public override async Task<IUser> IsAuthenticated(HttpRequest Request)
{
HttpFieldAuthorization Authorization = Request.Header.Authorization;
if (Authorization != null && Authorization.Value.StartsWith("Bearer ", StringComparison.CurrentCultureIgnoreCase))
{
try
{
string TokenStr = Authorization.Value.Substring(7).Trim();
JwtToken Token = new JwtToken(TokenStr);
string UserName = Token.Subject;
if (!this.factory.IsValid(Token) || UserName is null)
{
LoginAuditor.Fail("Login attempt failed.", UserName ?? string.Empty, Request.RemoteEndPoint, "HTTP");
return null;
}
IUser User = await this.users.TryGetUser(UserName);
if (User is null)
{
LoginAuditor.Fail("Login attempt failed.", UserName, Request.RemoteEndPoint, "HTTP");
return null;
}
else
{
LoginAuditor.Success("Login successful.", UserName, Request.RemoteEndPoint, "HTTP");
return User;
}
}
catch (Exception)
{
return null;
}
}
return null;
}
}
}