ASP.NET MVC - check Facebook login status - asp.net-mvc-4

This is more of a design question.
I figured out how to use the facebook login via the Facebook SDK c#.
QUESTION: What is the best way to check whether the user is logged into FB or not each time the user goes to a different page?
Back on ASP.NET webforms, I could simply put in code to check FB login status in the code behind of a master page. This was good ... once and done. But I don't understand how to implement something similar in Asp.Net MVC 4.0.
Given that the _Layout.cshtml file (which acts like a master page) is only a view (hence, no code behind), what is the best way to code a way to check if the user is logged into FB each time a user goes to a different web page? Because I would think, adding this bit of code to each controller can't be the optimal design solution.
The only solution that I can think of involves using Javascript on the client side to do a WebApi call ... I guess the script will be bundled with all the other scripts so that it runs on each page. But I was hoping to find a solution on the server side ...
I'm pretty new to MVC, learning things as I go along ... tips appreciated ... thanks!

I can think of a couple of points that might help you devise a solution.
You can put code in your _Layout, but I agree that you want to be careful about doing so. You could create a helper or partial view and have your _Layout call it so that it's executed for every action. Your helper/partial would need to execute the required logic and then return something. The problem that I have with this is it's a lot of overhead every request.
You could do an AJAX call after the page is loaded (as you suggested). This means that the page still loads quickly. The problem I have with this is that you're now dependant on Javascript. It's also potentially a little hacky(?)
What about storing the user's status (logged on/off) in a session/cookie and also providing a 5 minute expiry. You can use the Helper/Partial method from before or have some logic fire in OnActionExecuting (or similar). Your logic should check to see if the status has expired and then connect to the Facebook API to update the status. This has the advantage of low overhead (i.e. not checking again until 5 minutes has passed).
I don't know of your exact situation so I can't say what method, if any, is best.

Related

Page & Action wise Authorization Asp.Net Core Razor Pages

I have a requirement to configure the user's authorization per module per screen per action. For example, one user should be able to Create/Save WorkOrders in WorkOrder Module, but another user should only able to View/Delete WorkOrders. Similarly, a third user should only be able to View WorkOrders. This is an example of one screen. Now there are many screens in the application. Let's keep the actions same for all i.e. View, New, Update, Delete.
There is a reports module also, in which the user will create reports on the fly and add it into the application. So authorization is required here too. For example, a user can View/Print WorkOrder reports. But another user can only view reports. Let's keep the actions in reports only View & Print.
I am not sure Asp.Net Core built-in authorization is capable of this or not. What I have looked so far, it is not possible. Please correct me if I am wrong.
Now question is, how should I do this? I had a similar kind of requirement in a previously built application where I used database tables to store rights against each user and each screen. And upon log-in, I used to fetch that data, and then while loading the web page; I used to show or hide the relevant buttons & menus based on user's rights. But here in Asp.Net Razor Pages, the action method matters (If I'm not wrong), and certain functionality can be accessed via route. I am looking for some attribute-based solution.
I found this link with more or less above mentioned implementation using database tables and route URL to determine action name. So the URLs are saved in the database and on runtime they are checked and matched with the current URL and the user is authenticated.
Another link here, where the developer has used attribute-based filtering on action methods. But URL Routes are not being saved in the database or anywhere.
Are these the only & best solution to my problem? I have no problem implementing them, they look logical. But I just want to use the best available approach. Can anyone assist me with any other more suitable approach?

In IdentityServer4, how do you securely store the ReturnUrl?

I am developing an identity server 4 dotnet core application so this is as much as a dotnet question than and IDS4 question. One example of state I need to maintain between pages (login, signup etc...) is the returnUrl. The application I'm migrating from used to store it in a session variable but, as I understand, unless I run a persistent session strategy, this won't scale well.
So currently, I'm passing it around as a field in each View Model used by each view so it can be returned. Is this a sound approach? I'll be needing other fields to be passed around as well so I'm wondering whether this is a secure and logical way to do it.
So currently, I'm passing it around as a field in each View Model used by each view so it can be returned. Is this a sound approach?
Yes, how you choose to pass it around is up to you, I choose this same approach. You could use TempData, Sessions or even localStorage as an alternative. I think having it in the models (view models) is a good approach because you are explicitly specifying where you want the return url to exist, otherwise it might persist in context that you wouldn't want.
Now the security question because obviously you might be able to see the return url in the browser address field.
As part of Identity Server 4 setup you specify which return url's you are allowed to redirect back to, so I don't think there is any harm in having the users see the redirect url.
Something to consider is what if the user would share the url to someone else in the middle of the authentication process, would they be able to resume from that part of the process that the initial user has stopped? is this something you want in your app?
If you mean reliably instead of securely, write tests which will provide you with confidence that your code works.

"__RequestVerificationToken is not present" error when I can clearly see it in Developer tools

