Back button takes you back to authenticated page after logout - c#

When user hits back button after logout, they get Document Expired. However, when user click on this message
Click Try Again to re-request the document from the website,
in browser, they are able to access an authenticated page again.

It is because the page is cached. For all secure requests you will need to manually kill the cache. You can do something like this:
public class SecurePageAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
}
}
You would then use it in your controllers like so:
[SecurePage]
public ActionResult Index() {
return View();
}
You could also annotate your entire controller or register this globally if the majority of your site is secure.

For a GET Request, you'd expect them to still see the authenticated page on "back" but not be able to interact with it (assuming you use POST for actions).
Since you're talking about a POST Request though (as it's giving you the expired message), it's possible that you're missing the [Authorize] attribute from your controller/action which will allow any unauthenticated user to access it, have you checked this?

Related

MVC Authorization Route

So, I'm using the ASP.NET SimpleMembershipProvider user, roles and authorization structure. This controller requires the user is logged in, so that when it acesses this page while logged off, the login page appears.
[Authorize]
public class CompanyController : Controller
{
//stuff...
}
For this page, I want restricted access only to admins, so here it goes
[Authorize(Roles = "Admin")]
public class UserManagementController : Controller
{
//fields, methods, etc...
}
But when I try to access it logged off or logged in with a user account not in the "Admin" role, it shows the login page, but I wanted a custom page telling the user that page has restricted access and he does'nt have the credentials. How to do it, I mean without having to resort to if's and redirects in every method, that would blow the point of authorization atributes.
Thanx
You can put authorization attributes on methods NOT just the class for more fine grained control.

MVC 4 redirect from login page to previous page after user weren´t authorized before

i would like to ask if c# or mvc has a easy way to redirect user back to the page they came from if they are try to enter a unauthorized page and have to login?
I already have a very huge web app and i´m a litte bit too lazy to overwork every single method with a direction string to it´s page for the case of unauthorization. So if it is possible i would like to choose another way, more resitent for changes.
For authorization at moment i use a custom class inherited from AuthorizeAttribute:
public class CustomAuthorizationAttribute : AuthorizeAttribute
{
public RolesEnum[] RequiredRoles;
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null) throw new ArgumentNullException("httpContext");
if (!httpContext.User.Identity.IsAuthenticated) return false;
if (RequiredRoles.Contains(AzaraSession.Current.UserComparison.GetRole())) return true;
else return false;
}
}
we can save route path in Session before redirecting to Authentication page and immediately after authenticating with help of session we can redirect back,
this will be one time code changes.
Thanks and lets us know in case of any issue.
I found a very easy solution in the AuthorizeAttribute directly. It creates an parameter 'returnUrl', which have the url of the failed login page. So i just need to take this parameter in the 'LogOn' method and 'Redirect' to this page after login is operated.

ASP.NET MVC Roles and Security

Assume like this is my SampleController action method
public ActionResult AdminView()
{
return View()
}
If want this controller method to be called if the logged in user belongs to admin role, otherwise this method call should be blocked and the user should get an some custom unauthorized access error page.
In my asp .net mvc web application, when the user logs in, I am storing the user role in a session as a string. And whenever there is a need to validate the user role, I compare the value stored in the session against a constant say "ADMIN_ROLE". But I am writing that piece of code to check for the user role in almost every controller action method and then either return an appropriate view for the user or an unauthorized access page view if the user role is restricted for the controller action method.
I googled and read that we can use something like this.
[Authorize(Roles="admin")]
public ActionResult AdminView()
{
return View()
}
But I am not sure how the Authorize and the Roles keyword works. How when putting Roles = "Admin", is going to help in checking my user role string stored in the session, or how I can redirect a user to unauthorized page, in case the role does not match the role tagged for the action method.
As per my thinking you need to code for authorization.
public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
private readonly RoleEnum[] _acceptedRoles;
public AuthorizeAttribute(params RoleEnum[] acceptedroles)
{
_acceptedRoles = acceptedroles;
}
public AuthorizeAttribute(params bool[] allowAll)
{
if (allowAll[0])
_acceptedRoles = new RoleEnum[] { RoleEnum.Admin, RoleEnum.user};
}
public void OnAuthorization(AuthorizationContext filterContext)
{
if (SessionHelper.UserInSession == null)//user not logged in
{
FormsAuthentication.SignOut();
filterContext.Result =
new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary {{ "controller", "Home" },
{ "action", "Index" },
{ "returnUrl", filterContext.HttpContext.Request.RawUrl } });//send the user to login page with return url
return;
}
if (!_acceptedRoles.Any(acceptedRole => SessionHelper.UserInSession.UserRoles.Any(currentRole => acceptedRole == currentRole.Role)))
//allow if any of the user roles is among accepted roles. Else redirect to login page
throw new UnauthorizedAccessException();
}
}
This is also work for return URL.
As per comments, if you are using custom authentication/authorization mechanism then you need to implement custom authorize attribute where you can put custom logic to check if user has admin role or not. Something like below:
public class CustomizedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
//check for role in session variable "ADMIN_ROLE"
//if not valid user then set
filterContext.Result = new RedirectResult(URL)
}
}
There is a small nice explanation in this link:
http://weblogs.asp.net/jgalloway/archive/2011/04/28/looking-at-how-asp-net-mvc-authorize-interacts-with-asp-net-forms-authorization.aspx
as per this:
ASP.NET MVC includes an [Authorize] attribute, which when placed on any controller actions will forbid unauthorized access. The AuthorizeAttribute allows you to specify a list of roles or users.
You can also place the AuthorizeAttribute on a controller, in which case it will apply to all actions in the controller. Attempting to access an action secured by the AuthorizeAttribute when you're not logged in will take you to a standard LogOn screen, with a link to register if you don't already have an account.
How does the [Authorize] attribute redirect me to Log On?
The AuthorizeAttribute is an ActionFilter, which means that it can execute before the associated controller action. The AuthorizeAttribute performs its main work in the OnAuthorization method, which is a standard method defined in the IAuthorizationFilter interface. Checking the MVC source code, we can see that the underlying security check is really just looking at the underlying authentication information held by the ASP.NET context:
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
return false;
}
If the user fails authentication, an HttpUnauthorizedResult ActionResult is returned, which produces an HTTP 401(Unauthorized) status code. If it weren’t for ASP.NET Forms Authentication, an HTTP 401 status code would be sent to the browser, which would show the browser’s default login prompt.

