Skip to content

Commit

Permalink
Merge pull request #10 from elsupergomez/update-asp-net-core-to-2.0
Browse files Browse the repository at this point in the history
Update asp net core to 2.0
  • Loading branch information
RodrigoPereyraDiaz authored Jul 2, 2019
2 parents 881b6df + 6ee2ba3 commit 1b06d9a
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 152 deletions.
8 changes: 6 additions & 2 deletions MakingSense.AspNetCore.Authentication.SimpleToken.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
# Visual Studio Version 16
VisualStudioVersion = 16.0.28917.181
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1A4906E1-3779-42B3-BE5D-2079B4D0C0C9}"
EndProject
Expand All @@ -12,6 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.gitignore = .gitignore
appveyor.yml = appveyor.yml
LICENSE = LICENSE
NuGet.Config = NuGet.Config
README.md = README.md
EndProjectSection
EndProject
Expand All @@ -34,4 +35,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{209CD8C9-0545-4A2E-826D-5B83044261AF} = {1A4906E1-3779-42B3-BE5D-2079B4D0C0C9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B2C5D2C9-1449-47DC-80D9-FD90D490015A}
EndGlobalSection
EndGlobal
7 changes: 7 additions & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,12 @@
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="makingsense-aspnet" value="https://ci.appveyor.com/nuget/makingsense-aspnet" />
</packageSources>
<packageSourceCredentials>
<makingsense-aspnet>
<add key="Username" value="[email protected]" />
<add key="ClearTextPassword" value="4@pdw@BlfpQn" />
</makingsense-aspnet>
</packageSourceCredentials>
</configuration>
29 changes: 26 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# SimpleToken Authentication Middleware
# SimpleToken Authentication

This package allows to extract token from authenticated requests and delegate it to an appropriated ISecurityTokenValidator and generate and AuthenticationTicket.

## Behavior

### Token extraction details

This middleware tries to support almost [RFC 6750](http://tools.ietf.org/html/rfc6750) and some licenses based on [GitHub behavior](https://developer.github.com/v3/oauth/#use-the-access-token-to-access-the-api). But does not support Form-Encoded Body Parameter (http://tools.ietf.org/html/rfc6750#section-2.2).
This tries to support almost [RFC 6750](http://tools.ietf.org/html/rfc6750) and some licenses based on [GitHub behavior](https://developer.github.com/v3/oauth/#use-the-access-token-to-access-the-api). But does not support Form-Encoded Body Parameter (http://tools.ietf.org/html/rfc6750#section-2.2).

There are three methods of sending tokens:

Expand Down Expand Up @@ -76,7 +76,30 @@ For example:
WWW-Authenticate: Bearer
```
## Usage
## Usage v2
It is necessary to register all valid `ISecurityTokenValidator` classes and configure the Authentication service using the `AddSimpleTokenAuthentication` extension method.
Example:
```csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISecurityTokenValidator, MyCustomTokenValidator>();
services.AddAuthentication()
.AddSimpleTokenAuthentication();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) {
app.UseAuthentication();
app.UseMvc();
}
}
```

## Usage v1

It is necessary to register all valid `ISecurityTokenValidator` classes and add the middleware to ApplicationBuilder using `UseSimpleTokenAuthentication`.

Expand Down
5 changes: 1 addition & 4 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
os: Visual Studio 2017

version: 1.1.3-alpha-{build}
version: 2.0.0-alpha-{build}

nuget:
project_feed: true

install:
- cmd: nuget sources add -Name makingsense-aspnet -Source https://ci.appveyor.com/nuget/makingsense-aspnet -UserName [email protected] -Password 4@pdw@BlfpQn

before_build:
- cmd: set DOTNET_ASSEMBLY_FILE_VERSION=%APPVEYOR_BUILD_NUMBER%
- cmd: set DOTNET_BUILD_VERSION=%APPVEYOR_BUILD_NUMBER%
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,26 @@
<PropertyGroup>
<Description>MakingSense.AspNetCore.Authentication.SimpleToken Class Library</Description>
<Authors>MakingSense</Authors>
<TargetFrameworks>net451;netcoreapp1.1</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>MakingSense.AspNetCore.Authentication.SimpleToken</AssemblyName>
<PackageId>MakingSense.AspNetCore.Authentication.SimpleToken</PackageId>
<PackageTags>ASP.NET 5;vnext;authentication;token;bearer</PackageTags>
<PackageProjectUrl>https://github.com/MakingSense/aspnet-authentication-simpletoken</PackageProjectUrl>
<PackageLicenseUrl>http://www.gnu.org/licenses/lgpl.html</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>git://github.com/MakingSense/aspnet-authentication-simpletoken</RepositoryUrl>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.1' ">1.1.1</RuntimeFrameworkVersion>
<VersionPrefix>1.1.3-alpha</VersionPrefix>
<VersionPrefix>2.0.0-alpha</VersionPrefix>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MakingSense.AspNetCore.Abstractions" Version="1.1.3-alpha-*" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="1.1.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
<PackageReference Include="MakingSense.AspNetCore.Abstractions" Version="2.0.0-alpha-173" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.0.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Linq" Version="4.3.0" />
<PackageReference Include="System.Threading" Version="4.3.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
<PackageReference Include="System.Collections" Version="4.3.0" />
<PackageReference Include="System.Runtime" Version="4.3.0" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>

</Project>
29 changes: 26 additions & 3 deletions src/MakingSense.AspNetCore.Authentication.SimpleToken/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# SimpleToken Authentication Middleware
# SimpleToken Authentication

This package allows to extract token from authenticated requests and delegate it to an appropriated ISecurityTokenValidator and generate and AuthenticationTicket.

## Behavior

### Token extraction details

This middleware tries to support almost [RFC 6750](http://tools.ietf.org/html/rfc6750) and some licenses based on [GitHub behavior](https://developer.github.com/v3/oauth/#use-the-access-token-to-access-the-api). But does not support Form-Encoded Body Parameter (http://tools.ietf.org/html/rfc6750#section-2.2).
This tries to support almost [RFC 6750](http://tools.ietf.org/html/rfc6750) and some licenses based on [GitHub behavior](https://developer.github.com/v3/oauth/#use-the-access-token-to-access-the-api). But does not support Form-Encoded Body Parameter (http://tools.ietf.org/html/rfc6750#section-2.2).

There are three methods of sending tokens:

Expand Down Expand Up @@ -76,7 +76,30 @@ For example:
WWW-Authenticate: Bearer
```
## Usage
## Usage v2
It is necessary to register all valid `ISecurityTokenValidator` classes and configure the Authentication service using the `AddSimpleTokenAuthentication` extension method.
Example:
```csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISecurityTokenValidator, MyCustomTokenValidator>();
services.AddAuthentication()
.AddSimpleTokenAuthentication();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) {
app.UseAuthentication();
app.UseMvc();
}
}
```

