Facebook ASP.NET MVC App with multiple controllers - c#

I am using the Facebook C# SDK to develop an iframe Facebook application.
I looked at the example and find this piece of code to do authorization in a controller:
namespace Auth_And_Allow.Controllers
{
[HandleError]
public class HomeController : Controller
{
[CanvasAuthorize(Perms = "user_about_me")]
public ActionResult Index()
{
FacebookApp fbApp = new FacebookApp();
if (fbApp.Session != null)
{
dynamic result = fbApp.Get("me");
ViewData["Firstname"] = result.first_name;
ViewData["Lastname"] = result.last_name;
}
return View();
}
}
}
But what should i do if my app is using a lot more then one controller?
Should i use the same authorization code in all controllers or is there another way? (I know it will work that way but right now i am searching for best practices to build facebook apps)

The CanvasAuthorize attribute will ensure that your user is logged in and has the appropriate permissions. You dont need to check this again by checking if the Session is null. Additionally, the CanvasAuthorize attribute (like the regular Authorize attribute) can be applied to you controllers as well as your actions. I would just do something like this:
[CanvasAuthorize(Perms = "user_about_me")]
public class FirstController : Controller {
}
[CanvasAuthorize(Perms = "user_about_me")]
public class SecondController : Controller {
}
Make sure you use the Controller extensions named CanvasRedirect accessed by this.CanvasRedirect inside a controller with the Facebook.Web.Mvc namespace referenced. These redirect helpers will ensure that you redirect correctly and dont "lose" the user's session.

Related

Use [Authenticate] attribute in MVC controller using sessions to authorize users?

I have been searching for similar solutions online but everything seems overcomplicating, currently, I have a UserController that I only want users that are logged in to access, my current solution involves using if statements however I was wondering if it's possible to use the [Authorize] attribute and apply it to methods or the entire controller perhaps?
public class UserController : ASessionController {
public UserController (IAmazonDynamoDB dynamoDbClient, DynamoDBContext dynamoDbContext) : base(dynamoDbClient, dynamoDbContext) {
}
// [Authorize]
public IActionResult Index () {
// check session variable
if(!UserIsLoggedIn()){ /*redirect to sign in*/ }
return View();
}
}
Perhaps I am not understanding if this is the purpose of the Authorize attribute? Thank you in advance.
You can use the Authorize attribute on endpoints and / or the Controller itself
It will force the User to be authenticated to again access to the decorated item.
In addition you can also restrict it to authenticated users with a given or multiple roles like in the example
[Authorize(Roles = "Administrator")]
public IActionResult Index()
{
...
}
[Authorize(Roles = "Administrator,Guest")]
public IActionResult NotAnIIndex()
{
...
}
But you should read the Microsoft Documentation tuturial

How to redirect all pages in my mvc asp.net web app except for one role?

I work with asp.net c# mvc framework. I need a way to 'turn-off' my web app for all users except administrator (i. e. all pages should return to something like "The application is closed" for all the roles except Admin).
I already create a button in order to save the status of the web app (ON/OFF) in a DB.
Do I have to check on each page the status of the application ?
Is-it possible to have a global redirection except for one role ?
I don't know how to properly do this global closure. Any suggestions are welcomed.
I can think of three approaches to check and do a redircet
An HttpModule hooked into the appropriate, post-authorisation event. Presumably PostAuthorizeRequest of HttpApplication.
In your "global" (Global.aspx.cs) subscribe to that same event.
An MVC Action filter, overriding OnActionExecuting. (Ensure you make it global, to avoid needing to apply to every controller: add to GlobalFilters.Filters in your Application_Start.)
Of these 3 is part of MVC, but is much later in the pipeline (much more work will have been done, to be thrown away when the filter fails).
Use of a module is controlled by configuration which would make is easier to switch on and off.
option 2 is likely easiest to implement, but I would tend to prefer the modularity that 1 gives.
You can accomplish your requirement with the help of custom filters shown below :-
[CheckUserRole]
public class YourController : Controller
{
public ActionResult YourAction()
{
}
}
public class CheckUserRoleAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Get the User Id from the session
// Get Role associated with the user (probably from database)
// Get the permission associated with the role (like Read, write etc)
// if user is not authenticated then do as :
filterContext.Result = new RedirectToRouteResult(new
RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
}
}
Did you tryActionFilterAttribute ?
Here is a basic example:
Your controller:
[IsAdmin]
public class YourController
{
}
Your attribute
public class IsAdminAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if () // Check that your user is not an Admin and that your application is "turn-off"
{
filterContext.Result = new HttpStatusCodeResult(403); // or whatever you want
}
}
}
Add [IsAdmin] on top of all your controllers.
You can write in all other Controllers which are used as follows..
public class HomeController : Controller
{
public ActionResult Index()
{
if (User.IsInRole("Administrator"))
return RedirectToAction("PagetoRedirect");
else
return RedirectToAction("CommonPagetoShowApplicationAsClosed");
}
}
Or
Action Filter, you can create on your own and look for named action like IndexRolename

