How to Login/Authenticate a User with ASP.NET MVC5 Rtm Bits Using Aspnet.Identity

How do you login/authenticate a user with Asp.Net MVC5 RTM bits using AspNet.Identity?

So here's what login will basically look like in RTM (code copied from the ASPNET Identity sample code):

    //
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}

// If we got this far, something failed, redisplay form
return View(model);
}

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

EDIT: And you need the follow changes in your Startup.Auth.cs:

        app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});

How do you create a user with Asp.Net RTM bits using AspNet.Identity?

Here's what the Register method looks like, its basically creating a user with a password:

    //
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model) {
if (ModelState.IsValid) {
var user = new ApplicationUser() { UserName = model.UserName };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded) {
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else {
AddErrors(result);
}
}

// If we got this far, something failed, redisplay form
return View(model);
}

MVC5 aspnet.identity + FLASH user authentication

So far i've found 3 possible(?) approaches. None of them seems easy and clear, and didn't tested them yet...

  1. Pass some validation/verification token to FLASH by flashvars, use it for each request to unrestricted server method and validate it manually.
  2. Call javascript functions from FLASH, used for restricted communication (i hope that such js calls will be automatically validated as normal web calls are?).
  3. Try to somehow read .AspNet.ApplicationCookie, ASP.NET_SessionID, __RequestVerificationToken cookies and use them in Flash when sending URLRequest. (don't know if it is even possible).

Do any of this makes any sense?

Are there really no easy/better sollution for validating user request made from flash app ;(?

EDIT:
Ad.2 Test Passed, User is authenticated :D. Seems quite nice actually (ExternalInterface.call(...)). Crucial FLASH-ASP.NET communication using JS and AJAX.

EDIT2:

Im just calling JavaScript from Flash, and this javaScript is then comunicating with server using AJAX that already is authenticated. Using external interface you can also call Flash functions from javaScript (when received answer). So communication is complete.

FLASH:

public static function SendToServer(_sParam:String):void
{
ExternalInterface.call("JAVASCRIPT_FUNCTIONNAME", "TEST", _sParam);
}

//If you want to call FLASH functions from JavaScript you need to call this in FLASH:

ExternalInterface.addCallback("NAME_FOR_JAVASCTIPT_OF_FLASH_FUNCTION", FLASH_FUNCTION);

//From now this FLASH_FUNCTION will be called when you call swfobj.NAME_FOR_JAVASCTIPT_OF_FLASH_FUNCTION() in JavaScript.

JAVASCRIPT:

//You need to be able to get SWF object in flash to call its registered functions
function swfobj() {
return $("#modafswf").get(0);
}

function JAVASCRIPT_FUNCTIONNAME(mffname, mfpvalue) {
try {
$.ajax({
url: "/FlashComm/" + mffname,
data: "{ 'param': '" + mfpvalue + "' }",
dataType: "text",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
swfobj().NAME_FOR_JAVASCTIPT_OF_FLASH_FUNCTION(mffname, data);
}
});
} catch (ex) {}
}

And finally ASP.NET:

[HttpPost]
public string TEST(string param)
{
string result = RESULT_ERROR;
result = RESULT_OK;
return result;
}

How to do programmatic sign in using aspnet Identity Framework v2?

Well, it seems that you are not using ASP.NET Identity. ASP.NET Identity is new membership system of asp.net, which automatically creates database tables for storing users, encrypting password, etc.

What you are trying to do is to use the new authentication system provided by OWIN, which replaces the old FormsAuthentication style.

To make it work, you have to create the cookie authentication. Like this:

public static class AuthConfig
{
public const string DefaultAuthType = "DefaultAppCookie";
public const string LoginPath = "/System/SignIn";

public static void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthType,
LoginPath = new PathString(LoginPath)
});

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier; //or whatever

}
}

In the login action:

var claims = new Claim[] {
new Claim(ClaimTypes.Name, "somename"),
new Claim(ClaimTypes.NameIdentifier, "someidentifier"),
new Claim("foo", "bar"),
};

