when I was writing ASP.NET applications I used the Forms Authentication with my custom login page, like so:
Once login is a success I checked him as authenticated:
FormsAuthentication.RedirectFromLoginPage(userId.ToString(), true);
In order to check if a user is logged in, I had a class that inherited from a base page and all pages inherited from it, which contained a method that returned a bool after checking if the user is authenticated, with the following command:
return HttpContext.Current.User.Identity.IsAuthenticated;
Now, I'm doing an ASP.NET MVC application, and was wondering what is the best was to do that on MVC?
Thanks
ok MVC is very simple and similar
for your question you can use like .......
in your controller
public ActionResult LogOn()
{
return View();
}
//
// POST: /Account/LogOn
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var userInfo = new UserInfo()
{
UserName = model.UserName,
Password = model.Password,
};
var service = new CSVService();
if(service.ValidateUser(userInfo))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return Redirect("~/");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
The best way to authenticate website / web-application is using the Membership which is provided by Microsoft built in for Easy-ness .
From this you can do following things(features)
it maintains Log-in status (you don't have to bother about Authentication).
It allows to provide Roles & Users and Assigning permission who can see which page
(Page Restriction)
It provides built-in Stored Procedures and UI tools like Log-in, Log-out,user,Password Recovery, Etc elements. & Highly secure (Hack-Proof)
for more info:
Walk through Membership (MSDN)
Related
I'm able to authenticate using anything for a password. The email has to be a valid registered email, but the pwd doesn't matter. Everything else is working normally.
Any suggestions on where to start trouble shooting this? I haven't found any similar issues in web searches.
My view...
My action in the account controller...
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(AccountLoginModel viewModel)
{
if (!ModelState.IsValid)
return View(viewModel);
var user = _manager.FindByEmail(viewModel.Email);
if (user != null)
{
await SignInAsync(user, viewModel.RememberMe);
string uid = user.Id;
return RedirectToLocal(viewModel.ReturnUrl);
}
ModelState.AddModelError("", "Invalid username or password.");
return View(viewModel);
}
and the signinasync method...
private async Task SignInAsync(IdentityUser user, bool isPersistent)
{
// Clear any lingering authencation data
FormsAuthentication.SignOut();
// Create a claims based identity for the current user
var identity = await _manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
// Write the authentication cookie
FormsAuthentication.SetAuthCookie(identity.Name, isPersistent);
}
I did create a seperate MVC web project to see the scaffolded login action, which is quite a bit different. The SmartAdmin template is customized enough that its difficult to start changing things without knowing what I'm effecting. Any direction is appreciated.
If username in your system is email, you should use
var user = _manager.FindAsync(viewModel.Email, viewModel.Password);
and then signin the user if it's not null.
If username is not email, you should first get the user and then check for password
var user = _manager.FindByEmail(viewModel.Email);
bool isPasswordCorrect = await _manager.CheckPasswordAsync(user, viewModel.Password);
I'm having some trouble with my application, because I need 2 ways to log in: form (user + password) or route (passing user unique identifier).
I configured FormsAuthentication and it's working for user + password method, but when I try to log in through unique identifier, I can't redirect to my HomeController.
User + Password:
[HttpPost]
public string Authenticate(string usuario, string senha, string returnUrl)
{
var authenticated = this.UsuarioService.Acessar(usuario, senha, out int codUsuario);
if (authenticated)
{
var user = this.UsuarioService.Buscar(codUsuario);
MontaPermissoes(ref user);
FormsAuthentication.SetAuthCookie(JsonConvert.SerializeObject(user), false);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
return returnUrl;
else
return Url.Action("Index", "Home", new { id = "" });
}
return null;
}
Unique Identifier:
[HttpGet]
private RedirectToRouteResult Autenticacao(Guid uniqId)
{
var usuario = UsuarioService.Buscar(uniqId);
if (usuario != null)
{
MontaPermissoes(ref usuario);
FormsAuthentication.SetAuthCookie(JsonConvert.SerializeObject(usuario), false);
return RedirectToAction("Index", "Home", new { culture = RouteData.Values["culture"] });
}
return RedirectToAction("Index", "Login", new { culture = RouteData.Values["culture"] });
}
Using user + password, I just return next URL to redirect via Javascript, but unique identifier log in will be used by another application, using the same database.
This problem could be IIS related, your application has to have two authentication options enabled.
FormsAuthentication
Anonymous Authentication
With anonymous authentication enabled the application can allow Anonymous calls.
You can add an AllowAnonymous attribute to your controller or specific controller methods to make sure that FormsAuthentication won't be triggered.
[AllowAnonymous]
public class MyController: Controller {}
I'm trying to take advantage of Microsoft.AspNetCore.Authentication.MicrosoftAccount in a .NET Core MVC app as explained here, but I would like to skip the storage layer, so that users are not entered in the database.
What I would like to achieve is: ok, my users are just external Microsoft accounts, I don't do any management of them, I just let them login to the app and check, somehow (a list or whatever) which ones are the allowed ones (like john#boo.com can login, and since his identity is verified by the Microsoft account, well, then he can enter).
What I did was to start with the typical
dotnet new mvc --auth Individual
Them modify it to support Microsoft accounts and that worked.
But, I would like to bypass creating the user in the database, and just log him in. I tried the following:
// GET: /Account/ExternalLoginCallback
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
return View(nameof(Login));
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return RedirectToAction(nameof(Login));
}
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
var user = new ApplicationUser { UserName = email, Email = email };
// var result = await _userManager.CreateAsync(user);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "Microsoft account logged in.");
return RedirectToLocal(returnUrl);
}
But if I don't do the
_userManager.CreateAsync
it fails miserably :-S
So, is there a way to achieve this or what I'm trying simply goes against the Identity principles?
Thanks!
This article show how to use the ASP.NET OAuth providers without ASP.NET Identity, in other words without a DB.
I have a MVC and a Web API projects within the same solution, on the MVC project I have a very small Admin area protected with a login and password (just for one user). On this area I get the data on clinet side using API calls.
This is my Login function:
public ActionResult SubmitLogin(string UserName, string Password)
{
if (ModelState.IsValid)
{
if (UserName == "xxxxx" && Password == "yyyyy")
{
FormsAuthentication.SetAuthCookie(UserName, true);
return RedirectToAction("Index", #"Admin/Users");
}
}
var errors = (from value in ModelState.Values
from error in value.Errors
select error.ErrorMessage).ToList();
if (errors.Count == 0)
{
errors.Add("UserName or Password are incorrect");
}
ViewBag.Message = errors;
return View("Index");
}
The Login form works fine, the issue is with the API calls, my API controller is [Authorize] but when I make a request:
self.getUsers = function (callback) {
$.get("../MySite.API/Users/GetUsers/", callback);
}
I get a 401 error.
I understand I have to somehow send the AuthCookie with the AJAX request but I'm not sure how.
Any help would be appreciated.
I have an asp.net mvc4 application, in which i have to logout from an account :
if (_fonction == "User")
{
if (_is_admin == true) return RedirectToAction("Index");
else
{
Session["user"] = _u;
return RedirectToAction("Index", "User");
}
}
in the controller User
public ActionResult Index()
{
if (Session["user"] == null) return RedirectToAction("Index", "Home");
return View(Session["user"]);
}
the action Logout
public ActionResult Logout()
{
if (_is_admin) { Session["user"] = null; return RedirectToRoute("Administration"); }
else { Session["user"] = null; return RedirectToAction("Index", "Home"); }
}
i do this : i log in to a user account then i disconnect so i'am in the home page , then i click into the back button of the browser i got the page of the account. When i refresh i returned to the home page. i think that the problem is in the cache and i don't think that make it null is a good idea .
So how can i fix this problem?
You can try to add [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] as an attribute to your User controller's Index action to force non-cached results.
But I would strongly suggest to just use AuthorizeAttribute because this will prevent unauthorized web requests done on a specific view. The benefit of using this is that you still give the users the liberty to cache your views and be secured at the same time.
if you do not want to clean your cache then below is the javascript which helps you to hard refresh your page on click of the browser back button
if (window.name != "") { // will be '' if page not prev loaded
window.name = ""; // reset to prevent infinite loop
window.location.reload(true);
}
window.name = new Date().getTime();
put the above "javascript" code on your page. so, it will hard refresh your page.