asp.net mvc global vs class filters - asp.net-mvc-3

My MVC 3 app has authorize filters at the class level. As I understand it, when I try for example /Home/Index and I have not logged in it should re-route me to the page I have specified - my log-in page.
My app does not do this and I am allowed to see the result of Home/Index having not logged in; However, when I register the filters globally, the authorization step kicks in as expected.
Any ideas?

What do you mean by class level authorize filters? If you place it on the controller it will work and apply to all action on this particular controller:
[Authorize]
public class HomeController: Controller
{
public ActionResult Index()
{
return View();
}
}
Now if you try to navigate to /Home/Index and the user is not logged in he will be redirected to the LogOn action.

Related

Login page with Spring

I'm setting up my security support in Spring and I am exploring what it has to offer. While setting up my login URL and view, I needed to register simple controllers for home and login URL. Concretely, code is:
#Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/").setViewName("home");
registry.addViewController("/login");
}
In line registry.addViewController("/").setViewName("home"); it seems that that line simply adds controller for URL "/" and for GET to that URL simply uses view "home" for rendering.
Did I get it right? Main question is about line registry.addViewController("/login");. Here I add controller for "/login" URL.
But how application knows which view to use? When I tried the app it really used "login" view I created.
Well, you are on the right track but not completely. If you are NOT logged in and open the URL "yourdomain.tld/" you will be redirected to the URL "yourdomain.tld/home" which normally could be a login page. (first line). Of course, you need a controller to handle this request and return a proper JSP/JSF page.
Your second line is not needed. The trick is that with such a configuration you can use the URL "yourdoamin.tld/" with a different page for logged in users.
And to answer your main question, you need a controller for every URL or part of the URL you want to use. And within this controller, you can choose the views according to the requested URL.
Example:
#Controller
#RequestMapping(value="/info")
#Scope(value="session")
public class InfoController extends AbstractWebController {
#RequestMapping
public ModelAndView infoPage() {
ModelAndView mav = this.getModelAndView("info/infopage");
return mav;
}
}
This controller is responsible for all URLs starting with "yourdomain.tld/info". And as you can see I have only the URL "yourdomain.tld/info" to return a proper view. In this example I return "infopage.jsp". You can add code to return different views for other pages.

Simple login to session

I work on simple project in .net core. It school task, so I do not need any advanced practices. Can you tell me what is the simplest way to set default view when session is null ? For example When user manually enter Url /Home/Tasks he will be redirected to Account/Login until enter correct login. Thanks
You achieve that simply use basic authentication. Choose Individual User Accounts option while creating new application:
After that take a look at the Startup.cs class and add following lines to ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<IdentityOptions>(options =>
{
options.Cookies.ApplicationCookie.LoginPath = new PathString("/Login");
options.Cookies.ApplicationCookie.LogoutPath = new PathString("/Logoff");
});
}
or
services.Configure<CookieAuthenticationOptions>(options =>
{
options.LoginPath = new PathString("/Account/Login");
});
Ones this is done you can mark your controller with an [Authorize] attribute and all actions of that controller will require user to be logged in:
[Authorize]
public class HomeController : Controller
{
...
}

Redirecting to login view when unauthorized during POST

I am using AuthorizeAttribute to ensure that my controller actions aren't ran when the current user is unauthorized. This works great for GET requests. If the user is not authorized then they are redirected to the login view.
However, this does not work for POST requests as the browser isn't expecting to be redirected during a POST.
The generally agreed upon solution to this is to disallow users from reaching portions of the application which generate POST requests without first being authorized. While this logic makes sense, I don't think it encompasses all real world scenarios.
Consider having the web application open in two tabs. The user is signed in and authorized in both tabs and is viewing content which, when clicked, could initiate a POST request. The user then signs out of one tab and is taken back to the login page. The other tab is unaware that this event has occurred. The user then initiates a POST request from this second tab.
How can I gracefully redirect them to the login page in this scenario?
I believe you are incorrect. I have a custom blog (that still needs a ton of work) which I use the [Authorize] attribute on the Admin controller. This controller handles blog post.
I tested your scenario of:
Opening up two browser screens on my post screen
logging out in the first tab
Attempting to post on the second tab
when it tried to post it redirected me to the login screen.
[Authorize]
public class AdminController : BaseController
{
public ActionResult Post(int? id)
{
if (id != null)
{
var blogPost = _blogService.RequestPost((int)id);
var blogPostViewModel = _blogPostViewModelMapper.CreateViewModel(blogPost);
return View(blogPostViewModel);
}
return View();
}
//
// POST: /Post/
[HttpPost]
public ActionResult Post(BlogPostViewModel blogPost)
{
var stringTags = blogPost.Tags.Split(',');
var tagIds = _blogTagMapper.MapStringsToIds(stringTags);
blogPost.TagIds = tagIds;
_blogService.SaveBlogPost(BlogPostlMapper.CreateEntity(blogPost));
return RedirectToAction("Index", "Home");
}
}