Lock Down ASP.NET MVC App Administration Site to LocalHost only

I have an ASP.NET MVC website that I would like to add a small administration page to. The issue I have is that I will be deploying this all over and I will not have SSL available. I am OK with requiring the administrator to remote desktop and use the local browser to perform the administration.
Can this be done? I would basically like to get the same behavior as <customeErrors mode="RemoteOnly" /> except for my administration pages. Can I do this via web.config some how?
Request.IsLocal is your friend.
http://msdn.microsoft.com/en-us/library/system.web.httprequest.islocal.aspx
You can use that to check that a request is coming from the local machine.
Custom Attribute
You could then extend this to be a custom attribute, but that might be overkill. If that is the route you choose this is a good example that does something similar:
Custom Attributes on ActionResult
MVC3 onwards allows you to set an attribute at Controller level, rather than Method too, so you could lock access to the entire controller responsible for the admin pages.
I did it by writing a custom attribute, like this:
public class IsLocalAttribute : AuthorizeAttribute
{
public bool ThrowSecurityException { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isLocal = httpContext.Request.IsLocal;
if (!isLocal && ThrowSecurityException)
throw new SecurityException();
return isLocal;
}
}
Basic usage on an entire controller:
[IsLocal]
public class LocalOnlyController : Controller
{
public ActionResult Index()
{
return View();
}
}
or on a specific method:
public class SomeController : Controller
{
[IsLocal]
public ActionResult LocalOnlyMethod()
{
return View();
}
}
If you want to throw a security exception instead of a 302 redirect:
public class SomeController : Controller
{
[IsLocal(ThrowSecurityException = true)]
public ActionResult LocalOnlyMethod()
{
return View();
}
}

How can I redirect to different views on authorization failure?

While using mvc intranet template with domain authorization, how can I redirect to some certain error page on authorization failure depending on the controller?
So, I have a controller class:
[AuthorizeWithRedirect(Users = #"user")]
public class MyController : Controller
{
...
}
By default I'm not redirected anywhere. I see only a blank page, if I open the page under another user. The issue is that I want the request to be redirected to different pages for different controllers if the authorization fails. That is, one page for MyController, another page for other controller, etc.
I know I could derive from AuthorizeAttribute and override HandleUnauthorizedRequest method. But I can't make it work:
public class AuthorizeWithRedirect : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext context)
{
UrlHelper urlHelper = new UrlHelper(context.RequestContext);
context.Result = new RedirectResult(urlHelper.Action("MyErrorPage"));
}
}
I get an error, saying that the specified url is not found, while MyErrorPage.cshtml does present in the Views\Shared folder.
EDIT
[Authorize(Users = #"user")]//should be redirected to ErrorPage1
public class MyController1 : Controller
{
...
}
while
[Authorize(Users = #"user")]//should be redirected to ErrorPage2
public class MyController2 : Controller
{
...
}
That is, different error pages for different controllers on one and the same authorization failure
The AuthorizeWithRedirect looks good.
But MVC is complaining that you do not have right action method.
The view is not an issue here. The controller and action method is.
Try something like this:
context.Result = new RedirectResult(urlHelper.Action("Test", "Redirect"));
With present TestController with an public action method Redirect.
Use the Handle Error Data Annotation on top of your login method
[HandleError]
public ActionResult Login()
{
//your action method
}

How to make pages automatically use https when using asp.net mvc 2.0

I am wondering how do I make pages automatically use https? Like if a user types in
http://www.mysite.com
It should take them right to the login page. However I have SSL required on this page(when they try to login).
So how could I make it so it would change it to
https://www.mysite.com even if they don't type it in themselfs?
You can use the RequireHttpsAttribute on the appropriate controllers and/or actions:
[RequireHttps]
public class SecureController : Controller
{
public ActionResult YourAction()
{
// ...
}
}
// ...
public class YourController : Controller
{
[RequireHttps]
public ActionResult SecureAction()
{
// ...
}
}
i believe you are looking for
[RequireSsl(Redirect = true)]
there is a discussion you can find here
SSL pages under ASP.NET MVC
Edited:
found this link might be useful
http://blog.stevensanderson.com/2008/08/05/adding-httpsssl-support-to-aspnet-mvc-routing/

Categories