How can I force the user login before go to any where in my application? - asp.net

I'm working on the asp.net mvc5 project, my problem is forcing the user login then they can go anything on my site. I'm using Session to check user login or not (I'm not using Identity or Authorization).
Here is my Login code:
[HttpPost]
public ActionResult Login(User user)
{
if (IsValid(user.username, user.password))
{
Session["username"] = user.username;
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Login details are wrong.");
}
return View(user);
}
I can check the user login or not with Session but I cannot deny the user access to the link, if I have to do this manually, I will need to add the block code below to any action in every controller I have.
public ActionResult Index()
{
if (Session["username"] != null)
{
//then user can go anywhere with any link
}
else
{
//user cannot go to here without login
}
}
There is any way I can force the user to redirect to the login page (if they are not login) when they click on any link or type the link in the browser? I was searching about config the route or using filter config but it seems not to solve my problem. I hope there has the general way to do this without adding the check-code manually to each controller/action.
Thanks for reading my problem, I will be very appropriated any comment to help me solve this.

One possible way to tackle on this globally is to override the OnActionExecuting method on the controller, that does the check and redirects to the homepage if no user is logged or allows the action if there is a user.
This can be done on a base controller so that it applies to all the website (by making all controllers inherit from this one).
public abstract class LoginRequiredController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (Session["username"] != null)
{
base.OnActionExecuting(filterContext);
}
else
{
//Redirect to the main page, or login, or somewhere else, without running the requested action
filterContext.Result = Redirect("/");
return;
}
}
}
Controllers inheriting from this one will check on each request that there is a user, and redirected to the main page in case there isn't one, without needing to copy/paste this check for each method.
Of course, the login controller should not inherit from it or it would be impossible to login at all.

Related

ASP.Net Custom Authorize Attribute Incorrectly Redirects to Login Page in IE

I wanted to show a custom access denied page when the user doesn't have the proper role to access a page so I created a custom AuthorizeAttribute. This has worked well, but we had a strange issue come up. One of our pages is using the default index action, and this one will redirect users to the login page when they are using IE. This only appears to happen in IE and it only happens if the action is defaulted. Meaning, the URL with /Area/Controller/Index works fine, but if you simply put in /Area/Controller it redirects to the login page.(specified in the forms tag in the web.config) Another oddity is that this was happening consistently in a prod environment, but not in a test environment. There's nothing in the web.config tags specific to the page and nothing funny that jumps out in the Route config for the area.(below)
Anyone know of any bugs or something else to investigate?(or maybe something quirky about the default action that may explain it)
context.MapRoute(
"TicketEntry_default",
"TicketEntry/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
Here is the Authorize attribute:
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult("/Login");
return;
}
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.IsAjaxRequest() ? "/Login/Login/AccessDeniedAjax" : "/Login/Login/AccessDenied");
}
}
}

Include JavaScript based on ActiveDirectory Membership

I've got a single page application and in the start page I've linked to the ActionResult "_ADMIN()"
#Html.Action("_ADMIN")
Depending on the user's group membership, this ActionResult returns either an EmptyResult or its view:
public ActionResult _ADMIN()
{
if (User.IsInRole("admin"))
{
return View();
}
else
{
return new EmptyResult();
}
}
Its view consists of this one line:
#Scripts.Render("~/bundles/admin")
This works but feels suboptimal. I could copy the start page and create seperate ones for non-admins and admins, but that would be even more suboptimal. I'm using MVC 4.
What's a better way to include a bundle of JavaScript only if the current user is in a certain Active Directory group?
You can add scripts depending on roles. Like that :
if (User.IsInRole("admin"))
{
#Scripts.Render("~/bundles/admin")
}
And on your Action method you add attribute then the user will be automatically redirected to the login page if it does not have rights. You can add this attribute also on whole class.
[Authorize(Roles = "admin")]
I would only show the link to admin users:
if (User.IsInRole("admin"))
{
#Html.Action("_ADMIN")
}
Then, in the event a non-admin tried to access the action method, I would block the request at the action method:
[Authorize(Roles = "admin")]
public ActionResult _ADMIN()
{
return View();
}

Load different master pages for different users