## Usage v1

It is necessary to register all valid `ISecurityTokenValidator` classes and add the middleware to ApplicationBuilder using `UseSimpleTokenAuthentication`.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
using System;
using System;
using MakingSense.AspNetCore.Authentication.SimpleToken;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Framework.Internal;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Builder
{
public static class SimpleTokenAppBuilderExtensions
{
[Obsolete("UseSimpleTokenAuthentication is obsolete. Configure SimpleTokenAuthentication authentication with AddAuthentication().AddSimpleTokenAuthentication in ConfigureServices. See https://go.microsoft.com/fwlink/?linkid=845470 for more details.", error: true)]
public static IApplicationBuilder UseSimpleTokenAuthentication(this IApplicationBuilder app)
{
if (app == null)
Expand All @@ -19,38 +16,10 @@ public static IApplicationBuilder UseSimpleTokenAuthentication(this IApplication
return UseSimpleTokenAuthentication(app, new SimpleTokenAuthenticationOptions());
}

[Obsolete("UseSimpleTokenAuthentication is obsolete. Configure SimpleTokenAuthentication authentication with AddAuthentication().AddSimpleTokenAuthentication in ConfigureServices. See https://go.microsoft.com/fwlink/?linkid=845470 for more details.", error: true)]
public static IApplicationBuilder UseSimpleTokenAuthentication(this IApplicationBuilder app, SimpleTokenAuthenticationOptions options)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}

if (options == null)
{
throw new ArgumentNullException(nameof(options));
}

if (string.IsNullOrEmpty(options.AuthenticationScheme))
{
options.AuthenticationScheme = "Bearer";
}

if (options.SecurityTokenValidatorsFactory == null)
{
// TODO: fix it because it is using app services, and it should use scope services,
// a work around could be:
// ```
// SecurityTokenValidatorsFactory = () =>
// {
// var context = app.ApplicationServices.GetService<IHttpContextAccessor>().HttpContext;
// return context.RequestServices.GetServices<ISecurityTokenValidator>();
// }
// ```
options.SecurityTokenValidatorsFactory = () => app.ApplicationServices.GetServices<ISecurityTokenValidator>();
}

return app.UseMiddleware<SimpleTokenAuthenticationMiddleware>(Options.Create(options));
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;

namespace MakingSense.AspNetCore.Authentication.SimpleToken
{
public static class SimpleTokenAuthenticationExtensions
{
public static AuthenticationBuilder AddSimpleTokenAuthentication(this AuthenticationBuilder builder)
=> builder.AddSimpleTokenAuthentication(SimpleTokenDefaults.AuthenticationScheme, null);

public static AuthenticationBuilder AddSimpleTokenAuthentication(this AuthenticationBuilder builder,
Action<SimpleTokenAuthenticationOptions> configureOptions)
=> builder.AddSimpleTokenAuthentication(SimpleTokenDefaults.AuthenticationScheme, configureOptions);

public static AuthenticationBuilder AddSimpleTokenAuthentication(this AuthenticationBuilder builder,
string authenticationScheme,
Action<SimpleTokenAuthenticationOptions> configureOptions)
=> builder.AddSimpleTokenAuthentication(authenticationScheme, SimpleTokenDefaults.DisplayName, configureOptions: configureOptions);

public static AuthenticationBuilder AddSimpleTokenAuthentication(this AuthenticationBuilder builder,
string authenticationScheme,
string displayName,
Action<SimpleTokenAuthenticationOptions> configureOptions)
{
return builder.AddScheme<SimpleTokenAuthenticationOptions, SimpleTokenAuthenticationHandler>(authenticationScheme, displayName,
(SimpleTokenAuthenticationOptions options) => {
configureOptions?.Invoke(options);

if (options.SecurityTokenValidatorsFactory == null)
{
options.SecurityTokenValidatorsFactory = () =>
{
// TODO: fix it because it is using app services, and it should use scope services,
// a work around could be:
// ```
// SecurityTokenValidatorsFactory = () =>
// {
// var context = builder.Services.BuildServiceProvider().GetService<IHttpContextAccessor>().HttpContext;
// return context.RequestServices.GetServices<ISecurityTokenValidator>();
// }
// ```
var serviceProvider = builder.Services.BuildServiceProvider();
return serviceProvider.GetServices<ISecurityTokenValidator>();
};
}
});
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
using System;
using System;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using MakingSense.AspNetCore.Authentication.Abstractions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Net.Http.Headers;

namespace MakingSense.AspNetCore.Authentication.SimpleToken
{
public class SimpleTokenAuthenticationHandler : AuthenticationHandler<SimpleTokenAuthenticationOptions>
{
public SimpleTokenAuthenticationHandler(
IOptionsMonitor<SimpleTokenAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock)
: base(options, logger, encoder, clock)
{
}

/// <summary>
/// Overrides the standard AuthenticationHandler to be more robust supporting [RFC 6750](http://tools.ietf.org/html/rfc6750) and
/// some licenses based on [GitHub behavior](https://developer.github.com/v3/oauth/#use-the-access-token-to-access-the-api).
Expand Down Expand Up @@ -53,7 +63,6 @@ public static string ExtractToken(HttpRequest request)
return pair.Substring(ix + 1).Trim();
}
}

// Not so nice, but AuthenticateResult.Fail does not allow us to show the error
throw new AuthenticationException("Authorization header exists but does not contains valid information.");
}
Expand All @@ -67,41 +76,44 @@ public static string ExtractToken(HttpRequest request)
return null;
}

static readonly Task DoneTask = Task.FromResult(0);

/// <summary>
/// Searches the 'Authorization' header for a 'Bearer' token. If the 'Bearer' token is found, it is validated using <see cref="TokenValidationParameters"/> set in the options.
/// </summary>
/// <returns></returns>
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
var token = ExtractToken(Request);

string token;
try
{
token = ExtractToken(Request);
}
catch (AuthenticationException ex)
{
return AuthenticateResult.Fail(ex.Message);
}
// If no token found, no further work possible
if (string.IsNullOrEmpty(token))
{
return AuthenticateResult.Skip();
return AuthenticateResult.NoResult();
}

var validationParameters = Options.TokenValidationParameters.Clone();

SecurityToken validatedToken;
var validators = Options.SecurityTokenValidatorsFactory();
foreach (var validator in validators)
{
if (validator.CanReadToken(token))
{
var principal = validator.ValidateToken(token, validationParameters, out validatedToken);
var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme);
var principal = validator.ValidateToken(token, validationParameters, out SecurityToken validatedToken);
var ticket = new AuthenticationTicket(principal, Scheme.Name);
return AuthenticateResult.Success(ticket);
}
}

// Ugly patch to make this method should to be async in order to allow result caching by caller
await DoneTask;
await Task.CompletedTask;

// Not so nice, but AuthenticateResult.Fail does not allow us to show the error
throw new AuthenticationException("Authorization token has been detected but it cannot be read.");
return AuthenticateResult.Fail("Authorization token has been detected but it cannot be read.");
}
}
}
Loading

0 comments on commit 1b06d9a

Please sign in to comment.