ASP.Net - Using Basic Authentication without having Windows Users - asp.net

We have an ASP.Net web application running on IIS6 that manages its own database of users.
The site itself just allows anonymous access and all authentication/security is managed using our application itself.
We have a page that contains an HTML table of data that we import into Excel and is then used for Reporting purposes. The page currently has no security implemented.
We need to add security to this page so that should these spreadsheets fall into the wrong hands then the data cannot be "Refreshed" without supplying a username / password.
If I set this page to not allow Anonymouse access then I can use Basic/Windows authentication with Windows Users in order to secure this page. Then when Excel refreshes the data the password dialog box pops up.
The problem is that I need to be able to secure this page based on the Users within our database and they will not be Windows users. I also need to do it in such a way that allows Excel to manage the authentication which excludes any Form based authentication.
Anyone got any ideas? Is it possible to get IIS to look elsewhere for it's Basic Authentication?

Ok, so I've found two solutions to this problem. One thanks to Zhaph - Ben Duguid's answer which is an HttpModule that allows ASP.Net to fully manage the authentication.
The second solution, and the one that I am going with, is thanks to this question/answer.
HTTP Authentication (Basic or Digest) in ASP Classic via IIS
I've stripped this down and have a simple test harness that seems to be working well. In this example, instead of a database call, it merely checks that the username and password match and considers that authenticated.
using System;
using System.Text;
namespace AuthenticationTests
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string authorisationHeader = Request.ServerVariables["HTTP_AUTHORIZATION"];
if (authorisationHeader != null && authorisationHeader.StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
{
string authorizationParameters = Encoding.Default.GetString(Convert.FromBase64String(authorisationHeader.Substring("Basic ".Length)));
string userName = authorizationParameters.Split(':')[0];
string password = authorizationParameters.Split(':')[1];
if (userName == password) //Perform your actual "login" check here.
{
//Authorised!
//Page loads as normal.
}
else
{
Unauthorised();
}
}
else
{
Unauthorised();
}
}
private void Unauthorised()
{
Response.AddHeader("WWW-Authenticate", "Basic");
Response.Status = "401 Unauthorized";
Response.End();
}
}
}

As you've got a custom database of users, I'd recommend looking at building a quick membership provider that talks to your database schema.
MSDN has a good example on "How to: Sample Membership Provider".
You can then use the standard access control mechanisms of ASP.NET to lock down the page, require authentication, etc, along with controls like Login, LoginStatus and others to provide much of the UI you need.
Edit to add
A quick search found the following, which might help:
Web Service Security - Basic HTTP Authentication without Active Directory
Where Greg Reinacker presents "a fully working sample in 100% managed code demonstrating the use of HTTP Basic authentication, using a separate credential store (in this case, a XML file, although this would be easy to change to a database or LDAP store)."

I'm not an expert but I thought that the point of Basic was that it was Windows Authentication. Can you run a script to synchronise your DB users with your Active Directory?
If it's a corporate AD, you could consider having a second AD just for your app and synchronising users from both your corporate AD and your DB. If you don't need to synchronise passwords (e.g. build a pwd-mgmt page in your site) you could just use scripts or C# or something. If you want something more sophisticated with built-in password synchronisation, you could look at ILM 2007 (soon to be FIM 2010).

Is the page an .html file or an .aspx file?
If it's an .aspx, you should keep this page under anonymous access and check for authentication in the page logic itself

I've written a library named FSCAuth that may help with this. It trivially can be set up for just basic authentication without Active Directory. It will instead read your user data out of a database/file/wherever(there is even a memory-only UserStore)
It is BSD licensed at Binpress

Related

Implement a Simple Authorization Function in ASP.NET Without Using ASP.NET Identity