In my Web-project (ASP.NET) I need 2 different master pages. One for users like "Admin", and one for the usual users. Where can I indicate what master page to load? How can I load the correct master page, depending on the user?
When your admin user try to log in check the username and password with the database and if the login credentials are valid, Set a session variable to indicate this is an admin session. Then you can have a method which returns true of false by checking the session value to tell you whether the current user is an admin or normal user.
When admin login is successfull, set this session variable
Session["adminUserName"]=txtUserName.Text;
Then write a method to check whether the current user is an admin or not
public bool IsAdmin()
{
if(Session["adminUserName"]!=null)
{
return true;
}
else
{
return false;
}
}
Have this method in a common place (like your base class or so ) and check during the page life cycle and load the appropriate master page.
void BasePage_PreInit(object sender, EventArgs e)
{
if(IsAdmin())
{
MasterPageFile = "~/MasterAdmin.master";
}
else
{
MasterPageFile = "~/MasterNormal.master";
}
}
If Its an ASP.NET MVC application, You can check this in your ActionMethod.
public ActionResult Index()
{
if(IsAdmin())
{
return View("Index", "MasterAdmin");
}
else
{
return View("Index", "MasterNormal");
}
}
Handle the Page_PreInit event in code-behind and set the MasterPageFile property to your liking.

MVC3 logged in User can see only own stuff apart from Admin

A novice to asp.net and mvc3. I am learning by setting myself challenges/developing an application. I tag all record tables where users interact with ProviderUserKey. Now I want to be able to restrict users logged in to be able to edit or delete their own records only but administrators can edit or delete any. I have been using scaffolding to generate controllers and views etc. for eg code for editing`// POST: /Post/Edit/5
[HttpPost]
public ActionResult Edit(PJpost pjpost)
{
if (ModelState.IsValid)
{
db.Entry(pjpost).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(pjpost);
}`
Any help will be highly appreciated.
If you have a generic Edit method/action and you would like to keep it that way, I would add a method in your controller somethink like ValidateOwnership(record). This method would need to verify if CurrentUser's ID is matching the one on the record and if user is a member of particular role - that can be done with RoleManager class. Method would return true/false.
When you got it ready just put the call to the method in your code after ModelState validation. It would look like this
[HttpPost]
public ActionResult Edit(PJpost pjpost)
{
if (ModelState.IsValid)
{
if(IsOwnershipValid(pjpost){
db.Entry(pjpost).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
else {
ModelState.AddModelError("ERROR","You're not allowed to do that");
return View(pjpost);
}
}
return View(pjpost);
}
EDIT :
So the OwnershipValidation could look like this :
public bool ValidateOwnership(Pjpost pjpost) {
if (pjpost.MemUID == Membership.GetUser().ProviderUserKey.ToString())
{
return true;
}
else
{
return false;
}
}
I hope this is what you meant.
You need to look in to user roles and the process of authorization usually, MVC provides a registration and log in in it template including the account controller. To restrict user access you have to assign roles to users.
the code behind it would look something like this.
[Authorize(Roles="admin")]
public ActionResult admin()
{
//Action gives an admin rights since the user is in the admin role
return View();
}
[Authorize(Roles="manager")]
public ActionResult manager()
{ //give a managers rights since user is im managers roles.
return View();
}

What is the correct way to implement login with redirect using JSF 2.0?

Part of my site should be accessible only to authorized users. Let's assume user would enter page a.html which belongs to the authorized-only part.
If I was to use servlets/JSP I could write a filter that checked whether user is logged in and if not - redirected him to login page. After a successful login user would be redirected to the page he wanted to reach initially, in this case a.html. (Page address could be stored in request).
What is a proper way to implement such scenario in JSF 2.0?
Just do it the same way, with a Filter. It's good to know that JSF session scoped managed beans are under the covers stored as a HttpSession attribute with the managed bean name as key.
Assuming that you've a managed bean like this:
#ManagedBean
#SessionScoped
public class UserManager {
private User user;
// ...
public boolean isLoggedIn() {
return (user != null);
}
}
Then you can check it in Filter#doFilter() as follows:
UserManager userManager = (UserManager) ((HttpServletRequest) request).getSession().getAttribute("userManager");
if (userManager != null && userManager.isLoggedIn()) {
chain.doFilter(request, response);
} else {
((HttpServletResponse) response).sendRedirect("login.xhtml");
}

Resources