Web Forms Authentication from code-behind - asp.net

Within my application a privileged user can add/delete/update user roles (while also assigning them to specific users). The below excerpt shows a rule in my web.config file which allows the functionality of user blocking to only administrators:
<location path="block-user.aspx">
<system.web>
<authorization>
<allow users="Administrator"/>
</authorization>
</system.web>
</location>
What if I want to dynamically add or delete other roles besides the default one? Can this be done through code-behind?

If you want to restrict some pages to certain roles, you can do this in Page_Load function;
protected void Page_Load(object sender, EventArgs e)
{
if(!User.IsInRole(allowedrole))
{
Response.Redirect("block-user.aspx");
}
else
{
//do stuff
}
}

Related

IIS - How to redirect

How can I redirect www.example.com/foo to www.example.com\subdir\bar.aspx in IIS?
Note: a file called "foo" does not exist. I'd like to just redirect a URL with that pattern to the second URL
The best thing to do is not redirect, but instead use routing to map the URL to the web form. Then you keep a nice clean URL which is easy for users to type, and it looks better for search engines. We can accomplish that with the MapPageRoute method.
Add this to your Global application class (global.asax or global.asax.cs)
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("", "foo", "~/subdir/bar.aspx");
}
Alternatively, you can add this to your web.config to do a redirect.
<configuration>
<location path="foo">
<system.webServer>
<httpRedirect enabled="true" destination="/subdir/bar.aspx" httpResponseStatus="Permanent" />
</system.webServer>
</location>
</configuration>

Implement RedirectFromLoginPage with two defaultUrl in asp.net

