Skip to content

Commit 2ee1c80

Browse files
authored
Merge pull request #63 from mo-esmp/feature/dashboard-auth
Implementing dashboard authorization filter.
2 parents b4038f4 + fc2b731 commit 2ee1c80

28 files changed

+338
-179
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,5 @@ MigrationBackup/
349349
# Ionide (cross platform F# VS Code tools) working folder
350350
.ionide/
351351
nuget.exe
352+
353+
.vshistory/

README.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58,45 +58,45 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
5858
}
5959
```
6060

61-
## Authorization: configuration
61+
## Options
62+
Options can be found in the [UIOptions](src/Serilog.Ui.Web/Extensions/UiOptions.cs) class.
63+
`internal` properties can generally be set via extension methods, see [SerilogUiOptionBuilderExtensions](src/Serilog.Ui.Web/Extensions/SerilogUiOptionBuilderExtensions.cs)
64+
65+
### Authorization
6266

63-
By default serilog-ui allows access to the log page only for local requests. In order to give appropriate rights for production use, you need to configure authorization. You can secure the log page by allowing specific users or roles to view logs:
67+
By default serilog-ui allows access to the log page only for local requests. In order to give appropriate rights for production use, you need to configure authorization. You can add your own implementations of the `IUiAuthorizationFilter` interface, whose Authorize method is used to allow or prohibit a request. The first step is to provide your own implementation.:
6468

6569
```csharp
66-
public void ConfigureServices(IServiceCollection services)
70+
public void Configure(IApplicationBuilder appBuilder)
6771
{
68-
services.AddSerilogUi(options => options
69-
.EnableAuthorization(authOptions =>
72+
appBuilder.UseSerilogUi(options =>
73+
{
74+
options.Authorization.AuthenticationType = AuthenticationType.Jwt;
75+
options.Authorization.Filters = new[]
7076
{
71-
authOption.AuthenticationType = AuthenticationType.Jwt; // or AuthenticationType.Cookie
72-
authOptions.Usernames = new[] { "User1", "User2" };
73-
authOptions.Roles = new[] { "AdminRole" };
74-
})
75-
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), "LogTableName"));
77+
new CustomAuthorizeFilter()
78+
};
79+
});
7680
// ...
7781
}
7882
```
79-
Only `User1` and `User2` or users with `AdminRole` role can view logs.
8083

8184
If you set `AuthenticationType` to `Jwt`, you can set a jwt token and an `Authorization` header will be added to the request and for `Cookie` just login into you website and no extra step is required.
8285

83-
To disable anonymous access for local requests, (e.g. for testing authentication locally) set `AlwaysAllowLocalRequests` to `false`.
84-
85-
To disable authorization on production, set `Enabled` to false.
86+
Here is an example of how you can implement your own authentication and authorization:
8687

8788
``` csharp
88-
services.AddSerilogUi(options => options
89-
.EnableAuthorization(authOption =>
89+
public class CustomAuthorizeFilter : IUiAuthorizationFilter
90+
{
91+
public bool Authorize(DashboardContext context)
9092
{
91-
authOption.AlwaysAllowLocalRequests = false; // disable anonymous access on local
92-
authOption.Enabled = false; // disable authorization access check on production
93-
})
94-
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), "Logs"));
95-
```
93+
var httpContext = context.GetHttpContext();
9694

97-
## Options
98-
Options can be found in the [UIOptions](src/Serilog.Ui.Web/Extensions/UiOptions.cs) class.
99-
`internal` properties can generally be set via extension methods, see [SerilogUiOptionBuilderExtensions](src/Serilog.Ui.Web/Extensions/SerilogUiOptionBuilderExtensions.cs)
95+
// Allow all authenticated users to see the Dashboard (potentially dangerous).
96+
return httpContext.User.Identity?.IsAuthenticated ?? false;
97+
}
98+
}
99+
```
100100

101101
### Log page URL
102102

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Microsoft.AspNetCore.Http;
2+
using Serilog.Ui.Web.Authorization;
3+
4+
namespace SampleWebApp.Authentication;
5+
6+
public class SerilogUiCustomAuthFilter : IUiAuthorizationFilter
7+
{
8+
public bool Authorize(HttpContext httpContext)
9+
{
10+
return httpContext.User.Identity is { IsAuthenticated: true };
11+
}
12+
}

samples/SampleWebApp/SampleWebApp.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@
2525
</ItemGroup>
2626

