Introduction
Hello people, hope you are doing great J. While working on my personal website, I came across a simple requirement. It was little tricky to override the conventional method of login in website. After a couple of days of research, I finally developed my own solution for it. I think there is plenty of room for tweaking in my code, so if anyone has a better approach, please do let me know.
Background
I asked this question on CodeProject few days ago here which stated that I have a website containing various links redirecting to various pages. Out of those pages, some are Authenticated links (requiring user to login to see it) and some un-authenticated links (which are free to all, anyone can see it). I am using SQL Membership with forms authentication in my website. Clicking the authenticated link redirects the page to Login page.
I wanted to override this functionality by staying at the same page and showing a modal popup. This means that if you click on an Authenticated link, you will not be redirected to login page; instead a modal login popup will show on the current page. You login inside the popup and then get redirected to the respective authenticated page. This functionality will work on any page inside the website without any fixed login page.
Using the Code
To start with, I have configured the web.Config to let the application know which files require authentication and which ones don’t. Below is the XML snippet from the code attached in the article:
<location path ="UnAuthenticatedFiles">
<system.web>
<authorization>
<allow users ="*"/>
</authorization>
</system.web>
</location>
<location path ="WelcomeForm.aspx">
<system.web>
<authorization>
<allow users ="*"/>
</authorization>
</system.web>
</location>
Now apart from the file and folder mentioned in the snippet above, everything else needs to pass through authentication. Calling any other page will redirect to login page.
Note: In the web.Config, I have not mentioned the LoginUrl
as there is no fixed login page. User can login on any page as there is login popup.
Next I added the Global.asax file.
Application_Error
method tracks the application errors. I used this to track when page redirects to login page. Below is the code snippet:
protected void Application_Error(object sender, EventArgs e)
{
if (Request.QueryString["ReturnUrl"] != null)
{
if (Request.QueryString["ReturnUrl"].Contains("aspx"))
{
bool val = UrlAuthorizationModule.CheckUrlAccessForPrincipal
(Request.QueryString["ReturnUrl"].ToString(),
HttpContext.Current.User, "GET");
if (val.Equals(false))
{
if (Request.UrlReferrer.AbsolutePath.Equals
(Request.QueryString["ReturnUrl"]))
Response.Redirect("WelcomeForm.aspx");
else
Response.Redirect(string.Format("{0}?ReturnUrl={1}",
Request.UrlReferrer.AbsolutePath, Request.QueryString
["ReturnUrl"].ToString()));
}
else
if (Request.Url.AbsolutePath.Contains("login.aspx") &&
Request.QueryString["ReturnUrl"].Contains("WelcomeForm.aspx"))
Response.Redirect(Request.QueryString["ReturnUrl"].ToString());
}
}
}
When RedirectToLoginPage()
is called, it redirects to login page using “ReturnUrl
”. In the above code, I check if Return URL is present and is an aspx file (as it comes with favicon.ico for the first time application is run).
Next, I use the function “UrlAuthorizationModule.CheckUrlAccessForPrincipal
” as it determines whether the user has access to the requested file. It returns Boolean value (true
/false
). Using the value (if true
, requires login), I redirect the request to the same page where it came with ReturnUrl
of the requested page (page which required authentication).
In my case, I am using MasterPage
so I have handled it on the Page_Load
of Master page. Code on master page load is as below:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Request.QueryString["ReturnUrl"] != null)
{
bool isFreeToAccess =
UrlAuthorizationModule.CheckUrlAccessForPrincipal
(Request.QueryString["ReturnUrl"].ToString(),
HttpContext.Current.User, "GET");
if (isFreeToAccess.Equals(false) || Request.QueryString
["ReturnUrl"].Contains("WelcomeForm.aspx"))
{
LoginPopupExtender.Show();
}
}
}
}
Here, I have to perform the same checks as in global.asax and if the CheckUrlAccessForPrincipal returns “true”, I show the popup.
As the creating of modal login popup is not in the scope of the problem statement, I am skipping that, however, you can find that in the code sample attached in the article. It is pretty simple to do.
So the final screen looks like below when the authenticated link is clicked:
Apart from that, normal links (un-authenticated links) continue to work normally. This is just a kind of cosmetic change to the application, in case you need it.
Points of Interest
I have attached a sample code which has the following credentials:
- User ID – Guest
- Password – 123456!1
History
- 15th December, 2010: Initial post