why HttpContext.Current.User Could not be initialized is reurn null - asp.net-mvc

I'm using this code for Authentication mvc .I am login but Context.User is null when trace project show current.user null.
I think Context.User Could not be initialized
how sloved this problem
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Context.User == null)
return;
var userService = ObjectFactory.GetInstance<IUserService>();
var userStatus = userService.GetStatus(Context.User.Identity.Name);
if (userStatus.IsBaned)
FormsAuthentication.SignOut();
var authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
return;
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// retrieve roles from UserData
if (authTicket == null) return;
var roles = authTicket.UserData.Split(',');
if (userStatus.Role != roles[0])
FormsAuthentication.SignOut();
Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
private void SetAuthCookie(string userName, string roleofUser, bool presistantCookie)
{
var timeout = presistantCookie ? FormsAuthentication.Timeout.TotalMinutes : 30;
var now = DateTime.UtcNow.ToLocalTime();
var expirationTimeSapne = TimeSpan.FromMinutes(timeout);
var authTicket = new FormsAuthenticationTicket(
1,
userName,
now,
now.Add(expirationTimeSapne),
presistantCookie,
roleofUser,
FormsAuthentication.FormsCookiePath
);
var encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL,
Path = FormsAuthentication.FormsCookiePath
};
if (FormsAuthentication.CookieDomain != null)
{
authCookie.Domain = FormsAuthentication.CookieDomain;
}
if (presistantCookie)
authCookie.Expires = DateTime.Now.AddMinutes(timeout);
Response.Cookies.Add(authCookie);
}

Related

HttpContext.Session.GetInt32() returns null

I have a simple Login form, where I set user Session data and redirect to Home page. This worked well before, but now in HomeController/Index, sessionID returns null and I'm not sure what caused this. It finds, that user is Authenticated, but doesn't get its ID.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel user)
{
if (ModelState.IsValid)
{
user.Password = Encryption.Encrypt(user.Password);
var checkLogin = _context.Users.FirstOrDefault(x => x.UserName.Equals(user.UserName) && x.Password.Equals(user.Password));
if (checkLogin != null)
{
HttpContext.Session.SetInt32("ID", checkLogin.ID);
HttpContext.Session.SetString("Name", checkLogin.Name);
HttpContext.Session.SetString("Surname", checkLogin.Surname);
HttpContext.Session.SetString("Role", checkLogin.Role.ToString());
var claims = new Claim[]
{
new Claim(ClaimTypes.Name, checkLogin.Name),
new Claim(ClaimTypes.Role, checkLogin.Role.ToString())
};
var identity = new ClaimsIdentity(claims, "AuthenticationCookie");
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity);
//var authProperties = new AuthenticationProperties()
//{
// IsPersistent = true
//};
await HttpContext.SignInAsync("AuthenticationCookie", claimsPrincipal);
return RedirectToAction("Index", "Home");
}
else
{
ViewBag.Notification = " Wrong Username or Password";
}
}
return View();
}
Home:
[HttpGet]
public IActionResult Index()
{
var authenticated = HttpContext.User.Identity.IsAuthenticated;
if (authenticated)
{
int? sessionID = HttpContext.Session.GetInt32("ID");
int userCode = _context.Users.First(x => x.ID == sessionID.GetValueOrDefault()).UserCode;
if(userCode != 0)
{
_usersHelper.CheckForTemporaryManagers(userCode);
}
}
return View();
}
My Startup has all the required info:
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache();
string sessionId = Configuration.GetConnectionString("EndSequance");
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.IsEssential = true;
options.Cookie.Name = sessionId;
options.Cookie.Path = "/" + sessionId;
});
services.AddHttpContextAccessor();

add role in database in asp mvc identity