What is ReturnURL in mvc3

What is Return URL in mvc3? When i write down my url in adress bar of the browser, at the append return url is automatically appended to it. How this happnes?
I provide the following url in adress bar
http://localhost:55875/admin
and after pressing enter it becomes
http://localhost:55875/Account/Logon?ReturnUrl=%2fadmin
I have debugged the logic for Logon action method, but dont see any logi which is appending returnurl to the provided url? How did this happen?
When an unauthenticated user tries to get into a section of your application which requires authentication, then returnUrl comes into the picture.The Url requested by the unauthenticated user is basically stored in returnurl.
for example below controller decorated with Authorize attribute :
[Authorize]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
The login action grabs the value of this parameter and puts it in the ViewBag so it can be passed to the View.
The View then stores this value in the form as shown by this line of code in the View.
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
The reason it is stored in the View is so that when the user does a Submit after entering their user name and password, the controller action that handles the post back will have access to this value.
Your application must be having Authentication for login which is handled by [Authorize] attribue. as user is not authenticated it returns to logon page with returnurl as admin
For more on AuthorizeAttribute How to use authorize attribute on MVC3
Below is the standard action of login when you login above returnurl ie admin is passes as second parameter, depending on which user is redirected to the page using return Redirect(returnUrl);
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Routing is one of the core concept of any ASP.NET MVC application. A URL of a MVC application is the combination of your Application root URL followed by Controller name and then Action to which request has been made e.g.
http://localhost:55875/{controller}/{action}/{optional parameters}
You probably have chosen new project with Account Controller and Authorization membership providers. As fellow members has mentioned, the Authorize attribute is probably the main reason you are being redirected to logon page.
From the documentation of Authorize attribute:
If an unauthorized user tries to access a method that is marked with
the Authorize attribute, the MVC framework returns a 401 HTTP status
code. If the site is configured to use ASP.NET forms authentication,
the 401 status code causes the browser to redirect the user to the
login page.
In browsers, whenever you hit enter key in address bar, browser always make a GET request to the server for resources.
That is what could have happened. Either your Admin Controller or its Index() method is decorated with [Authorize] action filter attribute e.g.
public class AdminController : Controller
{
///<summary>
/// This view will open whenever you make a HTTP GET request to your Admin
/// controller without providing any action method name in request explicitly.
/// Because it is decorated with Authorize attribute, any user who has not logged in
/// will be redirected to the login page...
///</summary>
[Authorize]
public ActionResult Index()
{
return View();
}
}
You may wonder why did application redirected to login view?
This is because by default this action has been set in your application inside your web.config file.
<authentication mode="Forms">
<forms loginUrl="~/Account/Logon"/>
</authentication>
MVC leverages the power of built-in authentication logic and redirects the user to view that has been set under loginUrl.
Try removing the [Authorize] action filter just for a change and see what happens. In the end it is your business logic to decide on which views you need to have only authorize or anonymous access.
However, you may also take a look at AllowAnonymous attribute. It allows you to skip authorization for a perticular contoller or action.
[Authorize]
public class AdminController : Controller
{
///<summary>
/// Skips Authorization..
///</summary>
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
///<summary>
/// Only allows authorize access...
///</summary>
public ActionResult Secure()
{
return View();
}
}
You can customize/override the behavior of these action filters as well.
Notice, [Authorize] has been added to controller itself if you have selected the project with internet and membership providers which will make all the actions inside this authorized except those with [AllowAnonymous] filter (if exists).
This article has good overview of Action filters in MVC.
First: you are trying to access an authorized page so every time you are trying to access this page the application automatically redirect you to login page
Second: how this happened?
in web.config file you can find a section for authentication
<authentication mode="Forms" >
<forms loginUrl="~/Account/Logon"/>
</authentication>
this section says that each time you are trying to access authorized page you will be redirected to this page and since its forms authentication so you will be redirected to this page
another thing you may using Authorize an AuthorizeAttribute which tells the application that the following ActionResult can't be accessed by anonymous users you can use this attribute in class level or ActionResult level as follows
[Authorize]
public class HomeController
{
}
Or
public class HomeController
{
[Authorize]
public ActionResult Index()
{
}
}

FormsAuthentication.SignOut() does not want to redirect to logout view

I am trying to redirect to a logout view when the user clicks on logout but mvc intercepts the redirection.
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return RedirectToAction("Logout", "Account");
}
public ActionResult Logout()
{
return View("LogOff");
}
Id like the LogOff view to be displayed after logout
I guess you have marked the complete account controller with the Authorize attribute. You should decorate only the actions that required authorization with that.

Resources