I'm trying to a CSRF protection to an existing MVC4 web application which uses DevExpress grids. I've added the Html.AntiForgeryToken() into the forms on the aspx pages (which contain ascx as partials containing the grids) and can see the __RequestVerificationToken and it's value clearly in developer tools when a save is called.
I've tried commenting out all my ValidateAntiForgeryToken attributes bar one - I went with the delete post method for simplicity (And also to eliminate the DevExpress grids messing with it) and I still keep coming up against this error:
There was a HttpAntiForgeryException
Url: http://localhost:54653/Users/Delete/f86ad393-0039-44e8-beed-a66dbab9266e?ReturnURL=http%3A%2F%2Flocalhost%3A54653%2FUsers
The exception message is
The required anti-forgery form field "__RequestVerificationToken" is not present.
Does anyone have any idea why this might be happening? Could it be that the error is non-descriptive and it's actually that the token doesn't match rather than that it doesn't exist? In previous answers to this question people just say "oh, you have to add the token," which is obviously not helpful here.
Are you submitting the form manually through Ajax? If that's the case, you need to pass the anti forgery token as another parameter with the name "__RequestVerificationToken".
Point 1 : Make sure if your application is has https secure protocol. Please load in https.
Point 2 : In case of DevExpress you have to call in the below pattern.
ViewContext.Writer.Write(Html.AntiForgeryToken().ToHtmlString());
After struggling with this for days I had a thought - maybe the browser is stopping the cookie being written. I did a search for dev servers and cookies not being written, and found that with Chrome and IE10 and up that there's problems writing the cookies.
I downloaded Firefox and tried it with that and it worked instantly. I then reapplied all the validate attributes to the all the controller methods and the all worked, every single one of them! Even the DexExpress postbacks seem to be working correctly.
I'll carry out more exhaustive testing, but for now, I think we're there.
Not exactly. If MVC AntiForgeryToken is already defined on page where you are using MvcxGridView and you want to protect grid actions you should send this token back to server during grid client side begin callback event.
settings.ClientSideEvents.BeginCallback = "function(s,e) { e.customArgs[\"__RequestVerificationToken\"] = $('input[name=\"__RequestVerificationToken\"]', $(s.GetMainElement())).val(); }";

Track last view with C# ASP.NET MVC

I don't have any code to show, because I'm not sure how to approach this. I am sending a user from one view to another where we will be doing CRUD OPERATIONS, I need to have a way of knowing what the last view I came to before the CRUD OPERATION so that I can send my user back to that view. I would also like to use this for redirection once someone has logged in. I want to have a way of setting the view I want them to get sent back to so that they can log in from any page on the site and it will remember that page instead of just dropping you on the home page.
I would accept a good tutorial as well, I'm pretty desperate to figure this out. SHoudl I just use ViewBag?
If you making <a></a> Through Html Helper then you globally set the querystring in function that can be later used for know the last view user visit.
As Balachandra mention you can use ReturnUrl inside the Request object.
Some other idea which can help you are
Request.Server["HTTP_REFERER"]
Request.UrlReferrer
A another simple algorithm to solve this issue is making JavaScript cookie to know what is current url. and last url. it's only take 2 url to remember in cookie.
When you want to know last referrer then you can easily look in user cookie to know the referrer.
If you want to know the url refeffer in inside Action then make a ActionFilter and just call this code
HttpContext.Current.Request.UrlReferrer.ToString()
In ASP.NET MVC we have TempData which used to pass Data from Views to Views. From this post http://www.rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications You can get better explanation.
This are enough Tricks to pass the data from Views to Views. For Example TempData will help you to store current url and you can get same information on next view. Remember that TempData is based on Session so it doesn't store the information for long time. For me TempData look perfect solution that you need to use for your own solution.
If you enable asp.net mvc authentication and try to browse any page in application, it will redirect user to login page with 'ReturnUrl' querystring parameter. This parameter holds the name of previous page from where user redirected from.
You can use similar approach even after login as well.

Need help fitting a design flow into REST

I'm having a bit of a trouble understanding how to fit a particular design flow I have into a proper REST architecture. Let me explain the flow:
I'm creating technical support website where users can submit ProblemRequests. On the front page, the user selects all the categories he's having trouble with and clicks "get help," which then redirects him to the next page where he fills out some forms to submit his request. Here are the pages:
Page 1 - Select Problem Categories
Page 2 - Fill out Problem Request
Page 2 basically acts like the NEW action for a ProblemRequest. The thing is each ProblemRequest depends on multiple ProblemCategories, so a nested route isn't going to work here. The next thing that comes to mind is sending in all relevant ProblemCategories ids as an GET param for the NEW ProblemRequest action, but I would rather not expose the IDs in the URL.
A Multi-Part form sort of comes to mind, but that involves making ProblemRequests have state, where some would be complete and others incomplete. I don't want to deal with the implications, because in reality this is a one page submission, not a very long-winded process.
What would work ideally is to override the NEW action for the ProblemRequests controller to respond to POST operations, but I don't know if this is considered bad programming practice. Is this a cardinal sin? Is it okay for me to change the NEW action to respond to POST instead of GET?
Please advise,
Thanks in advance.
Keep it simple. Is there any reason for the round-trip to the server? I'd just make the two "pages" a single page and maintain the state of the selected categories client-side.
Use a multi-step form: http://railscasts.com/episodes/217-multistep-forms
You can save the IDs in the session, and the model won't get saved in the DB until you are finished filling out the info. Works great for simple 2 or 3 step forms.
For more complex wizards you could use a gem like https://github.com/schneems/wicked