i need to when user regiter add in tabel AspNetRole add user id and role id .
but when i create a user show me this error .
how can i insert role in database ?
/*************************************************************************************************/
identityconfig :
public class ApplicationRoleManager : RoleManager<IdentityRole>
{
public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
: base(roleStore)
{
}
public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
{
return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>()));
}
}
public static class SecurityRole
{
public const string Admin = "admin";
public const string Accounting = "accounting";
}
StartupAuth :
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
AccountController :
public ApplicationRoleManager RoleManager
{
get
{
return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
}
private set
{
_roleManager = value;
}
}
public async Task<ActionResult> Register(RegisterViewModel model, HttpPostedFileBase IamgeProfile)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Username, Email = model.Email };
user.Name = model.Name;
user.Family = model.Family;
user.Address = model.Address;
user.BankName = model.BankName;
user.City = model.City;
user.Ostan = model.Ostan;
user.PhoneNumber = model.PhoneNumber;
user.HomeNumber = model.HomeNumber;
user.ShabaNo = model.ShabaNo;
user.PostaCode = model.PostaCode;
user.NationalCode = model.NationalCode;
if (IamgeProfile != null)
{
IamgeProfile = Request.Files[0];
var ext = System.IO.Path.GetExtension(IamgeProfile.FileName);
if (ext == ".jpeg" || ext == ".jpg" || ext == ".png")
{
string filename = model.Name + model.Family + model.NationalCode + ext;
IamgeProfile.SaveAs(Server.MapPath(#"~/Images/UserImageProfile/" + filename));
user.IamgeProfile = filename;
}
}
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
await UserManager.AddToRoleAsync(user.Id, role: SecurityRole.Accounting);
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking this link: link");
ViewBag.Link = callbackUrl;
return View("DisplayEmail");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
To add a role into AspNetRoles you can do this in your Seed() or other startup method:
if (!context.Roles.Any(r => r.Name == "Admin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "Admin" };
manager.Create(role);
}
https://msdn.microsoft.com/en-us/library/dn613057(v=vs.108).aspx

Authorize attribute doesn't work in MVC

I have a User with a role of Member. I have this Login Action:
public virtual ActionResult Login(string returnUrl)
{
if(User.Identity.IsAuthenticated)
{
if (IsValidReturnUrl(returnUrl))
return Redirect(returnUrl);
return Redirect(FormsAuthentication.DefaultUrl);
}
return View();
}
And I have this ActionMethod :
[Authorize(Roles="Member")]
public virtual ActionResult PostLostThing()
{
var maingroups = _maingroups.SelectAll();
var Provinces = _provinces.SelectAll();
ViewBag.MainGroups = new SelectList(maingroups, "GroupId", "GroupName", maingroups.FirstOrDefault().GroupId);
ViewBag.SubGroups = new SelectList(maingroups.FirstOrDefault().SubGroups, "id", "name");
ViewBag.Provinces = new SelectList(Provinces, "Id", "Title", Provinces.FirstOrDefault().Id);
ViewBag.Cities = new SelectList(Provinces.FirstOrDefault().Cities, "Id", "Name");
return View();
}
When user is logged in and call view PostLostThing it redirects to Login Page, but when the Role of Authorize attribute is removed, it works very well. I have this SetAuthCookie method:
private void SetAuthCookie(string memberName, string roleofMember, bool presistantCookie)
{
var timeout = presistantCookie ? FormsAuthentication.Timeout.TotalMinutes : 30;
var now = DateTime.UtcNow.ToLocalTime();
var expirationTimeSapne = TimeSpan.FromMinutes(timeout);
var authTicket = new FormsAuthenticationTicket(
1,
memberName,
now,
now.Add(expirationTimeSapne),
presistantCookie,
roleofMember,
FormsAuthentication.FormsCookiePath
);
var encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL,
Path = FormsAuthentication.FormsCookiePath
};
if (FormsAuthentication.CookieDomain != null)
{
authCookie.Domain = FormsAuthentication.CookieDomain;
}
if (presistantCookie)
authCookie.Expires = DateTime.Now.AddMinutes(timeout);
Response.Cookies.Add(authCookie);
}
What's the problem?
Since you're setting the auth cookie yourself, you need to implement the Application_AuthenticateRequest in the Global.asax.cs file. Otherwise, nothing beyond the user name is added to the Principal object.
Here's a sample implementation:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
string[] roles = null;
GenericPrincipal userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
Context.User = userPrincipal;
}
}
The overload you're using assumes that the value you've passed roleofMember is actually some serialized data. You then need to tell it how to handle deserializing that user data. Since you're just passing a single role name, you can amend the sample above to:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
string[] roles = new string [] { authTicket.UserData };
GenericPrincipal userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
Context.User = userPrincipal;
}
}

using #User.IsInRole("Admin") in MVC VIEW

I using #User.IsInRole("Admin") in mvc4
when i use this command in global.asax it return true but when I use in view of mvc it return sql server connection error .
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Context.User == null)
return;
var userService = ObjectFactory.GetInstance<IUserService>();
UserStatus userStatus = userService.GetStatus(Context.User.Identity.Name);
if (userStatus.IsBaned)
FormsAuthentication.SignOut();
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
return;
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// retrieve roles from UserData
if (authTicket == null) return;
string[] roles = authTicket.UserData.Split(',');
if (userStatus.Role != roles[0])
FormsAuthentication.SignOut();
Context.User = new GenericPrincipal(Context.User.Identity, roles);
}

mvc 4 can not be custom Authorize roles

HomeController
[Authorize(Roles = "Member")]
public ActionResult Contact()
{
return View();
}
Global.asax
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
//Construst the GeneralPrincipal and FormsIdentity objects
var authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (null == authCookie)
{
//no authentication cokie present
return;
}
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (null == authTicket)
{
//could not decrypt cookie
return;
}
//get the role
var role = authTicket.UserData.Split(new[] { ',' });
var id = new FormsIdentity(authTicket);
Context.User = new GenericPrincipal(id, role);
}
AccountController
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && _userbll.ValidateUser(model.UserName, model.Password))
{
var ticket = new FormsAuthenticationTicket(1, model.UserName, DateTime.Now, model.RememberMe ? DateTime.Now.AddDays(14) : DateTime.Now.AddMinutes(30), model.RememberMe, "Member");
var hashTicket = FormsAuthentication.Encrypt(ticket);
var userCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashTicket);
Response.Cookies.Add(userCookie);
return RedirectToLocal(returnUrl);
}
ModelState.AddModelError("", "error");
return View(model);
}
FormsAuthenticationTicket userData= "Member"
at last,use the mechanism of Membership Role made in built
结果还是使用了 Membership Role 内置的机制
mvc3 can be read userData

Resources