I'm building a simple CMS using ASP.NET MVC 5 and Entity Framework 6. I have 2 sites: Public and Admin. Public site to diplay all the content and Admin site to manage all the content.
I only need a single Admin account to handle all the content in the Admin site.
I'm thinking to use a session to keep the logged in user data and check for the session details when accessing an authorized page.
Keep the user data in a session.
var obj = db.UserProfiles.Where(a => a.UserName.Equals(objUser.UserName) && a.Password.Equals(objUser.Password)).FirstOrDefault();
if (obj != null)
{
Session["UserID"] = obj.UserId.ToString();
Session["UserName"] = obj.UserName.ToString();
return RedirectToAction("UserDashBoard");
}
Check before accessing an authorized page.
public ActionResult UserDashBoard()
{
if (Session["UserID"] != null)
{
return View();
} else
{
return RedirectToAction("Login");
}
}
So with this approach I wouldn't need to implement advance ASP Identity functions for the authorization.
Is this approach correct and would there be any downsides using this approach?
NEVER EVER EVER EVER EVER use session for authentication. It's insecure for starters, and it won't survive a loss of session (which IIS can kill at any time, for any reason). Session cookies are not encrypted, so they can be grabbed and used easily (assuming a non-encrypted link, even if you use HTTPS for authentication pages).
Another issue is that you are doing your authentication way too late in the pipeline. OnAuthenticate runs at the very beginning of the pipeline, while you action methods are towards the end. This means that the site is doing a lot of work it doesn't have to do if the user is not authorized.
I'm not sure why you are so against using Identity, the MVC basic templates already roll a full identity implementation for you. You don't have to do much.
The downside is that you have to write it all yourself anyway. You already need role-based authorisation and have to write cludges. Identity already have this implemented and tested for you. Also keeping information in session is not very secure.
And you don't need to implement much yourself anyway. Yes, there are lot of functionality that you'll probably won't need, but just don't use it.
Don't build your own authorisation system. Since you ask this question, you are probably not qualified enough to make it secure.

ASP.NET 3.5 Multiple Role Providers

I have an ASP.NET 3.5 application that I recently extended with multiple membership and role providers to "attach" a second application within this application. I do not have direct access to the IIS configuration, so I can't break this off into a separate application directory.
That said, I have successfully separated the logins; however, after I login, I am able to verify the groups the user belongs to through custom role routines, and I am capable of having identical usernames with different passwords for both "applications."
The problem that I am running into is when I create a user with an identical username to the other membership (which uses web.config roles on directories), I am able to switch URLs manually to the other application, and it picks up the username, and loads the roles for that application. Obviously, this is bad, as it allows a user to create a username of someone who has access to the other application, and cross into the other application with the roles of the other user.
How can I mitigate this? If I am limited to one application to work with, with multiple role and membership providers, and the auth cookie stores the username that is apparently transferable, is there anything I can do?
I realize the situation is not ideal, but these are the imposed limitations at the moment.
Example Authentication (upon validation):
FormsAuthentication.SetAuthCookie(usr.UserName, false);
This cookie needs to be based on the user token I suspect, rather than UserName in order to separate the two providers? Is that possible?
Have you tried specifying the applicationName attribute in your membership connection string?
https://msdn.microsoft.com/en-us/library/6e9y4s5t.aspx?f=255&MSPPError=-2147217396
Perhaps not the answer I'd prefer to go with, but I was able to separate the two by having one application use the username for the auth cookie, and the other use the ProviderUserKey (guid). This way the auth cookie would not be recognized from one "application" to the other.
FormsAuthentication.SetAuthCookie(user.ProviderUserKey.ToString(), false);
This required me to handle things a little oddly, but it simply came down to adding some extension methods, and handling a lot of membership utilities through my own class (which I was doing anyhow).
ex. Extension Method:
public static string GetUserName(this IPrincipal ip)
{
return MNMember.MNMembership.GetUser(new Guid(ip.Identity.Name), false).UserName;
}
Where MNMember is a static class, MNMembership is returning the secondary membership provider, and GetUser is the standard function of membership providers.
var validRoles = new List<string>() { "MNExpired", "MNAdmins", "MNUsers" };
var isValidRole = validRoles.Intersect(uroles).Any();
if (isValidRole)
{
var userIsAdmin = uroles.Contains("MNAdmins");
if (isAdmin && !userIsAdmin)
{
Response.Redirect("/MNLogin.aspx");
}
else if (!userIsAdmin && !uroles.Contains("MNUsers"))
{
Response.Redirect("/MNLogin.aspx");
}...
Where isAdmin is checking to see if a subdirectory shows up in the path.
Seems hacky, but also seems to work.
Edit:Now that I'm not using the username as the token, I should be able to go back to using the web.config for directory security, which means the master page hack should be able to be removed. (theoretically?)
Edit 2:Nope - asp.net uses the username auth cookie to resolve the roles specified in the web.config.

ASP.Net custom authentication with existing server

We have an existing user licensing server that is running via PHP. It allows for creation of users, checking if the provided username and password is valid, and updating a user.
We are creating a new ASP.Net website and want it to use this existing user PHP scripts/database to restrict access to portions of the ASP.Net website. Also there are web services that use the same login and password via basic authentication that we need to access as well from the ASP.Net server.
I am looking for a way for .Net to use the remote PHP scripts to validate login. And I need a way for the users login id and password to be available so I can use them to communicate with those existing web services from the ASP.Net server on their behalf.
Does anyone know how to go about getting this sort of thing done. Or any good tutorials or blogs?
Thanks!
It's possible to run PHP and ASP.NET on the same server, and even in the same web application. You can also create .NET code that runs before and/or after each PHP request (with an HttpModule).
PHP under IIS just has a separate HttpHandler that invokes the cgi-bin process.
If you want to call a PHP page from an ASP.NET page, one approach is to use Server.Execute() -- although web services would certainly be cleaner from an architectural perspective.
Beyond that, for the actual authentication/authorization part of your question, the approach depends on the specifics of your implementation. You can certainly do things like share cookies between PHP and .aspx.
unfortunatly they are different languages and php scripts cannot be used in an asp.net site. You would have to recreate your classes(scripts) but what you can do is use your existing database if its in mysql or any other. That's the best you would be able to do as far as I know.
If those PHP web services respect some industry standard such as SOAP for example, you can simply consume them by generating strongly typed client proxies. If not, well, then you still have the good old WebClient which allows you to send HTTP requests and read responses. It's as simple as:
using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "username", "john" },
{ "pwd", "secret" },
};
var result = client.UploadValues("http://foo.com/login.php", values);
// TODO: do something with the result returned by the PHP script
}
Have you tried using stored procedures instead of PHP scripts? That way you don't have to write multiple instances of the same code and it can be used in .NET and PHP.

