Tuesday, November 27, 2007

The problem with IIS6 that I have been curious about but up until today never needed a solution for.

The problem I am talking about is that with the IIS 6.0 UI you cannot set a host header on a SSL port for a domain.  You can live a long and happy life with a 1-cert-per-server config but with the case of a wildcard cert (one covering all subdomains of the domain it was purchased for) you really want to be able to take advantage of these extra subdomains.

Consider an example from a server below.  The two sites that are highlighted belong to the same domain - Lets call the red one www.MySite.com and the blue one shop.MySite.com.  There is a wildcard cert installed on the machine for *.MySite.com.

The first one is easy.  Install the cert and assign it to the site.

Setting this on subsequent sites on the same box is where you get the problem.  It can be done, and it isn't hard, you just have to know the trick!

The trick is the adsutil.vbs script that is included when you install IIS.  The default path to find these scripts is: C:\Inetpub\AdminScripts.

The process for assigning a host header for SSL to all subsequent sitess is:

  1. Don't assign a SSL port number to the second site.  Leave it on port 80 for now
  2. Open a command window and change to the path with adsutil.vbs.
  3. Run the following command:  cscript.exe adsutil.vbs set /w3svc/<site identifier>/SecureBindings ":443:<host header>"   In our example above the <site identifier> is replaced with the Id of the blue site, 1023406912, and the <host header> is replaced with shop.MySite.com
  4. adsutil will assign port 443 to the site, you do not need to reset IIS

TechNet has a rundown of all the things you can do with adsutil.vbs and IIS6, so check it out.  But don't get too attached - the Metabase is not showing up for IIS 7!

Listening To: The Boatman's Call, Nick Cave and the Bad Seeds

Tuesday, November 27, 2007 6:32:41 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [1]  | 
 Tuesday, November 06, 2007

I got this message again this morning and I am so sick of it!

Only 16 chars?  O RLY?  What if my dog's name is more than 16 chars long?

Further investigation of the JS source reveals that other error messages include:

Password can only contain letters and numbers

I am always talking to people about password policy and no wonder people are confused.  So much good guidance out there is buried under so much rubbish.

Compare this to the other user experience that is becoming more common:

Much better!  There was a time when it would be appropriate to explain why the second case is better... but in this day and age it should be obvious.  It is all about coercing people to do good passwords until they are made obsolete in the future.

Since Version 1.0.60731.0 of the ASP.NET AJAX Control Toolkit there has been a quite good Password Strength control available to the ASP.NET platform.  Everyone else (like my first, deliberately anonymous example) can just Google it!  There are plenty of samples available.

One that I liked was at Gerd Riesselmann's blog, where he shares (GPL) a simple example suitable for learning how this is done.

What do you think?  Is there any excuse for giving poor password guidance in 2007?

Tuesday, November 06, 2007 9:37:32 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, July 19, 2007

This is the third of my posts about group policy for web developers [part 1] [part 2], and today's post is a from-the-trenches tail about how you can get 401.1 Access Denied as a result of applying group policy.

Mad props to Jimmie Russ and his post Access Denied 401.1 goes away temporarily after IISRESET, as it was his post that sorted my problem today.

As you will see in his post, it is possible to push out User Rights Assignment policies via a GPO that can define the following rights:

  • Log on as a service
  • Log on as a batch job
  • Allow log on locally
  • Access this computer from the network

The above list may not be complete, but it was these four that caused a problem in my IIS environment.

Two tell-tail signs that this is your problem:

  1. If you run the always awesome AuthDiag utility and it reports that certain local accounts (like IUSR_*) have rights missing, specifically the ones listed above.
  2. When you view the User Rights Assignment in Local Security Settings
    • The above four rights are locked (have a little lock icon instead of the "blue 1s and 0s icon") and are not able to be edited.
    • The above four rights are not granted to our local accounts (again IUSR_* et al)

Again, it may not always be exactly those four - what you are looking for are policies that will not allow your IIS accounts (as listed in the AuthDiag results) to log on.

If I had my time again, I would have cranked up the failed security events and listed them here, but my servers are working again and I like it that way so this can be left as an exercise to the reader :-)

