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

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.

Related

Store Paypal Payments Pro account information outside of Web.config

I am using the .NET SDK for Paypal Payments Pro. The sample application stores the API account credentials in the website's Web.config file. I'd like to be able to pull these credentials from the database, instead.
Some searching turned up this entry, which asks the same question: Edit Settings in web.config. Unfortunately, the accepted answer didn't address how to store the credentials elsewhere; instead, it showed how to programmatically modify the Web.config file.
Is there any way to specify the Paypal Payments Pro API credentials programmatically?
Thanks
Right now, PayPal .NET SDKs are designed to pick the API account credentials only from the configuration file. Perhaps, future version will support dynamic authentication.
Thanks
UDPATE
You should be able to re-write the ConfigManager class and the SDKConfigHandler class to retrieve the values from a database (not web.config).
ConfigManager retrieves the data and uses the SDKConfigHandler class to structure the data so other methods and classes can use it.
You'll find both classes in \PayPal_Merchant_SDK\Manager\.
ORIGINAL
After reviewing the SDK, it looks like all you have to do is specify the credentials with a new UserInfo object:
UserInfo User = new UserInfo("<user>", "<vendor>", "<partner>", "<password>");
You just need to populate user, vendor, partner, and password, so I see no reason why you cannot store those in a database and retrieve them as necessary.
The UserInfo object is passed as a parameter to the SaleTransaction constructor.
SaleTransaction Trans = new SaleTransaction(User, Connection, Inv, Card, RequestID);
It would seem that as long as you re-instantiate both the UserInfo object and the the SaleTransaction object after switching credentials, you should be fine.
The PayflowUtility.AppSettings seems to merely be a helper method for retrieving the values from app.config. From Line 87 of DOSaleComplete.cs:
Should you choose to store the login information (Vendor, User, Partner and Password) in
app.config, you can retrieve the data using PayflowUtility.AppSettings.
For Example:
App.Config Entry: <add key="PayflowPartner" value="PayPal"/>
String mUser = PayflowUtility.AppSettings("PayflowUser");
String mVendor = PayflowUtility.AppSettings("PayflowVendor");
String mPartner = PayflowUtility.AppSettings("PayflowPartner");
String mPassword = PayflowUtility.AppSettings("PayflowPassword");
UserInfo User = new UserInfo (mUser, mVendor, mPartner, mPassword);
Someone's forked the project at github to use a hashtable instead of web.config
https://github.com/paypal/sdk-core-dotnet/pull/2
This changeset allows for passing the PayPal configuration in
hashtable form to the PayPalAPIInterfaceServiceService. This grants
the ability to store config data in an external config file or
database rather than forcing the use of an app/web.config file. This
is especially useful for shared class libraries that perform PayPal
SDK operations which are utilized by multiple calling applications;
also the ability to store a large number of accounts in a database
rather than a config file is advantageous. Backwards compatibility for
existing app/web.config configurations is supported.

Configure ASP.NET SQL Membership Provider from Web Role setting

I have a Web Role that is using the ASP.NET SQL Membership provider. Currently the configuration is in the Web.Config file. I would like to configure the connection string as a Web Role setting instead of having it in the Web.Config. The main reason that I wan this is so that I can set up configurations on the azure project to publish to different hosted services (dev, qa, etc.) Right now, I have to manually edit the web.config each time I want to publish to a different service.
I have a couple ideas on how I might be able to accomplish this.
Write a custom membership provider that wraps the SQL provider and provides custom configuration to it.
Put something in the Web Role OnStart method to change the connection string in the Web.config file.
Has anyone done something like this before, or have recommendations on which option might be best, or have another idea on how to accomplish this?
The Windows Azure SDK allows you to have multiple service configurations per environment. But web.config modifications are a bit harder. In your case I would suggest you write some code (or a startup task) that reads the connection string from the service configuration and writes it to the web.config.
Andy's blog post 'Programmatically modify web.config on WebRole Startup' explains exactly how you can do this:
public override bool OnStart()
{
using (var server = new ServerManager())
{
// get the site's web configuration
var siteNameFromServiceModel = "Web"; // TODO: update this site name for your site.
var siteName =
string.Format("{0}_{1}", RoleEnvironment.CurrentRoleInstance.Id, siteNameFromServiceModel);
var siteConfig = server.Sites[siteName].GetWebConfiguration();
// get the appSettings section
var appSettings = siteConfig.GetSection("appSettings").GetCollection();
AddElement(appSettings, "deploymentId", RoleEnvironment.DeploymentId);
AddElement(appSettings, "internalEndpointPort", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints
.First(t=>t.Key=="InternalEndpoint1").Value
.IPEndpoint.Port.ToString());
server.CommitChanges();
}
return base.OnStart();
}

