Search This Blog

Saturday, October 13, 2012

My persistent website 401 error

This is a reminder to myself.

I work in an NT environment with multiple domains (e.g. domainA, domainB, and domainC) where one domain ("domainC") trusts the other two domains.

I keep my IIS7 website in domainC and want users in any of the domains to be able to access it using their domain's credentials.

I make sure to disable anonymous access on my website and enable integrated windows authentication so that users will come into the website using their current credentials.  

The roadblock I experience each time is that I'll set up the website and test it using an account in domainC and all will be well.  During final testing I go over to domainB or domainA, log in, and try to get into the website and run into a "401" error. 

I always do this:  I'll go back to the website and try and reset permissions to the website's directory to allow "domainA\Everyone" and "domainB\Everyone" to have access, but for some reason I won't be able to.   I'll remark again that this works in my personal devlab but not in the client's environment.  I'll remember hearing that there's some sort of firewall blockage on LDAP calls between domains in this environment.

I'll try to create a domain local group in domainC and add the domainA\Everyone and domainB\Everyone groups into a local group I can give website rights to, but that won't work either.

I'll get frustrated here and start Googling and 4-5 hours will disappear as I learn how little I really know about security (and pursue several blind-alley solutions proposed by some other clueless bloggers).

I'll then spend another hour dicking around with every setting conceivable on my website, and then create a small sample "WhoAmI" website that just returns the current user's credentials.  Setting security on this test website, I'll turn off anonymous access, turn on nt authentication, and then give the local group WEBSERVERNAME\Users all rights to the website and discover that I can now access it from all the trusted domains.

The lesson here is to start by giving the WEBSERVERNAME\Users local group basic rights to the website just to get started.

This has cost me several hours to recreate twice -- Note to self:  don't do this again.

Friday, August 3, 2012

Searching a list<string> with case insensitivity

A lot of my web methods generate a list of strings from different sources that I want to quickly scan using the ".contains()" method.

Unfortunately the default method is case sensitive and, since I get information from different sources with differing casing-methods, my code will miss matches with slightly different casing.

string findMe = "String2Find"; 
List someStrings = new List{"one", "Two", "string2FIND", "Three"}; 
Console.WriteLine someStrings.contains(findMe);
 ==== Console === 
(false)
 ================ 

The bad solution is to go thru the list using .tolower() to lowercase all the members and compare each one against the comparator -- with the advent of LINQ there's a new overload for the method which allows comparisons without regard to case: 

string findMe = "String2Find"; 
List someStrings = new List{"one", "Two", "string2FIND", "Three"}; 
Console.WriteLine someStrings.contains(findMe, StringComparer.OrdinalIgnoreCase); 

==== Console === 
(true) 
================ 

I couldn't find this in the standard MSDN locations but it popped out at https://nickstips.wordpress.com/2010/08/24/c-ignore-case-on-list-contains-method/#comment-801

Friday, July 27, 2012

Learning WCF - Port contention issues during debugging

When working through exercises from the MSPress book on WCF for .NET 3.5 and from Bustamente's "Learning WCF" I ran into an issue when "self-hosting" WCF services in a console application.

One self-hosting example featured a solution with two projects:  1) a WCF service ("library") project and 2) a console app used to host the WCF service in the library project.   Each had an "app.config" file in it indicating that it wanted to use port 8080 under the local host URL:

... snip ...  <host> <baseAddresses> <add baseAddress="http://localhost:8080/NetStarCommandService" /> </baseAddresses> </host> ... snip ...

The solution built fine but when trying to run it presented this error message:

"HTTP could not register URL http://+:8080/NetStarCommandService/.  Another application has already registered this URL with HTTP.SYS"

If I changed the port number in either of the app.config files the code would run fine.

The problem turns out to be with a Visual Studio 2010 feature I was unaware of.  When you start a solution which has a WCF service in it Visual Studio will quietly start the WCF hosting service for the WCF service before running the code in the solution -- this causes the library project and the WCF hosting service to grab the port first and then prevent the self-hosting console code from running on that port.

The solution is very simple:  Right-click the WCF service project (the "library" project) in the solution, bring up its properties, and take a look at the "WCF Options" tab on the properties screen.  Uncheck the "Start WCF host when debugging another project in the same solution" checkbox and the project should run correctly.

Monday, June 25, 2012

Getting started with WCF - A Security Issue

Most of the free documentation I've been reading on WCF starts with a first "Hello World" application you try and create with WCF wherein you set up a contract, service, and host and then develop a client to call that host which returns a simple text string (e.g., "Hello WCF").

Most of this free documentation came out when WCF was first introduced, before the introduction of the Vista OS and Windows 7, and implicitly assumes that you're coding under credentials with admin rights on your machine.

The first roadblock I ran into, then, was a security access violation with an error message that read like:

"HTTP could not register URL http://+:800/.  Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkID=70353 for details).

Having run into this sort of issue before my immediate response was to try running the binaries under my machine's sysadmin account, but it still didn't work.

It turns out that listening on an HTTP port is considered a restricted operation in MS post-XP OS's, so if you want to do this using your standard dev account you'll need to explicitly elevate its rights to include listening on specific HTTP ports.  The NETSH command to do this for me was:

netsh http add urlacl url=http://+:8000/user=graperpc\dgraper

You can then check the current status of listening rights by entering:

netsh http show urlacl

Friday, April 27, 2012

Extremely slow response with a VS2010 solution

I copied a solution from my dev environment into a production environment and noted an extreme decrease in responsiveness ... e.g., a five second delay between a keypress and its appearing on the screen; 30 seconds plus to go from designer view to code view, etc.

The solution was pretty simple (although it destroys all my breakpoints) -- delete the SUO file for the project so that VS2010 has to build a new one.  Once that was done, performance was normal.

Tuesday, March 6, 2012

Converting everything in a file to lowercase with GVIM

To do it as a "replace":

:%s/[A-Z]/\L&/g

The obverse (to convert all to uppercase):

:%s/[A-Z]/\U&/g

Or, simply type:

ggVGu

Friday, November 4, 2011

Error 1001. The specified service has been marked for deletion

During windows services development there are periods during the final deployment process where I'm installing and uninstalling services pretty rapidly on a server and I occasionally run into this message: "Error 1001. The specified service has been marked for deletion." This error message will cancel the installation and, if you Google around for cures to this problem, the general consensus is to reboot the system.

The systems I work on require extensive permissions from a lot of people/departments to reboot, bringing development to a halt, so I found an easier way to get around the problem. It turns out that the error message is actually complaining that "services.msc" is currently open (in my case, I've left the server manager app open to list current service statuses), so stopping this process (again in my case, simply closing server manager) allows the service to be installed.