As Jimmie said, the solution is to have these rights not pushed down to your web servers.  This can be by not applying them in your Default Domain Policy, or by putting your web servers in a seperate OU blocking policy inheritance.  If you're not sure, consult an expert.

Thursday, July 19, 2007 4:39:09 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, June 27, 2007

Today's post is about a nifty little trick that I have seen done with search text boxes on sites over the years and I decided that it had to be in my toolbox too.

What we are going for is a search box that looks like this when the page loads:

...and looks like this when the user clicks into it:

This technique seems to mostly be applied to search boxes, and I can see the benefit in that.

The post that follows is the amalgum of many VS-A's

To get this done, it is a bit of CSS to style up the inactive and active state for the text box, and a tiny bit of Javascript to tie it together.  I'm using the term active and inactive not in any technical sense, just to describe the two styles that are applied to our text box in response to the user activity.

(assuming the rest of the page is a drab #f0f0f0 in colour...)  These are the two style rules that we are using in the images above:

.inactiveSearchBox
{
    background-color: #f0f0f0;
    border: solid 1px #ffffff;
}

.activeSearchBox
{
    border: groove 1px #d9d9d9;
    background-color: #ffffff;
}

The markup for the input box is then as follows:

<input type="text" class="inactiveSearchBox" id="SearchStrng" 
   value=" Search Here"

   onFocus="this.className='activeSearchBox'; if(this.value==' Search Here')this.value='';" 
   onBlur="if(this.value=='')this.value=' Search Here';this.className='inactiveSearchBox';"
/>

As you can see it all happens in the onFocus and onBlur events of the textbox.  When the text box gets the focus it sets the class to be our activeSearchBox style and clears our standard text.  The onBlur event restores the default value if the user did not enter anything and sets our style back to the inactiveSearchBox style.

Glossary:

VS-A, n. View Source, followd by an "Ah!". 
See also: VS-****.

Listening to:  Former co-workers :-)

ASP.Net | CSS | Geeking Out! | UX
Wednesday, June 27, 2007 11:32:32 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [1]  | 
 Wednesday, June 13, 2007

This is the second post on Group Policy for web developers.  Part 1 was about managing the local Intranet Zone for your AD network.  This post will be based on a similar scenario.  Specifically, when issuing certificates from a local Certification Authority, like Microsoft Certificate Services that ships in Windows Server 2003.

Modern browsers give you a more pretty warning system than they did last year when you view a site that do not chain back to a Trusted Root CA.  This is still an important warning and we don't want to condition people into just clicking yes every time they see it.

The first thing you will need to do (and like the last post, a certain degree of domain administrative Godness is required...) is get the CA's certificate from the CA.  Using Microsoft Certificate Services, you want to choose the option highlighted below:

This will prompt you to save the certificate file.  Do this, then delete it when you are done. 

Next we need to install the certificate into our client machines.  We will need a GPO.  You may use the one from the previous example or make a new one. Again the place in your AD to create this will vary.  For smaller sites adding at the the top level is fine, but hands off the default policy.

Navigate to Security Settings -> PK policies ->Trusted Root CA's as in the screen below:

Right-click on the Trusted Root CA's container and choose Import.  Here, browse for the cert file saved in step one and you are done!

Finally, here is some linkage to much more detail about Certificates in AD.

Wednesday, June 13, 2007 1:15:54 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, June 08, 2007

Some sites that you may have on your internal network, such as Virtual Server console, Sharepoint, ASP.NET sites of your own creation, and so on, can require your AD credentials to log you on.  Typically the browser will prompt you for them unless you add the site to the Local Intranet zone

This quickly becomes cumbersome as the number of users grows.  Everyone will have to add the URL to their Local Intranet zone manually and that spells work.

Internet Explorer

All the IE Zones, including Local Intranet, can be administered by Group Policy.  Where in your AD you create your GPO will depend on the scale of your operation, for smaller sites a GPO at the domain level is not a bad choice.  I'd caution against editing your default domain policy, consider creating a new GPO just under it.

Edit the GPO and browse to the Site To Zone Assignment List, inside the Internet Control Panel \ Security Page settings:

  

The UI will let you add IP addresses, FQDN's or http/https addresses, and which zone they will belong to.

