Asp.Net Authentication Module - c#

I have created an authentication module in ASP.Net but I do not want the logic in the authentication module to be executed if the resource is configured for anonymous access since the logic is expensive.
There are pages that require authentication in the same directory with pages that do not require authentication. I have no control over this. Is there an easy way to determine that a resource is configured to allow anonymous access prior to the URLAuthorizationModule?
Currently, I am doing the following which does "feel" right. Any help would be appreciated.
public static bool AllowEveryone()
{
bool rslt = false;
AuthorizationSection config = (AuthorizationSection)WebConfigurationManager.GetSection("system.web/authorization");
if (config.Rules != null && config.Rules.Count > 0)
{
AuthorizationRule r = config.Rules[0]; //doing this based on implementation of urlauthorization module in reflector...
if (r.Action == AuthorizationRuleAction.Allow && r.Users.Contains("*"))
{
return true;
}
//todo: check for allow anon ? case
}
return rslt;
}

I'm not sure how your code fits in with the Membership and Role provider system, but have you tried putting per-URL overrides in the web.config file?
<location path="MyAnonymousPage.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>

In a regular ASP.Net site this can be accomplished with the following code:
IPrincipal anonUser = new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]);
bool allowAnon = UrlAuthorizationModule.CheckUrlAccessForPrincipal(requestPath, anonUser, "get");
However, I am having problems getting it to behave as expected in SharePoint.

Related

How to debug this "value cannot be null. Parameter name: password" error?

