Thursday, February 17, 2011

Dell WebCam and WebEx problem


I recently had fun trying to get the integrated Dell WebCam on an E6410 to work with WebEx. Turns out that by default the software runs in Capture mode. At the bottom right if you change the drop down to IM mode, then WebEx can use the camera.

Monday, February 14, 2011

How to Set Up AD FS 2.0 to SSO to Salesforce using SAML 2.0

Project:
Set up Microsoft AD FS 2.0 on my Windows 2008 R2 Active Directory to allow my users to authenticate to Salesforce.com using their domain accounts using SAML 2.0. We'll be using Federated Authentication and not delegated authentication which requires you to code your own web service.

Introduction:
On paper, Single Sign-On (SSO) looks fairly simple and very logical and can lull you into a false sense of confidence. In practice, it requires a lot of planning, preparation, and some knowledge of sessions, authentication infrastructure, packet capture, encryption, and sometimes alcohol. If you're more of an administrator and less of a programmer, you'll also notice how closely the lines between the two are blurred when you work with these products. There's a lot of articles out there on using several 3rd party IDPs to SSO to the force.com suite but I had trouble finding stuff for AD FS 2.0

Prerequisites:
A working Active Directory, preferably 2008 or higher.
A server or virtual machine that can run AD FS 2.0, preferably 2008 or higher and joined to your domain.
An active Salesforce.com account. They do recommend using a developer account for the initial setup and testing of SSO.
A valid SSL certificate that's trusted on the Internet. I use a wildcard certificate personally.
A DNS host record for your new AD FS. For this tutorial, I'm using samlportal.example.com
If you're using a firewall (which you should) between your AD FS and the internet, then you'll need to publish inbound SSL to it. Preferably with no authentication required.
If you want to set up a AD FS Proxy in a DMZ, then a second server or virtual machine will be required. For that, you'll need port 443 open from the proxy AD FS to the internal AD FS and 443 open from the internet to your proxy AD FS. The proxy server does NOT have to be domain joined.

Federation Service Name notes:
Try to avoid using your internal DNS AD name, and do not name it the same as the server's host name. You really want this name to be unique. This name will also have to be resolvable on the Internet since you'll need an A record for it and an SSL certificate.

Setup:
First download AD FS 2.0 to your server.
Install the IIS role on your server.
Add your SSL certificate to IIS (IIS manager under Server Certificates) and bind it to 443.
Test the server to make sure SSL is working.
Only AFTER you have the SSL settings right, then proceed to install AD FS 2.0
Install AD FS 2.0 and choose the "Federation Server" option.
Then run the AD FS 2.0 Federation Server Configuration Wizard to Create a new Federation Service.
Now you have a decision point, if you've only got a handful of users you can just do a stand-alone install. If you plan on having hundreds to thousands of users on this, then you can set up a Farm which will allow you to have multiple servers. Note: This option uses Windows Internal database (aka SQL express effectively). If you want to utilize an existing SQL DB server, you have to install using the command line.
Next the installer will detect your SSL certificate. If it doesn't, something's wrong with your IIS configurations.
Click Next
It'll install now and give you a list of success/failures. Warnings are generally not a problem and often occur if you're reinstalling AD FS.
If you get an SPN registration error, you'll have to update it manually from the command line. Substitute the following using your federation id and the account you're running AD FS as a service under.
setspn -S host//samlportal.example.com ADFSserviceAcctName

After that's done, go into the AD FS 2.0 console, click Service, right click on Service and choose Edit Federation Service Properties.


Confirm that the Federation Service name, etc all match what you have on your DNS A record and your SSL certificate. Copy down your Federation Service Identifier.

Then go under Certificates and Export a copy of your Token-signing certificate. Now we'll jump over to Salesforce as we can't proceed without data from them.

Next go into your salesforce account, then Setup, then on the left Security Controls, then Single Sign-On settings. This next bit of configuration came from a forum post from "Da G Man" on the thread: http://social.msdn.microsoft.com/Forums/en/Geneva/thread/2fc66b27-966c-49e5-891e-6e7e404e001d (Yeah, forums are great).