ClaimsIdentity identity = new ClaimsIdentity(claims, AuthConfig.DefaultAuthType);
IAuthenticationManager authManager = Request.GetOwinContext().Authentication;

authManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);

I think that should be enough to make it work in your app. A few days ago I answered a similar question MVC Authentication - Easiest Way, take a look, it might be helpful.

How to do session management in aspnet identity?

Since you are using Asp.Net Identity, you want to store session related stuff as claims. This is very easy to extend with customised claims.

As an aside, I think you'd be better off simple extending ApplicationUser to hold the additional data, as detailed here.

That said, here is a complete example of how to add custom claim types to your application.

Step 1 - Define one or more custom claim types to hold your additional information

public static class CustomClaimTypes
{
public const string MasterFullName = "http://schemas.xmlsoap.org/ws/2014/03/mystuff/claims/masterfullname";
public const string MasterUserId = "http://schemas.xmlsoap.org/ws/2014/03/mystuff/claims/masteruserid";
}

A claim type is just a unique string that identifies the specific claim. Here we are just using a similar format as the built in claim types.

Step 2 - During the sign in process, set values for the custom claim types

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

//Fetch data from the UserMaster table
var userdata = GetdatafromUserMaster();

//Using the UserMaster data, set our custom claim types
identity.AddClaim(new Claim(CustomClaimTypes.MasterUserId, userdata.UserId));
identity.AddClaim(new Claim(CustomClaimTypes.MasterFullName, userdata.FullName));

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

Note: we are using custom claim types so that we preserve the existing NameIdentifier and Name claims, and can therefore easily access identity information from both Asp.Net Identity and our custom UserMaster table.

Step 3 - Add extension method(s) to IIdentity so we can easily access our custom claim data

public static class IdentityExtensions
{
public static string GetMasterUserId(this IIdentity identity)
{
if (identity == null)
return null;

return (identity as ClaimsIdentity).FirstOrNull(CustomClaimTypes.MasterUserId);
}

public static string GetMasterFullName(this IIdentity identity)
{
if (identity == null)
return null;

return (identity as ClaimsIdentity).FirstOrNull(CustomClaimTypes.MasterFullName);
}

internal static string FirstOrNull(this ClaimsIdentity identity, string claimType)
{
var val = identity.FindFirst(claimType);

return val == null ? null : val.Value;
}
}

Nothing fancy here. We just cast the IIdentity as a ClaimsIdentity and then return the value of either the first claim of the given CustomClaimType that we find, or we return null if a claim doesn't exist.

Step 4 - Now we can access our custom claim data in views and/or controllers really easily. Say you wanted to use the full name from your UserMaster table instead of the ApplicationUser? You can now do this:

<ul class="nav navbar-nav navbar-right">
<li>
@Html.ActionLink("Hello " + User.Identity.GetMasterFullName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>
<li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>

You can also do the same thing from within a Controller.

How can I detect when a user logs in with Microsoft.AspNet.Identity

There are some hook-s for this in the MVC's architecture. Implement one of these in Global.asax:

  • protected void Application_AuthenticateRequest() { }
  • protected void Application_PostAuthenticateRequest() { }
  • protected void Application_AuthorizeRequest() { }

How do you set the current user in an ASP.NET MVC 5 application using ASP.NET Identity?

First of all, did you miss .Current in your code sample?

It should be

HttpContext.Current.GetOwinContext()
.Authentication
.SignIn(...);

Secondly, I'm assuming you've setup cookie authentication in your app?

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
...
});

Here setting the authentication type is important! And when you generate the claims identity and before you pass it into the .SignIn() method, the claims identity needs to have the same authentication type so that they can talk!

I would use .CreateIdentityAsync() method from the UserManager class to create the identity instead, because you can pass the authentication type in as one of the parameters:

// Create an application user from your claim identity?
var appUser = new AppUser { ... };

// And pass the user into manager to create the identity with the same authentication
// type you used when you setup the cookie authentication
var claimsIdentity = _userManager.CreateIdentityAsync(appUser,
CookieAuthenticationDefaults.AuthenticationType);

I am using this way to impersonate users for admins that have developer role so that we can test the app.



Related Topics



Leave a reply



Submit