Creating folders using DirectoryEntry - directory

I am writing an ASP.NET (C#) application to create users for my domain. It also has to create folders and shares on a separate file server. I have so far been able to accomplish my task using
System.IO.Directory.CreateDirectory to create the folders,
a ("WinNT://fileserver/lanmanserver") DirectoryEntry to create the shares.
Unfortunately, my ASP.NET application has to run with impersonation on to create the folder. I don't like that. I would like to know if there is a way to create a folder on the file server using a DirectoryEntry object since i can pass the needed credentials to its constructor. Or, alternatively, is there a way to pass credentials to Directory.CreateDirectory?
Thanks in advance.
Here is the current code, just in case
strPath = "\\myServer\D$\newDir";
Directory.CreateDirectory(strPath);
using (DirectoryEntry deFS = new DirectoryEntry("WinNT://myServer/lanmanserver"))
{
using (DirectoryEntry deSH = deFS.Children.Add("newDir$", "fileshare"))
{
deSH.Properties["path"].Value = "D:\\newDir";
deSH.Properties["description"].Value = "My Stackoverflow sample share";
deSH.CommitChanges();
}
}

I don't believe you should be using DirectoryObject for that purpose, it wasn't made for such an access. But here's a trick you could be using to make impersonation easier. Create an impersonator class, which would implement IDisposable, something like this:
public class Impersonator : IDisposable
{
public Impersonator(userid, password)
{
... LogonUserEx();
... DuplicateToken();
... Impersonate();
}
public void Dispose()
{
... RevertToSelf();
}
}
then you would be able to do this:
using(new Impersonator("myaccount", "password"))
{
... do stuff that requires impersonation
}

As far as I know you have two options: impersonate a user that has permissions to create the directory on the remote share or give the permissions to the default user that runs asp.net services.
What is wrong with that? You are accessing a non-default resource on your network and the default privileges dont allow you to do that. It's pretty much like a regular user account trying to write on a network share.

The DirectoryEntry class has a constructor which take username and password as input. Have you tried this?
See documentation at Microsoft

Related

Where the vales like Userid and passwords are stored in SSO of BTDF

I have a query regarding BTDF SSO config setting. I am beginner with BizTalk.
I am looking for SSO storage where credentials are stored and retrieved from SSO. I have built-in app located at C:\Program Files (x86)\Deployment Framework for BizTalk 6.0\Framework\DeployToolsork\DeployTools
Could anyone tell me how to store and retrieve from existing SSO config like SSOSettingsEditor which is the default provided by BTDF.
Using BTDF, you can store your configurations as provided in SettingsFileGenerator.xml in BizTalk SSODB. BTDF automatically store your configuration if IncludeSSO property is set to true in btdfproj file.
If you have provided your credential details in SettingsFileGenerator.xml file then only you will find them in SSODB.
You should use SSOSettingsEditor to retrieve or make changes to the configurations. In SSOSettingsEditor, type in your application name and press enter.
Refer to link: BTDF IncludeSSO
BTDF provides a library for modifying SSO Settings that it uses. The method is uses is slightly different from the default Microsoft sample SSO client, so take care regarding which one you're using.
Per that link, the class provides these methods:
namespace SSOSettingsFileManager
{
public static class SSOSettingsManager
{
public static void WriteSetting(string affiliateApplication, string propertyName, string propertyValue);
}
}
It should be fairly straightforward to call that method once you've added a reference to the SSOSettingsFileReader.dll in whatever C# project you have generating your password or updating it, i.e.
string newPassword = GenerateMyPassword();
SSOSettingsFileManager.SSOSettingsManager.WriteSetting("MyApplicationName", "Password", newPassword;);
You could also look at the source of how he's doing it if you want to implement the method yourself.

Entity Framework DB Model First

I've created a fresh ASP.NET Web Forms model, with authentication pre built. I've then run through the following link
http://msdn.microsoft.com/en-us/data/jj206878
and created an entity framework from my exisiting database.
Ok, so far so good, however, when i fire up the project and click Register, the user created is still being inserted into a local db in the App_Data folder.
Why is this, and how can I ensure that all new users are pooled / created in my own database?
Probably because your DbContext is using built-in connection string. You can specify which connectionstring from your web.config to use when you initialize it in constructor like so.
public class MainDataContext : DbContext
{
public MainDataContext() : base("Name=NameOfConnectionString") { }
// public DbSet ...
}
Change you Default Connection String at Web.config/App.config with credentials of your own database.
Hope following link will help you:
http://hgminerva.wordpress.com/2013/09/21/how-to-create-the-asp-net-membership-tables-in-your-own-database/

.NET Web Service that takes email id as input and searches the Active Directory?

How to write a .NET Web Service that takes email id as input and searches the Active Directory to see if that user exists and returns a flag. I have an userID and Password that is used to query AD. Please describe how to do this and what else do I need?
Using WCF, you can achieve this fairly easily.
Step 1 - define a service contract
This defines your operations that you want, including the parameters they might need. Not knowing what exactly you might need, I just guessed and came up with something like this:
using System.ServiceModel;
namespace SearchAD
{
[ServiceContract]
public interface ISearchADService
{
[OperationContract]
bool EMailAddressExists(string emailAddress);
}
}
Step 2 - implement the service class
This means adding the "meat" to the bone (the service contract) - this is where you actually do what you're trying to do:
using System;
using System.DirectoryServices.AccountManagement;
namespace SearchAD
{
public class SearchADService : ISearchADService
{
public bool EMailAddressExists(string emailAddress)
{
// establish the Active Directory domain context to search in
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", userName, password);
// define your "query-by-example" user to search for
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.EmailAddress = emailAddress;
// instantiate the searcher to find that user
PrincipalSearcher findUserByMail = new PrincipalSearcher(qbeUser);
// search for the user - did we find one?
UserPrincipal userByEmail = findUserByMail.FindOne() as UserPrincipal;
return userByEmail != null;
}
}
}
Of course, in this setup - you'll need to get your domain name, the user name and the password (for querying Active Directory) from somewhere - a config file, constants in your service class - whatever works for you!
With this, you basically have your WCF service that takes an e-mail address and searches Active Directory for a user account matching that e-mail address. If found, true is returned - false otherwise.
Now, with your WCF service, you now only need to know how to host it (in IIS or self-hosting), and how to create clients for it to use the service - but that's just very basic WCF know-how, you shouldn't have any trouble finding the necessary infomrmation and tutorials, if you don't have that know-how already !
The mechanism used to search Active Directory is the System.DirectoryServices.AccountManagement namespace, which is part of .NET 3.5 and newer. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement

What is the most unobtrusive way to add a layer of security for a private beta of website?

Let's say I have an ASP.NET site (MVC in this case) that uses Forms authentication and a typical membership system. The site allows both authenticated and anonymous users.
When I release the site as a private beta I want to add another layer of security on top of the application, like superuser's simple password system, for example. Once a user has passed this layer of security, I still want my forms authentication/membership system in place so beta testers can view the site as authenticated or anonymous users.
What's the most unobtrusive way to achieve this? I'm looking for the easiest solution that will require the least amount of new or modified code. E.g. I don't want to modify every controller to check for a special cookie. There must be a better way...
There's a very similar question here, but it seems the site in question (once public) will only serve anonymous requests, so it doesn't necessarily compare to my situation. This answer suggests ServerFault used some cookie system, but there are no further details about how it might have been implemented.
Implement security at server level, in IIS and add the accounts/passwords in Active Directory of Windows running the IIS server.
You won't need to change any of the code.
Well, I know you don't want to modify your current controllers but here's what I did for a similar behaviour.
I've created a custom ActionFilterAttribute that I've given to every controller that requires to have that specific access check. You can have something like this :
public class CheckBetaAccess : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
if (!canAccess) {
filterContext.Controller.ViewData["someViewData"] = "some text";
filterContext.Result = new ViewResult {
ViewName = "the-view-anonymous-users-should-see",
ViewData = filterContext.Controller.ViewData
};
filterContext.Result.ExecuteResult(filterContext);
}
}
}
Then I decorated my controllers :
[CheckBetaAccess]
public class SomeController : Controller {
//....
}

ASP.Net - Using Basic Authentication without having Windows Users

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

Resources