ASP.NET authentication

when developing a login page i'm using the following method
protected void btnLogin_Click(object sender, EventArgs e)
{
if (Validateuser())
{
GetUserRoles();
Response.Redirect("Default.aspx");
lblMsg.Text = string.Empty;
}
else
{
lblMsg.Text = "Invalid User!";
}
}
just check if the user is valid.if valid redirect to a page else display a message.so why we have to use asp.net authentication types?
i've heard about windows,forms and passport authentication types.why we have to use them over the above method and whats the advantage of it.if possible please provide me some sample applications
The basic idea is that rather than you rolling your own security for a website, you should use established, generally accepted techniques and libraries. This allows you to take advantage of the work of security experts who would have been involved in the design and implementation of such authentication & authorization systems. Additionally, there will be a number of features that are already or will be available over time (e.g. support for Active Directory / LDAP, organizational units (OU)). You can take advantage of all of that will modifications to your code, rather than having to implement those features when your users demand them.
Over and above all this, publicly available implementations get used and penetration tested by a wide audience which will report bugs and weaknesses. These will typically get fixed quickly and patches will be issued on a regular basis.
You can read this article from 4GuysFromRolla.com that will give you a good understanding of ASP.NET security options.
One thing to keep in mind - Passport authentication is no longer available to the general public. It's for user by Microsoft only.
The code you shown is an old way of doing authentication. What if the user types the url of default.aspx directly ? How would you protect that ?
You need to learn latest ASP.NET 2.0 authentication basics:
http://www.eggheadcafe.com/tutorials/aspnet/009e2e5e-5a44-4050-8233-59a0d69844e8/basics-forms-authentication-in-aspnet-20.aspx

Protect some pages from direct access in ASP.NET

I have an ASP.NET page called admin.aspx that needs to be protected from direct access.
I want it to be accessed only when the user enter his name & password in another page called login.aspx.
I'm working in ASP.NET with Visual Basic .NET 2008, and I have no idea how to do it.
How can I do it?
The correct term for this behavior is Authorization
Some things I need to know beforehand:
Do you have your own Login / Logout Logic?
Are you using a custom User database / table?
If both of the above were answered with a yes: Have you read / heard something about Membership- and RoleProviders?
.NET has great built in mechanisms for solving this problem. It doesn't just offer great configuration possibilities, it is also very easy to implement!
Here is a very very detailed walk trough on the ASP.NET Membership Provider:
ASP.NET 2.0 Membership and Roles Tutorial Series
Even though it is using ASP.NET 2.0 and C#, it shouldn't really be that different on .NET3.5/4.0 and VB.NET
I found it :
In the login page ("login.aspx") do this :
Session("Name") = "Yes"
Response.Redirect("admin.aspx")
In the admin page ("admin.aspx") this :
If Session("Name") = "Yes" Then
'You can here display anything you want, or just leave it blank
Else
Response.Redirect("ErrorPage.aspx")
End If
You should check the user session first before loading your page:
protected void Page_Load(object sender, EventArgs e)
{
if (session == null)
{
// Just redirect to login page or no access page warning.**
}
if (!Page.IsPostBack)
{
//If your were logged in then you will access this page
}
}
You can handle it via Forms authentication. In your case you want to make sure that you restrict the access of admin.aspx so you can do so by giving that entry in web .config by specifying the location tag. Check out this site:
http://www.dnzone.com/go?60
HTH

Resources