Skip to content
This repository has been archived by the owner on Jan 24, 2021. It is now read-only.

Replacing current "user" objects with ClaimsPrincipal/ClaimsIdentity #1820

Merged
merged 24 commits into from
Mar 20, 2015
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
dc3a9ff
Deleting IUserIdentity. This breaks all the things.
damianh Feb 19, 2015
8be6af0
Rename UserIdentityExtensions to ClaimsPrincipalExtension. Mapped IUs…
damianh Feb 19, 2015
ca5447a
ModuleSecurity and SecurityHooks fixed to use ClaimsPrincipal extensi…
damianh Feb 19, 2015
f7513e7
Basic Auth IUserValidator returns a ClaimsPrincipal.
damianh Feb 19, 2015
3f3639c
Froms Auth IUserMapper returns a ClaimsPrincipal
damianh Feb 19, 2015
9cafef2
Authentication.Stateless user lookup func returns a ClaimsPrincipal
damianh Feb 19, 2015
942f4fa
Fix, changes (and some deletions) to ModuleSecurity, SecurityHooks an…
damianh Feb 19, 2015
c99698b
Replace IUserIdentity with ClaimsPrincipal.
damianh Feb 19, 2015
eaf2412
Unused using
damianh Feb 19, 2015
688bfdf
Nancy.Tests.Function fixed to use ClaimsPrincipal.
damianh Feb 19, 2015
9f628ff
Removing RequiresValidatedClaims - doesn't make sense give we're usin…
damianh Feb 19, 2015
e75f8ee
Nancy.Demo.Authentication.Basic fixed to use ClaimsPrincipal
damianh Feb 19, 2015
462f8c1
Nancy.Demo.Authentication fixed to use ClaimsPrincipal
damianh Feb 19, 2015
54faddd
Fix Nancy.Damo.Authentication.Forms to support ClaimsPrincipal
damianh Feb 19, 2015
f9cf3f5
Nancy.Demo.Authentication.Stateless fixed to use ClaimsPrincipal.
damianh Feb 19, 2015
f4be219
Delete tests /requiresvalidatedclaims isn't a thing.
damianh Feb 19, 2015
4950480
Removing Nancy.Authentication.Token and all related projects. Token (…
damianh Mar 11, 2015
99b7989
Perhaps TargetFrameworkVersion should be 4.5?
damianh Mar 12, 2015
4160b7d
Because Nancy middleware is in own project, move middlware tests to N…
damianh Mar 12, 2015
9e5c6e9
Remove commented out code
damianh Mar 12, 2015
7e3bb35
Katana user and owin user flow through.
damianh Mar 12, 2015
e8ae7c4
Do NOT use static service location in NancyMiddleware. The will cause…
damianh Mar 12, 2015
0135cdd
Do NOT use static service location in NancyMiddleware. The will cause…
damianh Mar 20, 2015
1ebb69f
Fix test - explicitly set the NancyBootstrapperLocator.Bootstrapper
damianh Mar 20, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
{
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text;
using System.Threading;

using FakeItEasy;

using Nancy.Bootstrapper;
using Nancy.Security;
using Nancy.Tests;
using Nancy.Tests.Fakes;

Expand Down Expand Up @@ -252,7 +252,7 @@ public void Should_set_user_in_context_with_valid_username_in_auth_header()
var fakePipelines = new Pipelines();

var validator = A.Fake<IUserValidator>();
var fakeUser = A.Fake<IUserIdentity>();
var fakeUser = A.Fake<ClaimsPrincipal>();
A.CallTo(() => validator.Validate("foo", "bar")).Returns(fakeUser);

var cfg = new BasicAuthenticationConfiguration(validator, "realm");
Expand Down
28 changes: 14 additions & 14 deletions src/Nancy.Authentication.Basic/IUserValidator.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
namespace Nancy.Authentication.Basic
{
using Nancy.Security;
using System.Security.Claims;

/// <summary>
/// Provides a way to validate the username and password
/// </summary>
public interface IUserValidator
{
/// <summary>
/// Validates the username and password
/// </summary>
/// <param name="username">Username</param>
/// <param name="password">Password</param>
/// <returns>A value representing the authenticated user, null if the user was not authenticated.</returns>
IUserIdentity Validate(string username, string password);
}
}
/// Provides a way to validate the username and password
/// </summary>
public interface IUserValidator
{
/// <summary>
/// Validates the username and password
/// </summary>
/// <param name="username">Username</param>
/// <param name="password">Password</param>
/// <returns>A value representing the authenticated user, null if the user was not authenticated.</returns>
ClaimsPrincipal Validate(string username, string password);
}
}
13 changes: 0 additions & 13 deletions src/Nancy.Authentication.Forms.Tests/Fakes/FakeUserIdentity.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ namespace Nancy.Authentication.Forms.Tests
{
using System;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading;

using FakeItEasy;

using Nancy.Authentication.Forms.Tests.Fakes;
using Nancy.Bootstrapper;
using Nancy.Cryptography;
using Nancy.Helpers;
Expand Down Expand Up @@ -379,7 +380,7 @@ public void Should_have_expired_empty_authentication_cookie_in_logout_response_w
var result = FormsAuthentication.LogOutResponse();

// Then
var cookie = result.Cookies.Where(c => c.Name == FormsAuthentication.FormsAuthenticationCookieName).First();
var cookie = result.Cookies.First(c => c.Name == FormsAuthentication.FormsAuthenticationCookieName);
cookie.Value.ShouldBeEmpty();
cookie.Expires.ShouldNotBeNull();
(cookie.Expires < DateTime.Now).ShouldBeTrue();
Expand All @@ -405,7 +406,7 @@ public void Should_set_user_in_context_with_valid_cookie()
{
var fakePipelines = new Pipelines();
var fakeMapper = A.Fake<IUserMapper>();
var fakeUser = new FakeUserIdentity {UserName = "Bob"};
var fakeUser = new ClaimsPrincipal(new GenericIdentity("Bob"));
A.CallTo(() => fakeMapper.GetUserFromIdentifier(this.userGuid, this.context)).Returns(fakeUser);
this.config.UserMapper = fakeMapper;
FormsAuthentication.Enable(fakePipelines, this.config);
Expand All @@ -421,7 +422,7 @@ public void Should_not_set_user_in_context_with_empty_cookie()
{
var fakePipelines = new Pipelines();
var fakeMapper = A.Fake<IUserMapper>();
var fakeUser = new FakeUserIdentity {UserName = "Bob"};
var fakeUser = new ClaimsPrincipal(new GenericIdentity("Bob"));
A.CallTo(() => fakeMapper.GetUserFromIdentifier(this.userGuid, this.context)).Returns(fakeUser);
this.config.UserMapper = fakeMapper;
FormsAuthentication.Enable(fakePipelines, this.config);
Expand All @@ -437,7 +438,7 @@ public void Should_not_set_user_in_context_with_invalid_hmac()
{
var fakePipelines = new Pipelines();
var fakeMapper = A.Fake<IUserMapper>();
var fakeUser = new FakeUserIdentity { UserName = "Bob" };
var fakeUser = new ClaimsPrincipal(new GenericIdentity("Bob"));
A.CallTo(() => fakeMapper.GetUserFromIdentifier(this.userGuid, this.context)).Returns(fakeUser);
this.config.UserMapper = fakeMapper;
FormsAuthentication.Enable(fakePipelines, this.config);
Expand All @@ -453,7 +454,7 @@ public void Should_not_set_user_in_context_with_empty_hmac()
{
var fakePipelines = new Pipelines();
var fakeMapper = A.Fake<IUserMapper>();
var fakeUser = new FakeUserIdentity { UserName = "Bob" };
var fakeUser = new ClaimsPrincipal(new GenericIdentity("Bob"));
A.CallTo(() => fakeMapper.GetUserFromIdentifier(this.userGuid, this.context)).Returns(fakeUser);
this.config.UserMapper = fakeMapper;
FormsAuthentication.Enable(fakePipelines, this.config);
Expand All @@ -469,7 +470,7 @@ public void Should_not_set_user_in_context_with_no_hmac()
{
var fakePipelines = new Pipelines();
var fakeMapper = A.Fake<IUserMapper>();
var fakeUser = new FakeUserIdentity { UserName = "Bob" };
var fakeUser = new ClaimsPrincipal(new GenericIdentity("Bob"));
A.CallTo(() => fakeMapper.GetUserFromIdentifier(this.userGuid, this.context)).Returns(fakeUser);
this.config.UserMapper = fakeMapper;
FormsAuthentication.Enable(fakePipelines, this.config);
Expand All @@ -485,7 +486,7 @@ public void Should_not_set_username_in_context_with_broken_encryption_data()
{
var fakePipelines = new Pipelines();
var fakeMapper = A.Fake<IUserMapper>();
var fakeUser = new FakeUserIdentity { UserName = "Bob" };
var fakeUser = new ClaimsPrincipal(new GenericIdentity("Bob"));
A.CallTo(() => fakeMapper.GetUserFromIdentifier(this.userGuid, this.context)).Returns(fakeUser);
this.config.UserMapper = fakeMapper;
FormsAuthentication.Enable(fakePipelines, this.config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@
<Compile Include="..\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Fakes\FakeUserIdentity.cs" />
<Compile Include="FormsAuthenticationConfigurationFixture.cs" />
<Compile Include="FormsAuthenticationFixture.cs" />
</ItemGroup>
Expand Down
5 changes: 2 additions & 3 deletions src/Nancy.Authentication.Forms/IUserMapper.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
namespace Nancy.Authentication.Forms
{
using System;

using Nancy.Security;
using System.Security.Claims;

/// <summary>
/// Provides a mapping between forms auth guid identifiers and
Expand All @@ -16,6 +15,6 @@ public interface IUserMapper
/// <param name="identifier">User identifier</param>
/// <param name="context">The current NancyFx context</param>
/// <returns>Matching populated IUserIdentity object, or empty</returns>
IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context);
ClaimsPrincipal GetUserFromIdentifier(Guid identifier, NancyContext context);
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
namespace Nancy.Authentication.Stateless
{
using System;

using Nancy.Security;
using System.Security.Claims;

/// <summary>
/// Configuration options for stateless authentication
/// </summary>
public class StatelessAuthenticationConfiguration
{
internal Func<NancyContext, IUserIdentity> GetUserIdentity;
internal readonly Func<NancyContext, ClaimsPrincipal> GetUserIdentity;

/// <summary>
/// Initializes a new instance of the <see cref="StatelessAuthenticationConfiguration"/> class.
/// </summary>
public StatelessAuthenticationConfiguration(Func<NancyContext, IUserIdentity> getUserIdentity)
public StatelessAuthenticationConfiguration(Func<NancyContext, ClaimsPrincipal> getUserIdentity)
{
GetUserIdentity = getUserIdentity;
this.GetUserIdentity = getUserIdentity;
}

/// <summary>
Expand Down
13 changes: 0 additions & 13 deletions src/Nancy.Demo.Authentication.Basic/DemoUserIdentity.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AuthenticationBootstrapper.cs" />
<Compile Include="DemoUserIdentity.cs" />
<Compile Include="MainModule.cs" />
<Compile Include="SecureModule.cs" />
<Compile Include="UserValidator.cs" />
Expand Down
5 changes: 1 addition & 4 deletions src/Nancy.Demo.Authentication.Basic/SecureModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ public SecureModule() : base("/secure")
{
this.RequiresAuthentication();

Get["/"] = x =>
{
return "Hello " + this.Context.CurrentUser.UserName;
};
Get["/"] = x => "Hello " + this.Context.CurrentUser.Identity.Name;
}
}
}
8 changes: 5 additions & 3 deletions src/Nancy.Demo.Authentication.Basic/UserValidator.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
namespace Nancy.Demo.Authentication.Basic
{
using System.Security.Claims;
using System.Security.Principal;

using Nancy.Authentication.Basic;
using Nancy.Security;

public class UserValidator : IUserValidator
{
public IUserIdentity Validate(string username, string password)
public ClaimsPrincipal Validate(string username, string password)
{
if (username == "demo" && password == "demo")
{
return new DemoUserIdentity { UserName = username };
return new ClaimsPrincipal(new GenericIdentity(username));
}

// Not recognised => anonymous.
Expand Down
13 changes: 0 additions & 13 deletions src/Nancy.Demo.Authentication.Forms/DemoUserIdentity.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="SecureModule.cs" />
<Compile Include="DemoUserIdentity.cs" />
<Compile Include="FormsAuthBootstrapper.cs" />
<Compile Include="MainModule.cs" />
<Compile Include="Models\UserModel.cs" />
Expand Down
2 changes: 1 addition & 1 deletion src/Nancy.Demo.Authentication.Forms/PartlySecureModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public PartlySecureModule()
Get["/secured"] = x => {
this.RequiresAuthentication();

var model = new UserModel(this.Context.CurrentUser.UserName);
var model = new UserModel(this.Context.CurrentUser.Identity.Name);
return View["secure.cshtml", model];
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/Nancy.Demo.Authentication.Forms/SecureModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public SecureModule() : base("/secure")
this.RequiresAuthentication();

Get["/"] = x => {
var model = new UserModel(this.Context.CurrentUser.UserName);
var model = new UserModel(this.Context.CurrentUser.Identity.Name);
return View["secure.cshtml", model];
};
}
Expand Down
11 changes: 6 additions & 5 deletions src/Nancy.Demo.Authentication.Forms/UserDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ namespace Nancy.Demo.Authentication.Forms
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;

using Nancy.Authentication.Forms;
using Nancy.Security;

public class UserDatabase : IUserMapper
{
Expand All @@ -17,18 +18,18 @@ static UserDatabase()
users.Add(new Tuple<string, string, Guid>("user", "password", new Guid("56E1E49E-B7E8-4EEA-8459-7A906AC4D4C0")));
}

public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)
public ClaimsPrincipal GetUserFromIdentifier(Guid identifier, NancyContext context)
{
var userRecord = users.Where(u => u.Item3 == identifier).FirstOrDefault();
var userRecord = users.FirstOrDefault(u => u.Item3 == identifier);

return userRecord == null
? null
: new DemoUserIdentity {UserName = userRecord.Item1};
: new ClaimsPrincipal(new GenericIdentity(userRecord.Item1));
}

public static Guid? ValidateUser(string username, string password)
{
var userRecord = users.Where(u => u.Item1 == username && u.Item2 == password).FirstOrDefault();
var userRecord = users.FirstOrDefault(u => u.Item1 == username && u.Item2 == password);

if (userRecord == null)
{
Expand Down
13 changes: 0 additions & 13 deletions src/Nancy.Demo.Authentication.Stateless/DemoUserIdentity.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AuthModule.cs" />
<Compile Include="DemoUserIdentity.cs" />
<Compile Include="Models\UserModel.cs" />
<Compile Include="RootModule.cs" />
<Compile Include="SecureModule.cs" />
Expand Down
8 changes: 6 additions & 2 deletions src/Nancy.Demo.Authentication.Stateless/RootModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ public class RootModule : NancyModule
{
public RootModule()
{
Get["/"] = _ => this.Response.AsText("This is a REST API. It is in another VS project to demonstrate how a common REST API might behave when accessing it from another website or application. To see how a website can access this API, run the Nancy.Demo.Authentication.Stateless.Website project (in the same Nancy solution).");
Get["/"] = _ => this.Response.AsText("This is a REST API. It is in another VS project to " +
"demonstrate how a common REST API might behave when " +
"accessing it from another website or application. To " +
"see how a website can access this API, run the " +
"Nancy.Demo.Authentication.Stateless.Website project " +
"(in the same Nancy solution).");
}

}
}
4 changes: 2 additions & 2 deletions src/Nancy.Demo.Authentication.Stateless/SecureModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public SecureModule()
Get["secure"] = x =>
{
//Context.CurrentUser was set by StatelessAuthentication earlier in the pipeline
var identity = (DemoUserIdentity)this.Context.CurrentUser;
var identity = this.Context.CurrentUser;

//return the secure information in a json response
var userModel = new UserModel(identity.UserName);
var userModel = new UserModel(identity.Identity.Name);
return this.Response.AsJson(new
{
SecureContent = "here's some secure content that you can only see if you provide a correct apiKey",
Expand Down
Loading