I made really basic facebook application, which collect permission from user to post data. Some time ago (around New year) it worked fine.
I am using http://facebooktoolkit.codeplex.com, and my code looks like this:
public partial class Facebook : CanvasFBMLBasePage
{
protected void Page_Load(object sender, EventArgs e)
{
if(this.Api.Users.HasAppPermission(global::Facebook.Schema.Enums.ExtendedPermissions.publish_stream))
And at this moment I am having exception: parameter uid or session key required
As i understand, I should have some session defined by Facebook and CanvasFBMLBasePage should parse it, and make it possible to use application, but this is not happening.
My application settings (maybe I mis something):
Canvas Callback URL: http://www.domain.com/app/action/facebook.aspx?
Render Method: FBML
Also, I put my IP in server whitelist.
Thanks for help
Have you called the "ConnectToFacebook" method in the api before calling "HasAppPermission"?
Related
What is the best way to set up authentication against a custom database of users, in ASP.NET? My current setup is not great, and I am sure that there is a better way to do authentication, but all I can find are some articles that are seven or eight years old. My current setup is as follows:
Application uses the Windows username (via Windows Authentication), to work out whether a user is in a database of allowed users. This is done via a call to an Authenticate method in Page_Load.
If the user isn't in the allowed users, then the page redirects to a login screen.
The flaw with this method is that it calls:
Response.Redirect("~/login.aspx", false)
Which executes the entire body of the Page_load method. Is there a better way of doing authentication? Would something like custom Page classes, or HTTPModules do the job?
You could do your check earlier in the request, like in OnInit, or you could do something a little more robust, like implement your own membership provider: MSDN article / Video tutorial
Okay, so this is basically how I done it. I wrote this class that inherits from System.Web.UI.Page. I override the OnInit event and this is where the authentication happens (looks up the Windows username against the database of users). If the user doesn't get authenticated, isTerminating gets set to true, and the OnLoad event only runs if isTerminating is false. I tried leaving a Response.Redirect with the second parameter set to false on its own, but this still ran all the subsequent page events. (even with a call to HttpApplication.CompleteRequest())
public class BasePageClass : Page
{
private bool isTerminating = false;
protected override void OnInit(EventArgs e)
{
isTerminating = !AuthenticationManager.Authenticate();
base.OnInit(e);
}
protected override void OnLoad(EventArgs e)
{
if (!isTerminating)
{
base.OnLoad(e);
}
}
}
I have no idea whether not running the OnLoad event is the best thing to do, but it "seems" to work fine.
I have made a custom error page for my ASP.NET 4 application. I put the exception object in HttpContext.current.Session["CustomError"] but when the user is redirected to the error page HttpContext.current.Session["CustomError"] is null.
I do it in CustomError class constructor like this:
public CustomError(enExceptionType ExceptionType) : base(ExceptionMessage(ExceptionType)) {
HttpContext.Current.Session["CustomError"] = this;
}
when I step over the code Session["Error"] contains the error object.
any idea?
UPDATE:
I removed custom error page from web.config and added this to glabal.asax:
void Application_Error(object sender, EventArgs e)
{
if (Context.IsCustomErrorEnabled)
{
Response.Redirect("~/Error.aspx");
}
}
by stepping through this function I noticed that when an exception is thrown this function is called two time, the first time Session["CustiomError"] contains the error object but the second time its null.
Instead of using Response.redirect(URL) (which I assume you have in your code) use
Server.Transfer(URL)
or
Response.redirect(url, false)
Why Server.Transfer(url)?
Transferring to another page using
Server.Transfer conserves server
resources. Instead of telling the
browser to redirect, it simply changes
the "focus" on the Web server and
transfers the request. This means you
don't get quite as many HTTP requests
coming through, which therefore eases
the pressure on your Web server and
makes your applications run faster.
Source here.
Please let me know if one of these works for you.
UPDATE:
If you use a web config setting can you try adding ResponseWrite value to redirectmode var?
<customErrors mode="RemoteOnly" defaultRedirect="~/errors/GeneralError.aspx" redirectMode="ResponseRewrite" />
If this is still not working I suggest to implement this (I've done it in my application to log the errors in log files (for me as admin) and present a generic error to the user).
This solved the problem, but I would appreciate it if someone tells me why :)
void Application_Error(object sender, EventArgs e)
{
if (Context.IsCustomErrorEnabled)
{
Response.Redirect("~/Error.aspx");
**Server.ClearError();**
}
}
I want to change page content while it is going from the server because i need to add some advertisements inside the html elements that are advertisement holder.
protected void Application_PreSendRequestContent(object sender, EventArgs e) this is good but i couldn't get access to HttpContext . Should i, i don't know :)
But in this method:
protected void Application_EndRequest(object sender, EventArgs e) i could get the HttpContext but i couldn't find the server response in it.
How can i do this?
You might want to implement a HttpModule instead of global.asax. You can find an example of a module that manipulates the response in MSDN: Walkthrough: Creating and Registering a Custom HTTP Module
See also this page for some additional information (e.g. why a HttpModule instead of global.asax): HTTP Handlers and HTTP Modules Overview
To answer your comment: here are some reasons why to use a module instead of global.asax (have a look at the document linked above for more information):
You can implement much of the functionality of a module in the application's Global.asax file [...] however, modules have an advantage over the Global.asax file because they are encapsulated and can be created one time and used in many different applications.
In IIS 7.0, the integrated pipeline enables managed modules to subscribe to pipeline notifications for all requests, not just requests for ASP.NET resources.
You can enable/disable a module via web.config (without touching any code)
You should use a module whenever you must create code that depends on application events, and when the following conditions are true:
You want to re-use the module in other applications.
You want to avoid putting complex code in the Global.asax file.
The module applies to all requests in the pipeline (IIS 7.0 Integrated mode only).
protected void
Application_PreSendRequestContent(object
sender, EventArgs e) this is good but
i couldn't get access to HttpContext .
Should i, i don't know :)
You can always get access to the HttpContext for the current request by using HttpContext.Current
I want to save each request to the website. In general I want to include the following information:
User IP, The web site url, user-if-exist, date-time.
Response time, response success-failed status.
Is it reasonable to collect the 1 and 2 in the same action? (like same HttpModule)?
Do you know about any existing structure that I can follow that track every request/response-status to the website?
The data need to be logged to sql server.
Look in your web server logs.
How about IIS logs? they already have all the data items you listed so far
In BeginRequest Method you need to write the following code.
protected void Application_BeginRequest(object sender, EventArgs e)
{
//String s = HttpContext.Current.Request.Path;
//HttpContext.Current.RewritePath("Login.aspx");
String referrer = HttpContext.Current.Request.UrlReferrer;
String sourceIP = HttpContext.Current.Request.UserHostAddress;
String browser = HttpContext.Current.Request.UserAgent;
}
I'm working on an app using ASP.Net's form authentication. The client also makes RESTfull calls to the server (ExtJS components on front end).
We are using a custom HttpHandler for the service calls.
My problem is that anytime the anytime the authentication cookie expires my HttpHandler 's ProcessRequest method isn't called in order for me to check for the cookie's absence and redirect the user to log in again.
An example would be a user leaves a page open then comes back in 20 mins and clicks on a dropdown that is loaded asynchronously. The app just hangs never getting to my handler.
Any thoughts?
Highly suggest reading the section entitled "The Pipeline Event Model" in this MSDN magazine article: Securely Implement Request Processing, Filtering, and Content Redirection with HTTP Pipelines in ASP.NET.
In a nutshell, authentication is performed well before the request is handed over to ProcessRequest() in your HttpHandler. If you need to handle these cases, you will need to hook into the pipeline events (such as BeginRequest or Authenticate Request) and add your own handlers, like so:
public class EnableWebServicesModule :
IHttpModule
{
public void Init(HttpApplication app)
{
// register event handler
app.BeginRequest += new EventHandler(this.OnBeginRequest);
}
public void OnBeginRequest(object obj, EventArgs ea)
{
// Check if security works here by looking for the cookie or
// the user context.
}
...
}
For further reading on this fascinating and exciting topic, check Rich Strahl's walkthrough: A low-level Look at the ASP.NET Architecture