I am Working on asp.net with two Login page for Staff and Student.When the Login is successful the user will be taken to WELCOME Page.But the problem is I have used RedirectFromLoginPage if the authentication is successful.Here is the code for that.
protected void Buttontbl1_Click(object sender, EventArgs e)
{
if (AuthenticateUser(Textusertbl1.Text,textpastbl1.Text))
{
FormsAuthentication.RedirectFromLoginPage(Textusertbl1.Text, CheckBoxtbl1.Checked);
}
else
{
errorlbl.Text="Invalid Username or Password";
}
}
I have given the defaultUrl as WelcomeStaff.aspx so if the authentication is successful the user is redirected to that.This is the code in Web.config file
<authentication mode="Forms">
<forms loginUrl="SelectUser.aspx" defaultUrl="welcomeStaff.aspx"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
So,I need the following to be implemented,
I want the same for another login.
-If the authentication is successful the user must be redirected to DefaultUrl="WelcomeStudent.aspx"
Its working fine for One Login Page.But I don't know how to implement for two aspx pages
So,Can we have two defaultUrl for two aspx file? Is there any other way to implement?Iam new to asp.net.Plz help.Thanks in advance
The way I usually deal with that kind of situation is configure that app to return to a redirect page (ex : redirection.aspx) that will check if the user is authenticated and if so, will redirect the user to another page based on is role. ex :
if (User.Identity.IsAuthenticated)
{
if(User.IsInRole("Student"))
{
Response.Redirect("WelcomeStudent.aspx");
return;
}
else if(User.IsInRole("Staff")
{
Response.Redirect("welcomeStaff.aspx");
return;
}
}
//For any other situation, return to login
FormsAuthentication.RedirectToLoginPage();
I hope this will help you.

Stopping the unauthorized users from redirecting to pages after writing urls in address bar

Whenever the user clicks logout button he is redirected to login page then he cannot go back by clicking back button.... but if he knows the url of any page even unauthorized page.he is able to access that page..I need to do is that he cannot access any page by typing urls..Plz help
You need to configure your web-app with Form authentication. Other alternatives are to use Session or Cookies.
You can put one session variable at the login page, insert some value only when the user gets to any page only via login page. And check for that session value in every page load, if the value not matches redirect to login page again.
Use the session variable in the page_load:
protected void Page_Load(object sender, EventArgs e)
{
Session["loggedin"] = "false";
}
... and check the login event. If user has pressed the login button then set the session variable "true".
protected void btnOK_Click(object sender, EventArgs e)
{
Session["loggedin"] = "true";
......
......
}
When the page is redirected to another page then check the status of the session variable
in page load event.
try
{
if (Session["loggedin"].ToString() == "false")
{
Response.Write("<script> alert('Session Expires! please login first'); </script>");
Response.Redirect("login.aspx");
return;
}
}
catch (Exception er)
{
Response.Redirect("login.aspx");
}
Sir please write the code in Web.config
<system.web>
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
protection="All"
timeout="30"
name=".ASPXAUTH"
path="/"
requireSSL="false"
slidingExpiration="true"
defaultUrl="default.aspx"
cookieless="UseDeviceProfile"
enableCrossAppRedirects="false" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
This code will prevent entering url in address bar without login.

ASP.Net - How can I allow imported script files be viewed by unauthenticated users when using Forms Authentication?

I'm using ASP.Net and forms authentication. When a user is directed to the Login Page I get a JavaScript error:
Message: Syntax error Line: 3 Char: 1
Code: 0 URI:
http://localhost:49791/login.aspx?ReturnUrl=%2fWebImageButton.js
This is because I am using a Custom Image Button in a separate Web Control Project control that adds a ScriptReference to the page:
public class WebImageButton : LinkButton, IScriptControl, IButtonControl
{
protected override void OnPreRender(EventArgs e)
{
// Link the script up with the script manager
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
if (scriptManager != null)
{
scriptManager.RegisterScriptControl(this);
scriptManager.Scripts.Add(new ScriptReference("<snip>.WebImageButton.js", "<snip>"));
}
base.OnPreRender(e);
}
}
If I add the following rule into my Web.Config, then the file is successfully imported:
<location path="WebImageButton.js">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
This isn't very good as I have a number of custom controls that do the same thing, and I don't particularly fancy authenticating each of their js files individually.
Is there no way that I can declare that all imported script references should be allowed? I tried authorising the WebResource.axd file in-case that allows it, but the page itself (when rendered) physically references the WebImageButton.js file.
The ideal scenario would be something like the following:
<location path="My.WebControlLibraryProject.Controls">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Is there any way to achieve this without listing each file?
EDIT: Just to be clear, these script files are in another project and are not in my actual web project. I know how to declare the location paths of directory paths to include a large number of files in one wack, but I can't figure out how to authenticate automatic script references, which are from embedded resources.
Is the WebImageButton.js an embedded resource? As I've seen, you had implemented IScriptControl. Thus, you must return all of script references on the IScriptControl.GetScriptReferences. I think an embedded resource never be authorized. I use some of custom controls in different situation and don't have any problem. I'm wondering that script manager references to WebImageButton.js directly, and not in form of .axd file. So, I think the problem is arising from your resource file.
public class WebImageButton : LinkButton, IScriptControl, IButtonControl
{
protected ScriptManager ScriptManager
{
get
{
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
if (scriptManager == null)
{
throw new System.Web.HttpException("<snip>");
}
return scriptManager;
}
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
this.ScriptManager.RegisterScriptControl<WebImageButton>(this);
}
#region IScriptControl Members
public System.Collections.Generic.IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
yield break;
}
public System.Collections.Generic.IEnumerable<ScriptReference> GetScriptReferences()
{
yield return new ScriptReference("<snip>.WebImageButton.js", "Assembly Name");
}
#endregion
}
This is just a guess - have you tried putting in a wildcard in the location path? Perhaps something like < location path="*.js">?
You can specify a generic location and put all your scripts there so that all the scripts that don't require authorization will pass. You just need to change the path to whatever folder you want it to be and put the scripts there.
That will work for not only scripts, but other resources as well, such as images, style sheets, etc.

Determine if user can access the requested page?

