Skip to content

Commit 360f328

Browse files
committed
- Challenge property moved from 'BasicOptions' to 'BasicHandler'.
- Comments added to the code.
1 parent 1fb2b8c commit 360f328

10 files changed

+105
-13
lines changed

LICENSE renamed to LICENSE.txt

File renamed without changes.

Mihir.AspNetCore.Authentication.Basic.sln

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
44
VisualStudioVersion = 15.0.27428.2011
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mihir.AspNetCore.Authentication.Basic", "Mihir.AspNetCore.Authentication.Basic\Mihir.AspNetCore.Authentication.Basic.csproj", "{F8FEFB06-9F93-4F50-8530-80F5C0A677FC}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mihir.AspNetCore.Authentication.Basic", "Mihir.AspNetCore.Authentication.Basic\Mihir.AspNetCore.Authentication.Basic.csproj", "{F8FEFB06-9F93-4F50-8530-80F5C0A677FC}"
7+
EndProject
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C704A959-E8CB-4F13-9212-D830FCEDBAEC}"
9+
ProjectSection(SolutionItems) = preProject
10+
LICENSE.txt = LICENSE.txt
11+
README.md = README.md
12+
EndProjectSection
713
EndProject
814
Global
915
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1-
namespace Mihir.AspNetCore.Authentication.Basic
1+
// Copyright (c) Mihir Dilip. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
namespace Mihir.AspNetCore.Authentication.Basic
25
{
6+
/// <summary>
7+
/// Default values used by basic authentication.
8+
/// </summary>
39
public static class BasicDefaults
410
{
11+
/// <summary>
12+
/// Default value for AuthenticationScheme
13+
/// </summary>
514
public const string AuthenticationScheme = "Basic";
6-
public const string DisplayName = "Basic";
715
}
816
}

Mihir.AspNetCore.Authentication.Basic/BasicExtensions.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
1-
using Microsoft.AspNetCore.Authentication;
1+
// Copyright (c) Mihir Dilip. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.Authentication;
25
using System;
36
using Microsoft.Extensions.DependencyInjection;
47
using Microsoft.Extensions.Options;
58

