mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-26 16:24:10 +08:00
Update authentication.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
|
|||||||
@@ -18,7 +18,12 @@ namespace MQTTnet.Server.Web
|
|||||||
{
|
{
|
||||||
private readonly ILogger<AuthenticationHandler> _logger;
|
private readonly ILogger<AuthenticationHandler> _logger;
|
||||||
|
|
||||||
public AuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory loggerFactory, UrlEncoder encoder, ISystemClock clock, ILogger<AuthenticationHandler> logger)
|
public AuthenticationHandler(
|
||||||
|
IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||||
|
ILoggerFactory loggerFactory,
|
||||||
|
UrlEncoder encoder,
|
||||||
|
ISystemClock clock,
|
||||||
|
ILogger<AuthenticationHandler> logger)
|
||||||
: base(options, loggerFactory, encoder, clock)
|
: base(options, loggerFactory, encoder, clock)
|
||||||
{
|
{
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
@@ -26,11 +31,9 @@ namespace MQTTnet.Server.Web
|
|||||||
|
|
||||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
{
|
{
|
||||||
await Task.CompletedTask;
|
|
||||||
|
|
||||||
if (!Request.Headers.ContainsKey(HeaderNames.Authorization))
|
if (!Request.Headers.ContainsKey(HeaderNames.Authorization))
|
||||||
{
|
{
|
||||||
return AuthenticateResult.Fail("Missing Authorization Header");
|
return AuthenticateResult.NoResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -83,6 +86,10 @@ namespace MQTTnet.Server.Web
|
|||||||
|
|
||||||
return AuthenticateResult.Fail(exception);
|
return AuthenticateResult.Fail(exception);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateUser(PythonDictionary context)
|
private bool ValidateUser(PythonDictionary context)
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -15,6 +17,7 @@ using MQTTnet.Server.Logging;
|
|||||||
using MQTTnet.Server.Mqtt;
|
using MQTTnet.Server.Mqtt;
|
||||||
using MQTTnet.Server.Scripting;
|
using MQTTnet.Server.Scripting;
|
||||||
using MQTTnet.Server.Scripting.DataSharing;
|
using MQTTnet.Server.Scripting.DataSharing;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||||
|
|
||||||
namespace MQTTnet.Server.Web
|
namespace MQTTnet.Server.Web
|
||||||
@@ -115,17 +118,22 @@ namespace MQTTnet.Server.Web
|
|||||||
services.AddSwaggerGen(c =>
|
services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
c.DescribeAllEnumsAsStrings();
|
c.DescribeAllEnumsAsStrings();
|
||||||
c.AddSecurityDefinition("Basic", new OpenApiSecurityScheme
|
|
||||||
|
var securityScheme = new OpenApiSecurityScheme
|
||||||
{
|
{
|
||||||
Scheme = "Basic",
|
Scheme = "Basic",
|
||||||
Name = HeaderNames.Authorization,
|
Name = HeaderNames.Authorization,
|
||||||
Type = SecuritySchemeType.Http,
|
Type = SecuritySchemeType.Http,
|
||||||
In = ParameterLocation.Header
|
In = ParameterLocation.Header
|
||||||
});
|
};
|
||||||
|
|
||||||
|
c.AddSecurityDefinition("Swagger", securityScheme);
|
||||||
|
|
||||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
{
|
{
|
||||||
[new OpenApiSecurityScheme { Name = "Basic" }] = new List<string>()
|
[securityScheme] = new List<string>()
|
||||||
});
|
});
|
||||||
|
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo
|
c.SwaggerDoc("v1", new OpenApiInfo
|
||||||
{
|
{
|
||||||
Title = "MQTTnet.Server API",
|
Title = "MQTTnet.Server API",
|
||||||
@@ -145,7 +153,9 @@ namespace MQTTnet.Server.Web
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddAuthentication("Basic").AddScheme<AuthenticationSchemeOptions, AuthenticationHandler>("Basic", null);
|
services.AddAuthentication("Basic")
|
||||||
|
.AddScheme<AuthenticationSchemeOptions, AuthenticationHandler>("Basic", null)
|
||||||
|
.AddCookie();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadMqttSettings(IServiceCollection services)
|
private void ReadMqttSettings(IServiceCollection services)
|
||||||
@@ -200,7 +210,7 @@ namespace MQTTnet.Server.Web
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 400;
|
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,9 +2,19 @@
|
|||||||
"""
|
"""
|
||||||
This function is invoked whenever a user tries to access protected HTTP resources.
|
This function is invoked whenever a user tries to access protected HTTP resources.
|
||||||
This function must exist and return a proper value. Otherwise the request is denied.
|
This function must exist and return a proper value. Otherwise the request is denied.
|
||||||
|
All authentication data must be sent via using the "Authorization" header. This header
|
||||||
|
will be parsed and all values will be exposed to the context.
|
||||||
"""
|
"""
|
||||||
|
header_value = context["header_value"] # The untouched header value.
|
||||||
|
|
||||||
username = context["username"]
|
scheme = context["scheme"]
|
||||||
password = context["password"]
|
parameter = context["parameter"]
|
||||||
|
|
||||||
|
username = context["username"] # Only set if proper "Basic" authorization is used.
|
||||||
|
password = context["password"] # Only set if proper "Basic" authorization is used.
|
||||||
|
|
||||||
context["is_authenticated"] = True # Change this to _False_ in case of invalid credentials.
|
context["is_authenticated"] = True # Change this to _False_ in case of invalid credentials.
|
||||||
|
|
||||||
|
# Example for an API key with proper format.
|
||||||
|
if header_value == "APIKey 123456":
|
||||||
|
context["is_authenticated"] = True
|
||||||
@@ -38,10 +38,10 @@
|
|||||||
},
|
},
|
||||||
"CommunicationTimeout": 15, // In seconds.
|
"CommunicationTimeout": 15, // In seconds.
|
||||||
"ConnectionBacklog": 10, // Set 0 to disable
|
"ConnectionBacklog": 10, // Set 0 to disable
|
||||||
"EnablePersistentSessions": false,
|
"EnablePersistentSessions": true,
|
||||||
"MaxPendingMessagesPerClient": 250,
|
"MaxPendingMessagesPerClient": 250,
|
||||||
"RetainedApplicationMessages": {
|
"RetainedApplicationMessages": {
|
||||||
"Persist": false,
|
"Persist": true,
|
||||||
"Path": "RetainedApplicationMessages.json",
|
"Path": "RetainedApplicationMessages.json",
|
||||||
"WriteInterval": 10 // In seconds.
|
"WriteInterval": 10 // In seconds.
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user