2727
<ItemGroup>
28-
<ProjectReference Include="..\..\src\Serilog.Ui.ElasticSearchProvider\Serilog.Ui.ElasticSearchProvider.csproj" />
29-
<ProjectReference Include="..\..\src\Serilog.Ui.MongoDbProvider\Serilog.Ui.MongoDbProvider.csproj" />
3028
<ProjectReference Include="..\..\src\Serilog.Ui.MsSqlServerProvider\Serilog.Ui.MsSqlServerProvider.csproj" />
31-
<ProjectReference Include="..\..\src\Serilog.Ui.PostgreSqlProvider\Serilog.Ui.PostgreSqlProvider.csproj" />
3229
<ProjectReference Include="..\..\src\Serilog.Ui.Web\Serilog.Ui.Web.csproj" />
3330
</ItemGroup>
3431

samples/SampleWebApp/Startup.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.Extensions.DependencyInjection;
88
using Microsoft.Extensions.Hosting;
99
using Microsoft.IdentityModel.Tokens;
10+
using SampleWebApp.Authentication;
1011
using SampleWebApp.Authentication.Jwt;
1112
using SampleWebApp.Data;
1213
using Serilog.Ui.MsSqlServerProvider;
@@ -39,11 +40,6 @@ public void ConfigureServices(IServiceCollection services)
3940
services.AddRazorPages();
4041

4142
services.AddSerilogUi(options => options
42-
.EnableAuthorization(authOption =>
43-
{
44-
authOption.AuthenticationType = AuthenticationType.Jwt;
45-
authOption.Usernames = new[] { "[email protected]" };
46-
})
4743
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), "Logs"));
4844

4945
services.AddSwaggerGen();
@@ -60,16 +56,17 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
6056
else
6157
{
6258
app.UseExceptionHandler("/Home/Error");
63-
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
59+
// The default HSTS value is 30 days. You may want to change this for production
60+
// scenarios, see https://aka.ms/aspnetcore-hsts.
6461
app.UseHsts();
6562
}
6663
app.UseHttpsRedirection();
6764
app.UseStaticFiles();
6865

6966
app.UseSwagger();
7067