.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

File permissions with FileSystemObject - CScript.exe says one thing, Classic ASP says another

I have a classic ASP page - written in JScript - that's using Scripting.FileSystemObject to save files to a network share - and it's not working. ("Permission denied")
The ASP page is running under IIS using Windows authentication, with impersonation enabled.
If I run the following block of code locally via CScript.exe:
var objNet = new ActiveXObject("WScript.Network");
WScript.Echo(objNet.ComputerName);
WScript.Echo(objNet.UserName);
WScript.Echo(objNet.UserDomain);
var fso = new ActiveXObject("Scripting.FileSystemObject");
var path = "\\\\myserver\\my_share\\some_path";
if (fso.FolderExists(path)) {
WScript.Echo("Yes");
} else {
WScript.Echo("No");
}
I get the (expected) output:
MY_COMPUTER
dylan.beattie
MYDOMAIN
Yes
If I run the same code as part of a .ASP page, substituting Response.Write for WScript.Echo I get this output:
MY_COMPUTER
dylan.beattie
MYDOMAIN
No
Now - my understanding is that the WScript.Network object will retrieve the current security credentials of the thread that's actually running the code. If this is correct - then why is the same user, on the same domain, getting different results from CScript.exe vs ASP? If my ASP code is running as dylan.beattie, then why can't I see the network share? And if it's not running as dylan.beattie, why does WScript.Network think it is?
Your problem is clear. In the current implementation you have only impersonation of users and no delegation. I don't want to repeat information already written by Stephen Martin. I only want to add at least three solutions. The classical way of delegation which Stephen Martin suggests is only one way. You can read some more ways here: http://msdn.microsoft.com/en-us/library/ff647404.aspx#paght000023_delegation. I see three practical ways of you solving your problem:
Convert the impersonation token of the user to a token with delegation level of impersonation or to a new primary token. You can do this with respect of DuplicateToken or DuplicateTokenEx.
Use S4U2Self (see http://msdn.microsoft.com/en-us/magazine/cc188757.aspx and http://msdn.microsoft.com/en-us/library/ms998355.aspx) to receive a new token from the old one with respect of one simple .NET statement WindowsIdentity wi = new WindowsIdentity(identity);
You can access another server with respect of one fixed account. It can be a computer account on an account of the application pool of the IIS. It can be another fixed defined account which one will only use for access to the file system.
It is important to know which version of Windows Server you have on the server where IIS is running and which Domain Function Level you have in Active Directory for your Domain (you see this in "Active Directory Domain and Trusts" tool if you select your domain and choose "Raise Domain Functional Level"). It is also interesting to know under which account the application pool of the IIS runs.
The first and the third way will always work. The third way can be bad for your environment and for the current permission in the file system. The second one is very elegant. It allows control of which servers (file server) are accessed from IIS. This way has some restrictions and it needs some work to be done in Active Directory.
Because you use classic ASP, a small scriptable software component must be created to support your implementation.
Which way do you prefer?
UPDATED based on the question from comment: Because you use classic ASP you can not use a Win32 API directly, but you can write a small COM component in VB6 or in .NET which use APIs which you need. As an example you can use code from http://support.microsoft.com/kb/248187/en. But you should do some other things inside. So I explain now which Win32 API can help you to do everything what you need with tokens and impersonation.
First of all a small explanation about impersonation. Everything works very easy. There are always one primary token under which the process runs. To any thread another token (thread token) can be assigned. To do this one needs to have a token of a user hUserToken and call API ImpersonateLoggedOnUser(hUserToken);.
To go back to the original process token (for the current thread only) you can call RevertToSelf() function. The token of user will be received and already impersonated for you by IIS, because you so configured your Web Site. To go back to the original process token you should implement calling of the function RevertToSelf() in your custom COM component. Probably, if you need to do nothing more in the ASP page, it will be enough, but I recommend you be more careful and save current users token in a variable before operation with files. Then you make all operations with file system and at the end reassign users token back to the current thread. You can assign an impersonation token to a thread with respect of SetThreadToken(NULL,hUserToken);. To give (save) current thread token (user token in your case) you can use OpenThreadToken API. It must work.
UPDATED 2: Probably the usage of RevertToSelf() function at the end of one ASP page would be already OK for you. The corresponding C# code can be so:
Create a new Project in C# of the type "Class Library" with the name LoginAdmin. Paste the following code inside
using System;
using System.Runtime.InteropServices;
namespace LoginAdmin {
[InterfaceTypeAttribute (ComInterfaceType.InterfaceIsDual)]
public interface IUserImpersonate {
[DispId(1)]
bool RevertToSelf ();
}
internal static class NativeMethods {
[DllImport ("advapi32.dll", SetLastError = true)]
internal static extern bool RevertToSelf ();
}
[ClassInterface (ClassInterfaceType.AutoDual)]
public class UserImpersonate : IUserImpersonate {
public UserImpersonate () { }
public bool RevertToSelf () {
return NativeMethods.RevertToSelf();
}
}
}
Check in project properties in "Build" part "Register for COM interop". In "Signing" part of the project check Sign the assembly and in "Choose a strong name key file" choose <New...>, then type any filename and password (or check off "protect my key..."). At the end you should modify a line from AssemblyInfo.cs in Properties part of the project:
[assembly: ComVisible (true)]
After compiling this project you get two files, LoginAdmin.dll and LoginAdmin.tlb. The DLL is already registered on the current computer. To register if on the other computer use RegAsm.exe.
To test this COM DLL on a ASP page you can do following
<%# Language="javascript" %>
<html><body>
<% var objNet = Server.CreateObject("WScript.Network");
Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");
var objLoginAdmin = Server.CreateObject("LoginAdmin.UserImpersonate");
var isOK = objLoginAdmin.RevertToSelf();
if (isOK)
Response.Write("RevertToSelf return true<br/>");
else
Response.Write("RevertToSelf return false<br/>");
Response.Write("One more time after RevertToSelf()<br/>");
Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");
var fso = Server.CreateObject("Scripting.FileSystemObject");
var path = "\\\\mk01\\C\\Oleg";
if (fso.FolderExists(path)) {
Response.Write("Yes");
} else {
Response.Write("No");
}%>
</body></html>
If the account used to run the IIS application pool has access to the corresponding network share, the output will be look like following
Current user: Oleg
Current user's domain: WORKGROUP
RevertToSelf return true
One more time after RevertToSelf()
Current user: DefaultAppPool
Current user's domain: WORKGROUP
Yes
Under impersonation you can only access securable resources on the local computer you cannot access anything over the network.
On Windows when you are running as an impersonated user you are running under what is called a Network token. This token has the user's credentials for local computer access but has no credentials for remote access. So when you access the network share you are actually accessing it as the Anonymous user.
When you are running a process on your desktop (like CScript.exe) then you are running under an Interactive User token. This token has full credentials for both local and remote access, so you are able to access the network share.
In order to access remote resources while impersonating a Windows user you must use Delegation rather then Impersonation. This will involve some changes to your Active directory to allow delegation for the computer and/or the users in your domain. This can be a security risk so it should be reviewed carefully.

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