Basically, I am trying to create an admin role (canEdit) that can add/remove products in the application. Analyzing the "IdentityResult Create" extension method I found out it has +1 override.
One has the parameters: manager, TUser user
The other has parameters: manager, TUser user, string password
This is an error I kept getting towards the end of the Wingtip Toys Microsoft asp.net tutorial. In my code which is identical to the tutorial except for the name of the Application (mine is gamestore as you see), I think I must use the 2nd method as the admin role has a password.
But I have tried different things and to understand and fix this by analyzing the metadata extensions for all those light blue classes and interfaces, etc you see, but I wasn't able to fix this at all.
Edit
I am adding code. The bolded line below is the erroring line.
namespace GameStore.Logic
{
internal class RoleActions
{
internal void AddUserAndRole()
{
// Access the application context and create result
variables.
Models.ApplicationDbContext context = new
ApplicationDbContext();
IdentityResult IdRoleResult;
IdentityResult IdUserResult;
var roleStore = new RoleStore<IdentityRole>(context);
var roleMgr = new RoleManager<IdentityRole>(roleStore);
if (!roleMgr.RoleExists("canEdit"))
{
IdRoleResult = roleMgr.Create(new IdentityRole { Name =
"canEdit" });
}
var userMgr = new UserManager<ApplicationUser>(new
UserStore<ApplicationUser>(context));
var appUser = new ApplicationUser
{
UserName = "canEditUser#gamestore.com",
Email = "canEditUser#gamestore.com",
};
**IdUserResult = userMgr.Create(appUser,
ConfigurationManager.AppSettings["AppUserPasswordKey"]);**
if(!userMgr.IsInRole(userMgr.FindByEmail("
canEditUser#gamestore.com").Id, "canEdit"))
{
IdUserResult = userMgr.AddToRole(userMgr.FindByEmail("
canEditUser#gamestore.com").Id, "canEdit");
}
}
}
}
Below is the config file for this Admin folder, but there is no password involved as you see..
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow roles="canEdit"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration>
Where do you expect
ConfigurationManager.AppSettings["AppUserPasswordKey"]
to get the password from? You did not put a value in the configuration file for it to read.
I have to say that it would be very strange to put the passowrd for a new user in the ap config file.
I mean you say 'see there is no password here', well exactly, so why is your code trying to read a password from there?

Asp.Net Role Based Authentication?

I want to redirect user based upon role.I can do it without using Forms Authentication but I want to do it with forms authentication. Following is my code:
Web.Config
<authentication mode="Forms">
<forms loginUrl="Forms/Login.aspx" defaultUrl="Member/Home.aspx">
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
Login.aspx.cs
protected void btnLogin_Click(object sender, EventArgs e)
{
members.memberEmail = txtEmail.Text;
members.memberPassword = operation.EncodePasswordToBase64(txtPassword.Text);
DataSet ds = operation.GetUsers(members);
if (ds != null)
{
int role = int.Parse(ds.Tables[0].Rows[0]["memberType"].ToString());
if (role == 2)
{
Response.Redirect("../Member/Home.aspx");
}
else if(role == 1)
{
Response.Redirect("../Admin/Home.aspx");
}
}
}
Here GetUsers function giving back the Dataset of members and I am checking role from DataSet and redirecting the user to respective home page. I am trying to accomplish same thing using forms authentication:
I have enabled the role manager in web config:
<roleManager enabled="true">
</roleManager>
I know, I am doing wrong. Can anyone guide me?

ASP.NET Directory Authentication

I have a .net 2.0 application using Forms Authentication with AD and have a directory for documents which has been configured using a web.config file -
<system.web>
<authorization>
<deny users="?"/>
<allow roles="Security Alerts - Admin"/>
<deny users="*"/>
</authorization>
</system.web>
When testing locally if I run the app and put the FQDN for a document /site/documents/Document1.pdf I am returned to the login page but when I have the site on a server I am able to open the PDFs without any problem. How can I force this so that if a user was to saves the URL of a document and tried to access it directly they would be forced to the login page to authenticate themselves first?
I have the same config for an ADMIN folder which includes aspx pages and works correctly and directs the users the Login page first, is it something to do with the doc type being a pdf as opposed to aspx pages.
Thanks in advance.
By default, .NET authentication does not work on static files such as pdfs.
You need to implement an HTTP Handler to serve your files if the user is authenticated.
It sound like your current authentication is set up and working correctly, so I won't go over the basics of setting that up.
Below is the relevant code which applies to your scenario taken from Kory Becker's helpful article here:
http://www.primaryobjects.com/2009/11/11/securing-pdf-files-in-asp-net-with-custom-http-handlers
You'll obviously have to alter the paths, namespaces and logic to suit your environment (e.g. IIS version) and/or specific file type requirements.
Step 1 - Create a FileProtectionHandler class which implements IHttpHandler
public class FileProtectionHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
switch (context.Request.HttpMethod)
{
case "GET":
{
// Is the user logged-in?
if (!context.User.Identity.IsAuthenticated)
{
FormsAuthentication.RedirectToLoginPage();
return;
}
string requestedFile = context.Server.MapPath(context.Request.FilePath);
// Verify the user has access to the User role.
if (context.User.IsInRole("Security Alerts - Admin"))
{
SendContentTypeAndFile(context, requestedFile);
}
else
{
// Deny access, redirect to error page or back to login page.
context.Response.Redirect("~/User/AccessDenied.aspx");
}
break;
}
}
}
public bool IsReusable { get; private set; }
private HttpContext SendContentTypeAndFile(HttpContext context, String strFile)
{
context.Response.ContentType = GetContentType(strFile);
context.Response.TransmitFile(strFile);
context.Response.End();
return context;
}
private string GetContentType(string filename)
{
// used to set the encoding for the reponse stream
string res = null;
FileInfo fileinfo = new FileInfo(filename);
if (fileinfo.Exists)
{
switch (fileinfo.Extension.Remove(0, 1).ToLower())
{
case "pdf":
{
res = "application/pdf";
break;
}
}
return res;
}
return null;
}
}
Step 2 - Add the following sections to your web.config file (with appropriate path/namespace modifications)
<httpHandlers>
...
<add path="*/User/Documents/*.pdf" verb="*" validate="true" type="CustomFileHandlerDemo.Handlers.FileProtectionHandler" />
</httpHandlers>
<system.webServer>
...
<handlers>
<add name="PDF" path="*.pdf" verb="*" type="CustomFileHandlerDemo.Handlers.FileProtectionHandler" resourceType="Unspecified" />
...
</handlers>
</system.webServer>

trying to get the username used to sign into the website

I'm using the following code to check the user's credentials and if successful I put them to make-request.aspx, but on make-request.aspx I want to check the value of the username they entered so I can show certain content.
Here's the authentication code:
foreach (string key in ConfigurationSettings.AppSettings.Keys)
{
dominName = key.Contains("DirectoryDomain") ? ConfigurationSettings.AppSettings[key] : dominName;
adPath = key.Contains("DirectoryPath") ? ConfigurationSettings.AppSettings[key] : adPath;
if (!String.IsNullOrEmpty(dominName) && !String.IsNullOrEmpty(adPath))
{
if (true == AuthenticateUser(dominName, userName, txtPassword.Text,adPath, out strError))
{
Response.Redirect("../make-request.aspx");// Authenticated user redirects to default.aspx
}
dominName = string.Empty;
adPath = string.Empty;
if (String.IsNullOrEmpty(strError)) break;
}
Everything works fine but I'm not sure how to get the username they entered into the form. Here's code that I've tried that is getting username of the machine username -- I think. Any help would be appreciated!
I've tried all three of these:
//string userName = Environment.UserName;
string userName = HttpContext.Current.User.Identity.Name;
//string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Here's the authentication/auth section of web.config:
<authentication mode="Windows" />
<authorization>
<allow users="*" />
<!--<deny users="*"/>-->
</authorization>
You are authenticating the user but not setting forms authentication cookie. Here's what you need to do:
FormsAuthentication.SetAuthCookie(userName, false);
Response.Redirect("../make-request.aspx");
Also make sure you have proper authentication/authorization set in your web.config. If you are not sure if it is setup correctly, share it here so we can take a look.
Set FormsAuthentication as below:
<authentication mode="Forms">
<forms loginUrl="Login.aspx"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
The HttpContext.Current.User.Identity.Name will work as long as the user is currently logged in when it is ran. In one of my sites, I use the following (written in VB):
Dim u As MembershipUser = Membership.GetUser(Membership.GetUserNameByEmail(HttpContext.Current.User.Identity.Name))
Tip: You can test if the user is already logged in by checking the value of HttpContext.Current.User.Identity.IsAuthenticated.
However . . .
. . . Using the current HTTP context is only necessary in content pages or web APIs. Alternatively, you can use MembershipUser u = Membership.GetUser(); from the master page, and then use u.Username to retrieve the username or u.ProviderUserKey to retrieve the GUID of the user.
If Session Is Nothing OrElse Session(Current_User) Is Nothing Then
udtGeneral = GetdoGeneralInstance()
susername = Request.ServerVariables("LOGON_USER").Split("\")(1).ToString()
'Either of these work i believe
susername = Request.ServerVariables(7).Split("\")(1).ToString()
'Dim susername1 = Request.Browser.Capabilities("extra").ToString.Split(";")(14).ToString.Split(":")(1).ToString
Session("ipAddress") = Request.ServerVariables("REMOTE_ADDR").ToString()
End If

Getting The Current User Name In ASP.NET Application

I am running a webpage that needs to be able to read the login id of the current user. Here is the code I am using:
string id = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Currently this returns the correct login but when I use it in this method:
protected Boolean isPageOwner()
{
string id = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
alert("User: " + id);
if (id.Equals(pageOwnerID))
{
return true;
}
if (accessPermission.ContainsKey(id))
{
return true;
}
return false;
}
the method returns false even though the id returned is identical to pageOwnerID. I'm really not sure which part of this I am having a problem with.
On a side note, my login id is of the form string1/string2 but the code retrieves it as string1 + string2 without the slash.
Any advice is appreciated.
Regards.
Try using this to retrieve the username....
if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
string username = System.Web.HttpContext.Current.User.Identity.Name;
}
It sounds like windows authentication is not being used - you need to disable anonymous access and enable windows integrated security.
Add this to your web.config...
<system.web>
<authentication mode="Windows"/>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
If you need the current logged in user's identity from within any layer (or Project in your solution) then use:
string userId = Thread.CurrentPrincipal.Identity.GetUserId();

Categories