How to handle anonymous user in mvc application? - c#

I am creating an Asp.NET MVC-4 application. In my application user can post their products. I want that whether user logged in or not [Anonymous] , he could post there products. For this i can use SessionId, but i am worry about if session expires that how can i detect the anonymous user.
I want to know about Migrating the Anonymous profile to logged in Userprofile. Please suggest me some good tutorials or resources or logic by which i can implement this.

http://msdn.microsoft.com/en-us/library/ewfkf772(v=vs.100).aspx has it all.
Use this to migrate rhe profiles in Global.asax
public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)
{
ProfileCommon anonymousProfile = Profile.GetProfile(args.AnonymousID);
Profile.ZipCode = anonymousProfile.ZipCode;
Profile.CityAndState = anonymousProfile.CityAndState;
Profile.StockSymbols = anonymousProfile.StockSymbols;
////////
// Delete the anonymous profile. If the anonymous ID is not
// needed in the rest of the site, remove the anonymous cookie.
ProfileManager.DeleteProfile(args.AnonymousID);
AnonymousIdentificationModule.ClearAnonymousIdentifier();
// Delete the user row that was created for the anonymous user.
Membership.DeleteUser(args.AnonymousID, true);
}

Related

Prompt user for additional information during an Open Id Connect event?

Using asp.net Core, Mvc and OpenIdConnect, is it possible to prompt an authenticated user for additional information during the ODIC authentication process, and then redirect back to the originally-desired page?
To give a concrete example: in our system one person, represented by an email address, can have multiple user ids that they may wish to operate under. Assume my email address is tregan#domain.com, and I have 3 user ids to choose from: treganCat, treganDog, treganMouse. When I hit a Controller action that is decorated with the [Authorize] attribute I first go through OpenIdConnect authentication, and one of the claims returned is an email address.
Using that email address, I want the application to prompt me to select the identity that I want to run under (treganDog, treganCat, or treganMouse).
From there, I want the application to take the user id that I selected, interrogate a database for the roles that go along with the selected user id, and load those roles as claims to my identity.
Finally, I want the application to send me on to my desired page (which is the protected Controller method that I originally attempted to visit).
Is this possible?
I'm using an Owin Startup class; the code below "works" except for the fictional line "var identityGuid = [return value from the prompt];" ("fictional" because it represents what I would like to occur, but in fact a series of redirects would be needed).
My example below uses the OnTicketReceived event, but that selection is arbitrary, I would be willing to do this in any event.
services.AddAuthentication(authenticationOptions =>
{
authenticationOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authenticationOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(openIdConnectOptions =>
{
openIdConnectOptions.Authority = Configuration["PingOne:Authority"];
openIdConnectOptions.CallbackPath = "/Callback";
openIdConnectOptions.ClientId = Configuration["PingOne:ClientId"];
openIdConnectOptions.ClientSecret = Configuration["PingOne:ClientSecret"];
openIdConnectOptions.ResponseType = "code";
openIdConnectOptions.Events.OnTicketReceived = (ticketReceivedContext) =>
{
var emailClaim =
ticketReceivedContext.Principal.Claims.FirstOrDefault(o =>
o.Type == ClaimTypes.Email);
string emailAddress = emailClaim.Value;
//here is where I would like to prompt the user to select an identity based on the email address
//the selected identity is represented by a guid
var identityGuid = [return value from the prompt];
var roles = new MyRepository(myContext).GetRolesForUserId(identityGuid);
var claims = new List<Claim>();
foreach (string role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
ticketReceivedContext.Principal.AddIdentity(new ClaimsIdentity(claims));
return Task.CompletedTask;
};
});
This is impersonation where there is a real user and you need to identify the impersonated user after login.
You will need to complete the login first, return to the app and configure the principal. Then render a UI and receive the selected choice.
You then need your UI to call the back end and tell it to update claims in the auth cookie. Not sure if you'll get this to work though - the impersonated user may need separate storage - such as a second cookie.
This highlights that it can be useful to separate the token / credential the UI receives from the claims the back end works with.
I use the below design a lot for REST APIs that serve UIs directly - though it may be overkill for your solution:
https://authguidance.com/2017/10/03/api-tokens-claims/
I think what I want to do is simply not possible without either figuring out a way to do it inside PingOne or writing my own IdentityServer and taking care of the extra steps there.
I decided to instead write a custom middleware that fires after the Authentication middleware, as described in this SO question: In asp.net core, why is await context.ChallengeAsync() not working as expected?

Create User Roles In Asp.net Web Application project

I need guidance from all of you experts for a simple task.
i'm working on my final year project which is a web based application.
In this application i have to create several users which will do different taks for example accountant will manage fee and admin will manage teacher and student accounts and so on.
i'm working hard on this and I've learned simple authentication.
I'm able to authorize users based on their user names and allow them to access specific pages or specific folder having multiple pages.
I'm doing this by using form authentication.
but
now as i want to create user role and assign different roles to different users so that I don't have to add each and every user name in web config file.
please suggest me the easiest way to do this. is there any book, or article or youtube video from where i can learn it ?
I've searched stack overflow and msdn but i'm unable to understand.
I'm waiting for your suggestions,
thanks in advance.
I'm nor working in MVC.
I'm using .net 4.5, visual studio 2012 and sql server 2014
You can attach roles to your user in this way:
in globl.asax add the following event, read the roles to assign to the logged user, create a new GenericPincipal and assign it to the user.
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
var app = (HttpApplication) sender;
var ctx = app.Context;
if (ctx.User != null)
{
//Read the roles from database for current user, create a new Principal, attach the principal to the user (im using EF)
using (var context = new BackendDbContext())
{
var user = context.Set<User>().Find(Convert.ToInt32(ctx.User.Identity.Name));
var identity = new GenericIdentity(user.UserId.ToString());
var principal = new GenericPrincipal(
identity,
new[] {user.UserRoleId.ToString()});
ctx.User = principal;
}
}
}

ASP.Net MVC Preventing direct access to action out of RedirectToAction method

My site aims to upload files to sharepoint folders. Users are coming from another system by using a button referencing my site and contains userId and other parameters. When a call comes to my site shown below
http://myapplication/Upload/ToFolder?entityName=new_policy&entityGuid=4451E282-80B0-E611-80E8-C4346BACFC18&systemUserId=1ADEC6E1-008C-430D-A163-D7BA7AD75689
I authenticate user with userId and redirect user to http://myapplication/Policy using RedirectToAction method and setting some parameters to static properties. Because of static properties I use my params but I dont want to do this way. I want to detect that when users types directly http://myapplication/Policy link and throw an error like "You should come from this site only via link on other system."
How can I detect this behaviour of users ?
You could set a tempdata value in the first action...
TempData["isRedirect"] = true;
which gets read by the second action
if(TempData["isRedirect"] == null)
{
//Deny access
}
//Set temp data again so that user can refresh
TempData["isRedirect"] = true;

Generating an Identity User with Roles (From Web API to MVC Application)

Currently developing a couple of applications (MVC and Web API) where my MVC application will send the request to the API to get authenticated and "login". I've got it working so that all my MVC application has to do is store the bearer token from the Web API and attach it anytime it needs to make a request for data.
At this point in the program we are looking to start working with Authorization and some security trimming to limit which users can make certain requests to the API and which users are able to see certain pages on the MVC application. In order to do this on both ends I need to get the Roles from my API and impersonate the Identity user on the MVC side since they are technically already logged in. My problem right now is probably kind of simple, but I can't figure out how to declare the Roles when I generate an identity user. Right now I just need a test case that we can explicitly declare and then I can grab it later once we start passing Roles from the API.
Any idea how to make a functioning example out of this with Roles?
private IdentityUser GenerateIdentityUser(string IdNum, string userN)
{
var newUser = new IdentityUser
{
Id = IdNum,
UserName = userN,
// Roles =
SecurityStamp = DateTime.Now.Ticks.ToString()
};
return newUser;
}
The Roles property in the IdentityUser has a private setter (see codeplex source code). The constructor for IdentityUser always creates an empty list of roles, so that it won't be null.
To set a role you'll need to add the following line after initializing your newUser object:
newUser.Roles.Add(new IdentityUserRole {UserId = newUser.Id, RoleId = "your role id"});

MVC 5 - Roles - IsUserInRole and Adding user to role

In MVC4 i used Roles.IsUserInRole to check if a given user is in some role. However, with MVC5 i can't do it anymore...
At first, it asked me to enable RoleManager at the web.config but then i discovered that microsoft moved away from Web.Security to Microsoft.AspNet.Identity.
My question now is, with Microsoft.AspNet.Identity how do i do an action similar to Roles.IsUserInRole?
And/or create a relation between the Role and the User.
By the way, i'm still trying to understand the new authentication methods (ClaimsIdentity?).
You should read http://typecastexception.com/post/2014/04/20/ASPNET-MVC-and-Identity-20-Understanding-the-Basics.aspx for the basics of Identity 2.0!
There's also a complete demo project to get you started:
https://github.com/TypecastException/AspNet-Identity-2-With-Integer-Keys
If you take this as the basis for your Identity foundation you'll end up with something like this:
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
const string name = "YourUsername"
const string roleName = "Admin";
var user = userManager.FindByName(name);
//check for user roles
var rolesForUser = userManager.GetRoles(user.Id);
//if user is not in role, add him to it
if (!rolesForUser.Contains(role.Name))
{
userManager.AddToRole(user.Id, role.Name);
}
The post above was really helpful (Thanks Serv, would vote up if my reputation allowed me to). It helped me solve an issue I was having with a few minor changes to fit what I was trying to achieve. My particular problem was that I wanted to check in an MVC view if the current user was in a given role group. I also found that Roles.IsUserInRole was no longer working.
If you are doing this in a view, but using ASP.NET identity 2.0 instead of the simple membership provider offered by previous MVC versions, the following might be helpful as a 1-line solution:
bool isAdmin = HttpContext.Current.User.IsInRole("Admin");
You may then combine it with HTML to selectively show menu items (which is what I've been using it for) with something like this:
#if (isAdmin)
{
<li>#Html.ActionLink("Users", "List", "Account")</li>
}
This allows me to prevent access to the user management hyperlinks where the user is not a member of the 'Admin' role.

Categories