Use Nancy FormsAuthentication, formsauthentication
1. Create a UserDatabase class and implement the IUserMapper Interface
Using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Security. Claims;
Using System. Security. Principal;
Using Nancy. Authentication. Forms;
Public class UserDatabase: IUserMapper
{
Private static List <Tuple <string, string, Guid> users = new List <Tuple <string, string, Guid> ();
Static UserDatabase ()
{
Users. Add (new Tuple <string, string, Guid> ("admin", "password", new Guid ("55E1E49E-B7E8-4EEA-8459-7A906AC4D4C0 ")));
Users. Add (new Tuple <string, string, Guid> ("user", "password", new Guid ("56E1E49E-B7E8-4EEA-8459-7A906AC4D4C0 ")));
}
Public ClaimsPrincipal GetUserFromIdentifier (Guid identifier, NancyContext context)
{
Var userRecord = users. FirstOrDefault (u => u. Item3 = identifier );
Return userRecord = null
? Null
: New ClaimsPrincipal (new ClaimsIdentity (BuildClaims (userRecord. Item1), "querystring "));
}
Public static Guid? ValidateUser (string username, string password)
{
Var userRecord = users. FirstOrDefault (u => u. Item1 = username & u. Item2 = password );
If (userRecord = null)
{
Return null;
}
Return userRecord. Item3;
}
/// <Summary>
/// Build claims based on username
/// </Summary>
/// <Param name = "userName"> Current username </param>
/// <Returns> IEnumerable of claims </returns>
Private static IEnumerable <Claim> BuildClaims (string userName)
{
Var claims = new List <Claim> ();
Claims. Add (new Claim (ClaimTypes. Role, userName ));
Return claims;
}
}
2. Create a FormsAuthBootstrapper startup class.
Using Nancy. Authentication. Forms;
Using Nancy. Bootstrapper;
Using Nancy. TinyIoc;
Public class FormsAuthBootstrapper: DefaultNancyBootstrapper
{
Protected override void ConfigureApplicationContainer (TinyIoCContainer container)
{
// We don't call "base" here to prevent auto-discovery
// Types/dependencies
}
Protected override void assumerequestcontainer (TinyIoCContainer container, NancyContext context)
{
Base. assumerequestcontainer (container, context );
// Here we register our user mapper as a per-request singleton.
// As this is now per-request we cocould inject a request scoped
// Database "context" or other request scoped services.
Container. Register <IUserMapper, UserDatabase> ();
}
Protected override void RequestStartup (TinyIoCContainer requestContainer, IPipelines pipelines, NancyContext context)
{
// At request startup we modify the request pipelines
// Include forms authentication-passing in our now request
// Scoped user name mapper.
//
// The pipelines passed in here are specific to this request,
// So we can add/remove/update items in them as we please.
Var formsAuthConfiguration =
New FormsAuthenticationConfiguration ()
{
RedirectUrl = "~ /Login ",
UserMapper = requestContainer. Resolve <IUserMapper> (),
};
FormsAuthentication. Enable (pipelines, formsAuthConfiguration );
}
}
3. logon method implementation
Post ["/login"] = x => {
Var userGuid = UserDatabase. ValidateUser (string) this. Request. Form. Username, (string) this. Request. Form. Password );
If (userGuid = null)
{
Return this. Context. GetRedirect ("~ /Login? Error = true & username = "+ (string) this. Request. Form. Username );
}
DateTime? Expiry = null;
If (this. Request. Form. RememberMe. HasValue)
{
Expiry = DateTime. Now. AddDays (7 );
}
Return this. LoginAndRedirect (userGuid. Value, expiry );
};
4. Authorization required
Get ["/secured"] = x => {
This. RequiresAuthentication (); // You must log on to the instance to access the instance. Otherwise, the bootstrap configuration address is returned.
This. RequiresClaims (c => c. Type = ClaimTypes. Role & c. Value = "admin"); // declare the admin Role for access; otherwise, 403
// This. requiresAnyClaim (h => h. value = "admin" | h. value = "User"); // the user with the declarative Value admin or User can be accessed; otherwise, 403
Var model = new UserModel (this. Context. CurrentUser. Identity. Name );
Return View ["secure. cshtml", model];
};