69
namespace Mihir.AspNetCore.Authentication.Basic
710
{
11+
/// <summary>
12+
/// Extension methods for basic authentication.
13+
/// </summary>
814
public static class BasicExtensions
915
{
16+
/// <summary>
17+
/// Adds basic authentication scheme to the project. It takes a implementation of <see cref="IBasicUserValidationService"/> as type parameter.
18+
/// </summary>
19+
/// <typeparam name="TBasicUserValidationService"></typeparam>
20+
/// <param name="configureOptions">Sets the <see cref="BasicOptions"/>. Realm option property must be set.</param>
21+
/// <returns>The instance of <see cref="AuthenticationBuilder"/></returns>
1022
public static AuthenticationBuilder AddBasic<TBasicUserValidationService>(this AuthenticationBuilder builder, Action<BasicOptions> configureOptions)
1123
where TBasicUserValidationService : class, IBasicUserValidationService
1224
{
25+
// Adds post configure options to the pipeline.
1326
builder.Services.AddSingleton<IPostConfigureOptions<BasicOptions>, BasicPostConfigureOptions>();
27+
28+
// Adds implementation of IBasicUserValidationService to the dependency container.
1429
builder.Services.AddTransient<IBasicUserValidationService, TBasicUserValidationService>();
1530

31+
// Adds basic authentication scheme to the pipeline.
1632
return builder.AddScheme<BasicOptions, BasicHandler>(BasicDefaults.AuthenticationScheme, configureOptions);
1733
}
1834
}

Mihir.AspNetCore.Authentication.Basic/BasicHandler.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System;
1+
// Copyright (c) Mihir Dilip. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
25
using System.Net.Http.Headers;
36
using System.Security.Claims;
47
using System.Text;
@@ -11,6 +14,9 @@
1114

1215
namespace Mihir.AspNetCore.Authentication.Basic
1316
{
17+
/// <summary>
18+
/// Inherited from <see cref="AuthenticationHandler{TOptions}"/> for basic authentication.
19+
/// </summary>
1420
public class BasicHandler : AuthenticationHandler<BasicOptions>
1521
{
1622
private readonly IBasicUserValidationService _basicUserValidationService;
@@ -21,26 +27,37 @@ public BasicHandler(IOptionsMonitor<BasicOptions> options, ILoggerFactory logger
2127
_basicUserValidationService = basicUserValidationService;
2228
}
2329

30+
private string Challenge => $"{BasicDefaults.AuthenticationScheme} realm=\"{Options.Realm}\", charset=\"UTF-8\"";
31+
2432
//protected new BasicEvents Events { get => (BasicEvents)base.Events; set => base.Events = value; }
2533
//protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new BasicEvents());
2634

35+
/// <summary>
36+
/// Searches the 'Authorization' header for 'Basic' scheme with base64 encoded username:password string value of which is validated using implementation of <see cref="IBasicUserValidationService"/> passed as type parameter when setting up basic authentication in the Startup.cs
37+
/// </summary>
38+
/// <returns></returns>
2739
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
2840
{
2941
if (!Request.Headers.ContainsKey(HeaderNames.Authorization))
3042
{
43+
// No 'Authorization' header found in the request.
3144
return AuthenticateResult.NoResult();
3245
}
3346

3447
if (!AuthenticationHeaderValue.TryParse(Request.Headers[HeaderNames.Authorization], out var headerValue))
3548
{
49+
// No valid 'Authorization' header found in the request.
3650
return AuthenticateResult.NoResult();
3751
}
3852

53+
3954
if (!headerValue.Scheme.Equals(BasicDefaults.AuthenticationScheme, StringComparison.OrdinalIgnoreCase))
4055
{
56+
// 'Authorization' header found but the scheme is not a basic scheme.
4157
return AuthenticateResult.NoResult();
4258
}
4359

60+
// Convert the base64 encoded 'username:password' to normal string and parse username and password from colon(:) separated string.
4461
var usernameAndPassword = Encoding.UTF8.GetString(Convert.FromBase64String(headerValue.Parameter));
4562
var usernameAndPasswordSplit = usernameAndPassword.Split(':');
4663
if (usernameAndPasswordSplit.Length != 2)
@@ -50,22 +67,32 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
5067
var username = usernameAndPasswordSplit[0];
5168
var password = usernameAndPasswordSplit[1];
5269

70+
// Validate username and password by using the implementation of IBasicUserValidationService.
5371
var isValidUser = await _basicUserValidationService.IsValidAsync(username, password);
5472
if (!isValidUser)
5573
{
5674
return AuthenticateResult.Fail("Invalid username or password");
5775
}
5876

77+
// Create 'AuthenticationTicket' and return as success if the above validation was successful.
5978
var claims = new[] { new Claim(ClaimTypes.Name, username) };
6079
var identity = new ClaimsIdentity(claims, Scheme.Name);
6180
var principal = new ClaimsPrincipal(identity);
6281
var ticket = new AuthenticationTicket(principal, Scheme.Name);
6382
return AuthenticateResult.Success(ticket);
6483
}
6584

85+
/// <summary>
86+
/// Handles the un-authenticated requests.
87+
/// Returns 401 status code in response.
88+
/// Adds 'WWW-Authenticate' with 'Basic' authentication scheme and 'Realm' in the response header
89+
/// to let the client know that 'Basic' authentication scheme is being used by the system.
90+
/// </summary>
91+
/// <param name="properties"></param>
92+
/// <returns></returns>
6693
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
6794
{
68-
Response.Headers[HeaderNames.WWWAuthenticate] = Options.Challenge;
95+
Response.Headers[HeaderNames.WWWAuthenticate] = Challenge;
6996
await base.HandleChallengeAsync(properties);
7097
}
7198
}

Mihir.AspNetCore.Authentication.Basic/BasicOptions.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1-
using Microsoft.AspNetCore.Authentication;
1+
// Copyright (c) Mihir Dilip. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.Authentication;
25

36
namespace Mihir.AspNetCore.Authentication.Basic
47
{
8+
/// <summary>
9+
/// Inherited from <see cref="AuthenticationSchemeOptions"/> to allow extra option properties for 'Basic' authentication.
10+
/// </summary>
511
public class BasicOptions : AuthenticationSchemeOptions
612
{
13+
/// <summary>
14+
/// This is required property. It is used when challenging un-authenticated requests.
15+
/// </summary>
716
public string Realm { get; set; }
817

9-
public string Challenge => $"{BasicDefaults.AuthenticationScheme} realm=\"{Realm}\", charset=\"UTF-8\"";
10-
1118
//public new BasicEvents Events
1219
//{
1320
// get => (BasicEvents)base.Events;

Mihir.AspNetCore.Authentication.Basic/BasicPostConfigureOptions.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
using System;
1+
// Copyright (c) Mihir Dilip. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
25
using Microsoft.Extensions.Options;
36

47
namespace Mihir.AspNetCore.Authentication.Basic
58
{
9+
/// <summary>
10+
/// This post configure options checks whether the required option property <see cref="BasicOptions.Realm" /> is set or not on <see cref="BasicOptions"/>.
11+
/// </summary>
612
class BasicPostConfigureOptions : IPostConfigureOptions<BasicOptions>
713
{
814
public void PostConfigure(string name, BasicOptions options)
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
using System.Threading.Tasks;
1+
// Copyright (c) Mihir Dilip. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System.Threading.Tasks;
25

36
namespace Mihir.AspNetCore.Authentication.Basic
47
{
8+
/// <summary>
9+
/// Implemention of this interface will be used by the 'Basic' authentication handler to validated the username and password.
10+
/// </summary>
511
public interface IBasicUserValidationService
612
{
13+
/// <summary>
14+
/// Implementation of the username & password validation logic.
15+
/// </summary>
16+
/// <param name="username"></param>
17+
/// <param name="password"></param>
18+
/// <returns></returns>
719
Task<bool> IsValidAsync(string username, string password);
820
}
921
}

Mihir.AspNetCore.Authentication.Basic/Mihir.AspNetCore.Authentication.Basic.csproj

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<Authors>Mihir Dilip</Authors>
66
<Company>Mihir Dilip</Company>
7-
<Description>Basic Scheme Authentication implementation for ASP.NET core</Description>
7+
<Description>Basic Scheme Authentication Implementation for ASP.NET Core 2.0</Description>
88
<RepositoryUrl>https://github.com/mihirdilip/Mihir.AspNetCore.Authentication.Basic</RepositoryUrl>
99
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
10+
<PackageProjectUrl>https://github.com/mihirdilip/Mihir.AspNetCore.Authentication.Basic</PackageProjectUrl>
11+
<Version>1.0.1</Version>
12+
<Copyright>Copyright (c) 2018 Mihir Dilip</Copyright>
13+
<PackageLicenseUrl>https://github.com/mihirdilip/Mihir.AspNetCore.Authentication.Basic/blob/master/LICENSE.txt</PackageLicenseUrl>
14+
<RepositoryType>GitHub</RepositoryType>
15+
<PackageIconUrl />
16+
<PackageTags>asp-net-core, aspnetcore, netstandard, netstandard20, basic-authentication, basicauthentication</PackageTags>
17+
<NeutralLanguage />
18+
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
19+
<PackageReleaseNotes>- Challenge property moved from BasicOptions to BasicHandler</PackageReleaseNotes>
1020
</PropertyGroup>
1121

1222
<ItemGroup>

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,4 @@ public class BasicUserValidationService : IBasicUserValidationService
8989
- [RFC 7617: Technical spec for HTTP Basic](https://tools.ietf.org/html/rfc7617)
9090

9191
## License
92-
[MIT License](LICENSE)
92+
[MIT License](LICENSE.txt)

0 commit comments

Comments
 (0)