Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
HttpModule.cs
1using System;
3using System.Security.Cryptography.X509Certificates;
4using System.Threading.Tasks;
5using Waher.Events;
12using Waher.Security;
17
18namespace Waher.Things.Http
19{
23 [Singleton]
24 [ModuleDependency("Waher.Service.IoTBroker.XmppServerModule")] // For JWT factory, if available.
26 {
27 internal const string PostPrivileges = "Admin.SensorData.Post";
28
29 private static HttpServer webServer;
30 private static SensorDataReceptorResource api;
31 private static LocalWebServerNode localWebServerNode;
32 private static X509Certificate certificate;
33 private static Scheduler scheduler;
34 private static string rootFolder;
35
39 public Task Start()
40 {
41 try
42 {
43 if (!Types.TryGetModuleParameter("HTTP", out object Obj) ||
44 !(Obj is HttpServer WebServer))
45 {
46 Log.Error("Local Web Server not found.");
47 return Task.CompletedTask;
48 }
49
50 webServer = WebServer;
51
52 if (!Types.TryGetModuleParameter("Root", out Obj) ||
53 !(Obj is string RootFolder))
54 {
55 Log.Warning("Root folder not defined.");
56 rootFolder = null;
57 }
58 else
59 rootFolder = RootFolder;
60
61 if (!Types.TryGetModuleParameter("Scheduler", out Obj) ||
62 !(Obj is Scheduler Scheduler))
63 {
64 Log.Warning("Scheduler not available.");
65 scheduler = null;
66 }
67 else
68 scheduler = Scheduler;
69
71
72 api = new SensorDataReceptorResource("/ReportSensorData", Schemes);
73 webServer.Register(api);
74 }
75 catch (Exception ex)
76 {
77 Log.Exception(ex);
78 }
79
80 return Task.CompletedTask;
81 }
82
90 {
91 string Privilege;
92
93 if (string.IsNullOrEmpty(Request.SubPath))
94 Privilege = PostPrivileges;
95 else
96 Privilege = PostPrivileges + Request.SubPath.Replace('/', '.');
97
99 }
100
109 {
110 return GetAuthenticationSchemes(Array.Empty<string>());
111 }
112
121 public static HttpAuthenticationScheme[] GetAuthenticationSchemes(string RequiredPrivilege)
122 {
123 return GetAuthenticationSchemes(new SinglePrivilege<HttpRequest>(RequiredPrivilege));
124 }
125
135 {
136 if ((RequiredPrivileges?.Length ?? 0) == 0)
138 else
139 return GetAuthenticationSchemes(Networking.HTTP.Authentication.RequiredPrivileges.GetAuthorization(RequiredPrivileges));
140 }
141
151 {
152 return GetAuthenticationSchemes(null, Authorization);
153 }
154
165 public static HttpAuthenticationScheme[] GetAuthenticationSchemes(Uri ResourceMetaData)
166 {
167 return GetAuthenticationSchemes(ResourceMetaData, Array.Empty<string>());
168 }
169
182 Uri ResourceMetaData, string RequiredPrivilege)
183 {
184 return GetAuthenticationSchemes(ResourceMetaData,
185 new SinglePrivilege<HttpRequest>(RequiredPrivilege));
186 }
187
200 Uri ResourceMetaData, params string[] RequiredPrivileges)
201 {
202 if ((RequiredPrivileges?.Length ?? 0) == 0)
203 return GetAuthenticationSchemes(ResourceMetaData, (IAuthorization<HttpRequest>)null);
204 else
205 {
206 return GetAuthenticationSchemes(ResourceMetaData,
207 Networking.HTTP.Authentication.RequiredPrivileges.GetAuthorization(RequiredPrivileges));
208 }
209 }
210
217 public static void GetDomainParameters(out string Domain, out int MinStrength,
218 out bool Encrypted)
219 {
220 if (!Types.TryGetModuleParameter("X509", out object Obj) ||
221 !(Obj is X509Certificate Certificate))
222 {
223 if (Types.TryGetModuleParameter("Realm", out Obj) &&
224 Obj is string Realm)
225 {
226 Domain = Realm;
227 }
228 else
229 Domain = null;
230
231 Encrypted = false;
232 MinStrength = 0;
233 }
234 else
235 {
236 certificate = Certificate;
237 Domain = BinaryTcpClient.GetDomainFromSubject(Certificate.Subject);
238 Encrypted = Domain != "localhost";
239 MinStrength = 128;
240 }
241 }
242
255 Uri ResourceMetaData, IAuthorization<HttpRequest> Authorization)
256 {
257 List<HttpAuthenticationScheme> Schemes = new List<HttpAuthenticationScheme>();
258
259 GetDomainParameters(out string Domain, out int MinStrength, out bool Encrypted);
260
261 if (!Types.TryGetModuleParameter("Users", out IUserSource UserSource))
262 UserSource = Users.Source; // Default users source
263
266 {
267 Schemes.Add(new JwtAuthentication(Encrypted, MinStrength, Domain,
268 UserSource, JwtFactory, ResourceMetaData));
269
270 // Any JWT token generated by the server will suffice. Does not have to point to a
271 // registered user.
272 }
273
274 webServer ??= Types.TryGetModuleParameter<HttpServer>("HTTP");
275
276 if (!(webServer is null) && webServer.ClientCertificates != ClientCertificates.NotUsed)
277 Schemes.Add(new MutualTlsAuthentication(UserSource));
278
279 Schemes.Add(new BasicAuthentication(Encrypted, MinStrength, Domain, UserSource));
280 Schemes.Add(new DigestAuthentication(Encrypted, MinStrength, DigestAlgorithm.MD5, Domain, UserSource));
281 Schemes.Add(new DigestAuthentication(Encrypted, MinStrength, DigestAlgorithm.SHA256, Domain, UserSource));
282 Schemes.Add(new DigestAuthentication(Encrypted, MinStrength, DigestAlgorithm.SHA3_256, Domain, UserSource));
283
284 if (!(webServer is null))
285 Schemes.Add(new SessionAuthentication(webServer));
286
287 if (Authorization is null)
288 return Schemes.ToArray();
289 else
290 {
291 return new HttpAuthenticationScheme[]
292 {
293 new RequiredPrivileges(Schemes.ToArray(), Authorization)
294 };
295 }
296 }
297
301 public static async Task CheckLocalWebServerNode()
302 {
303 foreach (INode Node in await MeteringTopology.Root.ChildNodes)
304 {
306 {
307 localWebServerNode = LocalWebServerNode;
308 break;
309 }
310 }
311
312 if (localWebServerNode is null)
313 {
314 localWebServerNode = new LocalWebServerNode()
315 {
316 NodeId = await (await Translator.GetDefaultLanguageAsync()).GetStringAsync(typeof(LocalWebServerNode), 1, "Local Web Server")
317 };
318
319 await MeteringTopology.Root.AddAsync(localWebServerNode);
320 }
321 }
322
326 public Task Stop()
327 {
328 if (!(webServer is null) && !(api is null))
329 {
330 webServer.Unregister(api);
331 webServer = null;
332 api = null;
333 }
334
335 return Task.CompletedTask;
336 }
337
342 public void UpdateCertificate(X509Certificate Certificate)
343 {
344 certificate = Certificate;
345 }
346
350 internal static X509Certificate Certificate => certificate;
351
355 internal static string RootFolder => rootFolder;
356
360 internal static HttpServer WebServer => webServer;
361
365 internal static Scheduler Scheduler => scheduler;
366
370 internal static LocalWebServerNode LocalWebServerNode => localWebServerNode;
371 }
372}
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:14
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1657
static void Warning(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a warning event.
Definition: Log.cs:576
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
Definition: Log.cs:692
Implements a binary TCP Client, by encapsulating a TcpClient. It also makes the use of TcpClient safe...
static string GetDomainFromSubject(string Subject)
Extracts the domain name from a certificate subject string.
Basic authentication mechanism, as defined in RFC 2617: https://tools.ietf.org/html/rfc2617
Digest authentication mechanism, as defined in RFC 2617: https://tools.ietf.org/html/rfc2617
mTLS authentication mechanism, where identity is taken from a valid client certificate.
Represents an HTTP authentication scheme that embeds a collection of authentication schemes,...
Authentication mechanism that makes sure the user has an established session with the web server.
Base class for all HTTP authentication schemes, as defined in RFC-7235: https://datatracker....
Represents an HTTP request.
Definition: HttpRequest.cs:22
string SubPath
Sub-path. If a resource is found handling the request, this property contains the trailing sub-path o...
Definition: HttpRequest.cs:194
Implements an HTTP server.
Definition: HttpServer.cs:41
HttpResource Register(HttpResource Resource)
Registers a resource with the server.
Definition: HttpServer.cs:1568
bool Unregister(HttpResource Resource)
Unregisters a resource from the server.
Definition: HttpServer.cs:1743
override void Add(ISniffer Sniffer)
ICommunicationLayer.Add
Definition: HttpServer.cs:1460
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:15
static bool TryGetModuleParameter(string Name, out object Value)
Tries to get a module parameter value.
Definition: Types.cs:607
Basic access point for runtime language localization.
Definition: Translator.cs:16
static async Task< Language > GetDefaultLanguageAsync()
Gets the default language.
Definition: Translator.cs:223
Class that can be used to schedule events in time. It uses a timer to execute tasks at the appointed ...
Definition: Scheduler.cs:14
Authorization based on a single privilege.
Use JWT tokens for authentication. The Bearer scheme defined in RFC 6750 is used: https://tools....
A factory that can create and validate JWT tokens.
Definition: JwtFactory.cs:66
bool Disposed
If the factory has been disposed.
Definition: JwtFactory.cs:272
Corresponds to a privilege in the system.
Definition: Privilege.cs:16
Corresponds to a user in the system.
Definition: User.cs:24
bool HasPrivilege(string Privilege)
If the user has a given privilege.
Definition: User.cs:187
Maintains the collection of all users in the system.
Definition: Users.cs:24
static IUserSource Source
User source.
Definition: Users.cs:37
static HttpAuthenticationScheme[] GetAuthenticationSchemes()
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:108
static HttpAuthenticationScheme[] GetAuthenticationSchemes(string RequiredPrivilege)
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:121
bool IsAuthorized(HttpRequest Request, IHasPrivileges User)
Checks if an user or object is authorized to perform an action.
Definition: HttpModule.cs:89
static async Task CheckLocalWebServerNode()
Checks if the Local Web Server Node has been created.
Definition: HttpModule.cs:301
static HttpAuthenticationScheme[] GetAuthenticationSchemes(Uri ResourceMetaData, IAuthorization< HttpRequest > Authorization)
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:254
Task Start()
Starts the module.
Definition: HttpModule.cs:39
Task Stop()
Stops the module.
Definition: HttpModule.cs:326
static HttpAuthenticationScheme[] GetAuthenticationSchemes(IAuthorization< HttpRequest > Authorization)
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:150
void UpdateCertificate(X509Certificate Certificate)
Updates the certificate used in mTLS negotiation.
Definition: HttpModule.cs:342
static HttpAuthenticationScheme[] GetAuthenticationSchemes(Uri ResourceMetaData, params string[] RequiredPrivileges)
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:199
static HttpAuthenticationScheme[] GetAuthenticationSchemes(params string[] RequiredPrivileges)
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:134
static HttpAuthenticationScheme[] GetAuthenticationSchemes(Uri ResourceMetaData, string RequiredPrivilege)
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:181
static HttpAuthenticationScheme[] GetAuthenticationSchemes(Uri ResourceMetaData)
Gets an array of authentication schemes available to authorize access to a web resource.
Definition: HttpModule.cs:165
static void GetDomainParameters(out string Domain, out int MinStrength, out bool Encrypted)
Gets domain parameters used in authentication.
Definition: HttpModule.cs:217
Node representing the local web server.
Web Service REST API that receives sensor data from external sources.
Defines the Metering Topology data source. This data source contains a tree structure of persistent r...
Interface for late-bound modules loaded at runtime.
Definition: IModule.cs:9
Basic authorization interface for objects of type T .
Interface for objects that have privileges.
Interface for Mutual TLS (mTLS) Clients or TLS servers.
Interface for data sources containing users.
Definition: IUserSource.cs:9
Interface for nodes that are published through the concentrator interface.
Definition: INode.cs:49
ClientCertificates
Client Certificate Options