How to set a default initialization cookie in ASP.NET MVC

I was wondering if anyone can shed some light on cookie management. More precisely I would like to know how I could set up an initial cookie/s when a user start a session in a website.
Currently the ASP.NET_SessionId cookie is located on user computers when they navigate to the domain. I would like to set up an additional cookie with details of languageid and countryid with default parameters the first time the user navigate to the site.
Do anyone knows if there is any technique to do this, such as through web.config set up or placing cookie details using layout.cshtml like
Response.Cookies["language"].Value = "1";
Response.Cookies["country"].Value= "7";
or similar?, any option will be appreciated.
You could do this in an action filter:
public class LocalizationAwareAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var httpContext = filterContext.HttpContext.Current;
if (!httpContext.Cookies.Keys.Contains("language"))
{
httpContext.Response.AppendCookie(new HttpCookie("language", 1));
}
if (!httpContext.Cookies.Keys.Contains("country"))
{
httpContext.Response.AppendCookie(new HttpCookie("country", 7));
}
}
}
The filter can be applied globally, so you don't have to worry about remembering it on each action method or controller.
I haven't worked much with cookies in ASP.NET MVC, but the way I'd do it would be to have a little block of code in Global.asax or a separate base controller that gets executed on every request. This code would check the HttpContext for the existence of such a cookie, and if it didn't exist, it would create one. I'll work up a code sample and will update this answer soon.

ASP.NET MVC: What is the correct way to redirect to pages/actions in MVC?

I am fairly new to MVC but not sure exactly which Redirect... replaces the standard redirect used in WebForms is the standard Response.Redirect()
For instance, I need to redirect to other pages in a couple of scenarios:
WHen the user logs out (Forms signout in Action) I want to redirect to a login page.
In a Controller or base Controller event e.g. Initialize, I want to redirect to another page (AbsoluteRootUrl + Controller + Action)
It seems that multiple redirects get called in some cases which causes errors, something to do with the fact a page is already being redirected? How can cancel the current request and just redirect?
Update:
The answer to this question (System.Web.Mvc.Controller Initialize) indicates that Initialize should not be used and OnActionExecuting should be used?
Any comments on why Initialize should not be used or why OnAuthorization is not a better option?
More Info:
This blog post (http://blog.wekeroad.com/blog/aspnet-mvc-securing-your-controller-actions/) indicates that OnActionExecuting is useful for authentication (as indicated in the link above) I guess adding this to that event in the base Controller class is fine as every page runs an Action in MVC so shouldn't make much difference and having the ability to redirect should be easier. This does make sense, but it also seems to make sense to me that things could be done in an event before this event and makes we question what those events are for? Will be giving OnActionExecuting a go..
1) When the user logs out (Forms signout in Action) I want to redirect to a login page.
public ActionResult Logout() {
//log out the user
return RedirectToAction("Login");
}
2) In a Controller or base Controller event eg Initialze, I want to redirect to another page (AbsoluteRootUrl + Controller + Action)
Why would you want to redirect from a controller init?
the routing engine automatically handles requests that come in, if you mean you want to redirect from the index action on a controller simply do:
public ActionResult Index() {
return RedirectToAction("whateverAction", "whateverController");
}
1) To redirect to the login page / from the login page, don't use the Redirect() methods. Use FormsAuthentication.RedirectToLoginPage() and FormsAuthentication.RedirectFromLoginPage() !
2) You should just use RedirectToAction("action", "controller") in regular scenarios..
You want to redirect in side the Initialize method? Why? I don't see why would you ever want to do this, and in most cases you should review your approach imo.. If you want to do this for authentication this is DEFINITELY the wrong way (with very little chances foe an exception)
Use the [Authorize] attribute on your controller or method instead :)
UPD:
if you have some security checks in the Initialise method, and the user doesn't have access to this method, you can do a couple of things:
a)
Response.StatusCode = 403;
Response.End();
This will send the user back to the login page.
If you want to send him to a custom location, you can do something like this (cautios: pseudocode)
Response.Redirect(Url.Action("action", "controller"));
No need to specify the full url. This should be enough.
If you completely insist on the full url:
Response.Redirect(new Uri(Request.Url, Url.Action("action", "controller")).ToString());
RedirectToAction("actionName", "controllerName");
It has other overloads as well, please check up!
Also, If you are new and you are not using T4MVC, then I would recommend you to use it!
It gives you intellisence for actions,Controllers,views etc (no more magic strings)

Categories