Choose Edit, then change the SAML drop down to 2.0.
For the Issuer, enter in your Federation Service Identifier. In this example, it was http://samlportal.example.com/adfs/services/trust
And yes, that is http and not https. And it is CASE-Senstive.
Choose User ID Type: Assertion contains User's salesforce.com username
Choose User ID Location: User ID is an Attribute element.
Enter Attribute Name: mail
Then click Save.

Now you can click on the Download Metadata button. Copy this file to your AD FS server.

Next on your AD FS server, go to Trust Relationships>Relying Party Trusts and add a new Relying Party Trust.
Under Data Source, choose Import data about the relying party from a file and choose your file that you downloaded from Salesforce.
Name it something. (This name will display on your user's login portal)
Choose the Permit all users option.
Click Next.
Click Finish.
Right-click on the relying party trust and choose Edit Claim Rules.
Name the claim something.
Choose Active Directory for the Attribute Store.
Choose E-mail Addresses for the LDAP Attribute and type in mail for the Outgoing claim Type.

Click OK, then OK.
Now make sure you have a user in salesforce whose username field matches the primary email address of a user in your active directory. Also make sure that this user is not an Administrator in Salesforce as by policy SSO supposedly doesn't work for those.

Now it's time to test. After much searching I figured out what URL I was supposed to use and I've provided it below:

(yes, it is https and it has no bearing on your Federation service identifier being http)


At this point the IDPInitiatedSignOn page should have loaded. If it didn't, then you've got a configuration issue. Otherwise you should be at a page that gives you the option to either log on or log on and go to salesforce in one step.

So now you've (hopefully) got the IDP initiated sign on part working! At some point you'll notice that you're still able to log in with your old login and password if you go to the salesforce site directly. Apparently the only way to fix that is to first switch to using their My Domain feature.



Once you're provisioned your domain, then log off, then back on using your new domain URL which will be in the form of yourdomain.my.salesforce.com

After that's set up, if you go back into Single Sign-On Settings and enter in an Identity Provider Login URL and Save your site will now force all visitors to use Single Sign-On. Now the URL is tricky and I found one that works but I can't promise it's the 'correct' one but it works and that'll do for now.
The above URL is comprised of my my SSO provider's IDP signon page plus a '?" then loginToRp= and then your salesforce domain name.

For further troubleshooting you may want to install a header capture program like Fiddler to help you debug your setup.

Feel free to comment if you have any corrections or suggestions and I'll integrate them into this howto.

Additional Notes:
There's a fun bug in Firefox where it'll prompt you endlessly for credentials. Workaround is here:

If you want to provide the Identity Provider Logout URL you can use:
https://samlportal.example.com/adfs/ls/?wa=wsignout1.0 (yeah, it's a legacy method but seems to work)

Useful Links:

Good forum post that answers the my domain SSO question.







Sunday, February 13, 2011

Powershell - search folder hierarchy for names matching a pattern from a file and copy them.


So I had a request this week for a quick script that could search a folder structure for filenames for patterns that matched strings inside of a text file and then copy them to another folder. All the files had long complicated filenames so they needed an easy way to search through them. If it was *nix I'd just use Perl but since it was for Windows Powershell's the right way to go.

the text file contained strings like
00xy569e
TRs3002010
00xy589f
00xy589s

# Gnawgnu - 2/2011
# Searches filenames in a folder structure for
# patterns provided via text file

# Files to be Searched.
$srcFolder = "D:\filestobesearched"

# Destination of file copy.
$dest = "d:\CopyMatchesHere"

# List of patterns to look for.
$srcFile = "d:\matchlist.txt"

# Read in matchlist from text file.
$matchlist = Get-Content $srcFile
foreach ($match in $matchlist) {
$a = gci -r -i *$match* $srcFolder
foreach ($c in $a) {
# Change to move-item if needed
copy-item $c $dest
}
}