71-
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
72-
// specifying the Swagger JSON endpoint.
68+
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger
69+
// JSON endpoint.
7370
app.UseSwaggerUI(c =>
7471
{
7572
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
@@ -79,11 +76,16 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
7976

8077
app.UseAuthentication();
8178
app.UseAuthorization();
82-
app.UseSerilogUi(x =>
79+
app.UseSerilogUi(options =>
8380
{
84-
x.RoutePrefix = "serilog-ui";
85-
x.HomeUrl = "/#Test";
86-
x.InjectJavascript("/js/serilog-ui/custom.js");
81+
options.RoutePrefix = "serilog-ui";
82+
options.HomeUrl = "/#Test";
83+
options.InjectJavascript("/js/serilog-ui/custom.js");
84+
options.Authorization = new AuthorizationOptions
85+
{
86+
AuthenticationType = AuthenticationType.Jwt,
87+
Filters = new[] { new SerilogUiCustomAuthFilter() }
88+
};
8789
});
8890

8991
app.UseEndpoints(endpoints =>

samples/SampleWebApp/appsettings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"ConnectionStrings": {
3-
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-SampleWebApp-93B544DE-DDCF-47C1-AD8A-BC87C4D6B954;Trusted_Connection=True;MultipleActiveResultSets=true"
3+
"DefaultConnection": "Server=(local);Database=aspnet-SampleWebApp-93B544DE-DDCF-47C1-AD8A-BC87C4D6B954;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
44
},
55

66
"AllowedHosts": "*",
77

88
"Jwt": {
99
"Audience": "SampleClient",
1010
"Issuer": "http://localhost:5000",
11-
"SecretKey": "Th!$P@ssw0rd",
11+
"SecretKey": "Th!$AlongP@ssw0rdForJwt",
1212
"ExpireDays": "30"
1313
},
1414

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using Microsoft.AspNetCore.Http;
2+
3+
namespace Serilog.Ui.Web.Authorization
4+
{
5+
public interface IUiAuthorizationFilter
6+
{
7+
bool Authorize(HttpContext httpContext);
8+
}
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Microsoft.AspNetCore.Http;
2+
3+
namespace Serilog.Ui.Web.Authorization
4+
{
5+
public class LocalRequestsOnlyAuthorizationFilter : IUiAuthorizationFilter
6+
{
7+
public bool Authorize(HttpContext httpContext)
8+
{
9+
return httpContext.Request.IsLocal();
10+
}
11+
}
12+
}

src/Serilog.Ui.Web/Extensions/ApplicationBuilderExtensions.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
using Microsoft.AspNetCore.Builder;
2-
using Microsoft.Extensions.DependencyInjection;
32
using System;
43

54
namespace Serilog.Ui.Web
65
{
76
/// <summary>
8-
/// Contains extensions for configuring routing on an <see cref="IApplicationBuilder"/>.
7+
/// Contains extensions for configuring routing on an <see cref="IApplicationBuilder"/>.
98
/// </summary>
109
public static class ApplicationBuilderExtensions
1110
{
1211
/// <summary>
13-
/// Adds a <see cref="SerilogUiMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>.
12+
/// Adds a <see cref="SerilogUiMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>.
1413
/// </summary>
1514
/// <param name="applicationBuilder">
16-
/// The <see cref="IApplicationBuilder"/> to add the middleware to.
15+
/// The <see cref="IApplicationBuilder"/> to add the middleware to.
1716
/// </param>
18-
/// <param name="options"> The options to configure SerilogUI dashboard. </param>
19-
/// <returns> IApplicationBuilder. </returns>
20-
/// <exception cref="ArgumentNullException"> throw if applicationBuilder if null </exception>
17+
/// <param name="options">The options to configure Serilog UI dashboard.</param>
18+
/// <returns>IApplicationBuilder.</returns>
19+
/// <exception cref="ArgumentNullException">throw if applicationBuilder if null</exception>
2120
public static IApplicationBuilder UseSerilogUi(this IApplicationBuilder applicationBuilder, Action<UiOptions> options = null)
2221
{
2322
if (applicationBuilder == null)
@@ -26,12 +25,6 @@ public static IApplicationBuilder UseSerilogUi(this IApplicationBuilder applicat
2625
var uiOptions = new UiOptions();
2726
options?.Invoke(uiOptions);
2827

29-
var scope = applicationBuilder.ApplicationServices.CreateScope();
30-
var authOptions = scope.ServiceProvider.GetService<AuthorizationOptions>();
31-
uiOptions.AuthType = authOptions.AuthenticationType.ToString();
32-
33-
scope.Dispose();
34-
3528
return applicationBuilder.UseMiddleware<SerilogUiMiddleware>(uiOptions);
3629
}
3730
}

src/Serilog.Ui.Web/Extensions/AuthorizationOptions.cs

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,27 @@
1-
using System.Collections.Generic;
1+
using Serilog.Ui.Web.Authorization;
2+
using System.Collections.Generic;
23

34
namespace Serilog.Ui.Web
45
{
56
/// <summary>
6-
/// The options to be used by SerilogUI to log access authorization.
7+
/// The options to be used by SerilogUI to log access authorization.
78
/// </summary>
89
public class AuthorizationOptions
910
{
1011
/// <summary>
11-
/// Gets or sets the type of the authentication.
12+
/// Gets or sets the type of the authentication.
1213
/// </summary>
13-
/// <value> The type of the authentication. </value>
14-
public AuthenticationType AuthenticationType { get; set; }
14+
/// <value>The type of the authentication.</value>
15+
public AuthenticationType AuthenticationType { get; set; } = AuthenticationType.Cookie;
1516

1617
/// <summary>
17-
/// Gets or sets the authorized usernames.
18+
/// Gets or sets the authorized usernames.
1819
/// </summary>
19-
/// <value> The usernames. </value>
20-
public IEnumerable<string> Usernames { get; set; }
21-
22-
/// <summary>
23-
/// Gets or sets the authorized roles.
24-
/// </summary>
25-
/// <value> The roles. </value>
26-
public IEnumerable<string> Roles { get; set; }
27-
28-
/// <summary>
29-
/// Gets or sets a value indicating whether this <see cref="AuthorizationOptions"/> is enabled.
30-
/// </summary>
31-
/// <value> <c> true </c> if enabled; otherwise, <c> false </c>. </value>
32-
public bool Enabled { get; set; } = true;
33-
34-
/// <summary>
35-
/// Whether to always allow local requests, defaults to <c>true</c>.
36-
/// </summary>
37-
/// <value> <c> true </c> if enabled; otherwise, <c> false </c>. </value>
38-
public bool AlwaysAllowLocalRequests { get; set; } = true;
20+
/// <value>The usernames.</value>
21+
public IEnumerable<IUiAuthorizationFilter> Filters { get; set; } = new List<IUiAuthorizationFilter>()
22+
{
23+
new LocalRequestsOnlyAuthorizationFilter()
24+
};
3925
}
4026

4127
public enum AuthenticationType

0 commit comments

Comments
 (0)