One nice side effect of this to watch for is the users can now not change their zones via the IE settings.

FireFox

For FireFox, you are going to have to create/maintain an all.js in the %installdir%\defaults\pref\ directory.

This is just a plain text file that can contain settings in the FireFox Javascript format.  For Integrated Authentication you will need to add the following line:

pref("network.negotiate-auth.trusted-uris", "comma seperated site list");

Listening To: Kruder and Dorfmeister, the K&D Sessions, part 1

Friday, June 08, 2007 11:19:27 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, March 23, 2007

My Pure CSS Tabs with ASP.NET 2.0 Master Pages post also apeared over on CSharpZealot.com where I just added a note about an alternate solution.  Copied here for completeness :)

There was an alternate solution using the CSS Friendly Control Adaptor toolkit for ASPNet 2.0 which renders the standard menu control as UL\LI tags rather than as tables

I chose to not go that route because I don't need the tabs to link to a sitemap datasource or anything cool like that - UL\LI in a master page was plenty good enough for me, however if you did want/need to link the same code to a sitemap then the CSS Friendly adaptors would be well worth looking into.

Listening to:  Wave of Mutilation: The Best of Pixies

Friday, March 23, 2007 11:35:46 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [2]  | 
 Sunday, March 11, 2007

So I came across a problem using a old CSS trick to make a tab strip/menu bar on a site from a Unordered List inside a Div

To create the tabs the trick is you can use some CSS like this:

#nav

   float:left

   margin: 0

   padding: 10px 0 0 46px

   list-style: none
;
}

#nav
li


   font-size: 150%

   float: left

   margin:0

   padding: 0
;
}

#nav
a


   float: left

   display: block

   margin: 0 1px 0 0

   padding: 4px 8px

   color: #333

   text-decoration: none

   border: 1px solid #949494

   border-bottom: none

   background: #686868

   color: #949494
;
}

...to turn a <UL> with the ID="nav" into some tabs.  For example we add the following to the master page:

<ul id="nav" > 
   <li id="navHome"><a href="default.aspx">Home</a></li> 
   <li id="navProducts"><a href="products.aspx">Products</a></li> 
   <!-- ...and so on... -->
</ul>

OK so far.  The thing with tabs is you always want the tab of the current page to glow a little or something to indicate what page the user is up to.

A common way is to assign an ID attribute to the body tag of each page and include some CSS that looks at the body ID and overrides the #nav a  for the current page.

The trick comes when the pages all descend from an ASP.NET 2.0 Master Page - the body tags are going to be identical on each page.

As luck would have it, CSS lets us select based on any attribute.  Once the page is rendered each page will get its own form tag where the Action attribute represents the current loaded page as so:  

<form name="aspnetForm" method="post" action="Default.aspx" id="aspnetForm">

Which would let us add the following to our stylesheet:

#nav a:hover, body form[action="Default.aspx"] #NavPlaceHolder #nav #navHome a
{
   background: #ffffff
;
}

OK So far but the problem is it is case sensitve!  We would need - If the page loads as default.aspx our tab won't highlight.  This just won't do!

The trick is to add a new ContentPlaceHolder in our master page straight above the UL listed above

<asp:ContentPlaceHolder runat="server" id="pageIdPlaceHolder" ></asp:ContentPlaceHolder>

Each page that descends from our master page should then override that ContentPlaceHolder to add an empty Span with a page-specific ID as so:

<asp:Content ID="pageIdContent" ContentPlaceHolderID="pageIdPlaceHolder" runat="server" >
   <
span id="ProductsPage"></span> <!-- This page will show the Products tab as selected -->
</
asp:Content>

and then we can add a rule to our CSS for each page that would read:  Whenever there is an element with the ID="ProductsPage" right next to one with the ID="nav" do the following.  The + operator selects the next adjacent node in the document as so:

#ProductsPage + #nav #navProducts a
{
   background: #ffffff;
}

And there you have it!  Accessable and maintainable nav bars from a UL using CSS, plus keeping all the time saving layout features of Master Pages.

Listening To:  The History Of Breaks

CSS | UX | ASP.Net
Saturday, March 10, 2007 11:26:14 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  |