I have an ASP.Net website with multiple roles, each with access to a separate directory (i.e. admin users can access /admin, shoppers can access /shop etc), using a shared login page. If someone visits the login page with the return URL set to a directory they do not have access to (e.g. a shopper visits /login.aspx?returnurl=/admin/index.aspx), the user can authentice successfully (the login credentials are valid), but they end up back at the login page (they don't have access to the page they've requested).
How do I pick this up, so I can display a message do the user?
UrlAuthorizationModule.CheckUrlAccessForPrincipal()
is what you need to use to test user access to a location (page or folder) ( http://msdn.microsoft.com/en-us/library/system.web.security.urlauthorizationmodule.checkurlaccessforprincipal.aspx )
I ended up doing this in the page_load event of the login page:
if (User.Identity.IsAuthenticated)
{
LoginErrorDetails.Text = "You are not authorized to view the requested page";
}
The thinking being, if an authenticated user ends up at the login page, they have either been sent their as a result of trying to access an page they are not authorized to view, or they have authenticated and then manually gone to the log in page (unlikely).
A further action would be to send the user to the relevant home page whenever they visit the login page, if they are already authenticated.
One approach would be to override OnLoad of your aspx forms and check if the authenticated user is allowed access to the resource based on the role. So you create a BasePage.cs (in which you define a class BasePage which inherits from System.Web.UI.Page) for example from which all your Forms (aspx) inherit, in which you do this:
protected override void OnLoad(EventArgs e)
{
InitializeSitemap();
if (SiteMap.CurrentNode != null)
{
if (!UrlHelper.IsAnonymousAllowed(SiteMap.CurrentNode) && (!HttpContext.Current.User.Identity.IsAuthenticated || !UrlHelper.IsAccesible(SiteMap.CurrentNode)))
{
// You can redirect here to some form that has a custom message
Response.Redirect("~/Forms/Logout.aspx");
return;
}
}
base.OnLoad(e);
}
Then in your UrlHelper class you need that IsAccessible function used above:
public static bool IsAccesible(SiteMapNode node)
{
bool toRole = false;
foreach (string role in node.Roles)
{
if (role == "*" || HttpContext.Current.User.IsInRole(role))
{
toRole = true;
}
}
return toRole;
}
Here is IsAnonymousAllowed in case you wondered:
public static bool IsAnonymousAllowed(SiteMapNode node)
{
return node[AllowAnonymousAttribute] != null ? bool.Parse(node[AllowAnonymousAttribute]) : false;
}
If you have different directories and you are using asp.net authentication it is very easy.
All you need is to put web.config file in each directory and define roles which can access files in that directory like this:
<authorization>
<allow roles="shoppers"/>
<deny users="?"/>
</authorization>
You can get more details from this article on MSDN
You can set all in main web.config like this:
<!-- Configuration for the "sub1" subdirectory. -->
<location path="sub1">
<system.web>
<httpHandlers>
<add verb="*" path="sub1" type="Type1"/>
<add verb="*" path="sub1" type="Type2"/>
</httpHandlers>
</system.web>
</location>
<!-- Configuration for the "sub1/sub2" subdirectory. -->
<location path="sub1/sub2">
<system.web>
<httpHandlers>
<add verb="*" path="sub1/sub2" type="Type3"/>
<add verb="*" path="sub1/sub2" type="Type4"/>
</httpHandlers>
</system.web>
</location>
</configuration>
This is from this article on MSDN :)
EDIT:
In your page load method do this:
if(!User.IsInRole("shopper"))
{
lblNoAccess.Visible=true;
lnkHome.Url="PATH_TO_HOME_PAGE_OF_THIS_ROLS";
}
Hope this helps you!
You can redirect him on the index page, telling him that he cannot access that page;)
Well, why don't you catch the directory in the login page? If the login page can determine which directory the user is trying to access, maybe they can get redirect to the right page based on role. If someone tries to go to /admin, and authentication succeeds, you can check if they do have access there. If not, you can either redirect to basic landing page indicating they do not have access or you redirect them to the role's landing page.
EDIT:
You could probably do the redirecting in the LoggedIn event of the control.
One other option is to set a session variable when you're checking rights, and displaying that on the login page.
So you could do:
if(!User.IsInRole("shopper"))
{
session("denied") = "You don't have access to shop";
response.redirect("/login");
}
Then in the login page:
if ( session("denied") != "" ) {
message.text = session("denied");
session("denied") = "";
}

Resources