|
 Thursday, August 09, 2007

Windsor Links

windsor_rawlogo Every once in awhile I'll make a post that is for my own use, this happens to be one of them.

Ayende, put up a great post awhile back that I just bumped into. It has a bunch of good Windsor Container links/tutorials and he has labeled them as Windsor Patterns.

If you haven't used Windsor/MicroKernel for IoC, its best time you look into it. :)

#    Comments [0] |

DbDataReader Mishap

This is something that I'm almost afraid to admit to. *sheepish grin*

I was debugging a DbDataReader Unit Test and all of a sudden it started to fail. After  about 5 minutes of thrashing I saw that I had put the DbDataReader object into the Watch window (which was not pinned -- therefore I could not see it). I was checking a value of the DbDataReader and working with it in the watch window. Well, I forgot to remove that watch, and as soon as the unit test started again, it bombed bout because as soon as the DbDataReader was available it attempted to perform some work on it (before the Read method was called). Therefore when we did call anything on the DbDataReader later in the game, it blew up because it had already thrown  an exception in the watch window.

Ooops. :)

Moral of the story: Make sure you delete your watch variables when you're done. Oops. :) Perhaps I should be using the Auto's window instead. :)

#    Comments [0] |
 Monday, August 06, 2007

Portable Applications - A Life Saver on a USB Stick

Like many of you out there I'm straight up addicted to using Notepad++. If I can't use N++ I begin to have a productivity melt down. I have a ton of hot keys memorized, a bunch of formatters memorized, hell, it makes my life 10 times easier and I'm 10 times as productive with this tool. When its AWOL I feel, well, empty inside... Ok, not really... but you get the point. :)

There are times when  you're out at a client, or working on a server and you just need access to certain tools that are not normally accessible on the machine that you're working on. In consulting, this happens A LOT. Enter PortableApps.

Portable Apps allows you to put a lot of your common use applications onto a USB Stick so you can use them anywhere.

I have the following portable apps on my USB Stick:

You can choose from a list of apps on the site and build your own little custom set of programs. Here's what I do:

1. Create a folder called UTILS on your USB Stick

2. Create a folder called PORTABLE inside of the UTILS directory

3. Drop all the Portable apps into that directory and now you have a TON of great apps at your fingertips.

Caution though... not all apps run on all operating systems. Most apps will run, but check them here: Application Compatibility Page.

 

Furthering its use, you can even download the Application Suite which contains most of the above items listed as well as some others. The application suite gives you a nice little start menu type of interface and it even places itself in the task bar until you tell it to close. Once you have that running you can also install other portable apps into your application suite by visiting the applications page, downloading the app you want, and then choosing install from the options on the Application Suite.

Here is a shot of my portable app suite running on Vista Business.

portableappssuite

#    Comments [0] |
 Friday, August 03, 2007

Presenting at Arizona .NET User Group - Dependency Injection & Inversion of Control

I will be presenting at the AZ .NET User Group on August 14th. I'm going to cover how to use Dependency Injection along with Inversion of Control to decouple your applications. I will also demonstrate how these techniques can help ease unit testing.

When: August 14th

Time: 6pm

Location: Microsoft Corp 2929 N Central Ave # 1400 Phoenix, AZ 85012 (map).

See AZGROUPS.COM for more info.

See ya there!

#    Comments [2] |
 Thursday, August 02, 2007

IIS 6 & PHP - Mimicking .htaccess User/Pass Functionality

If you happen to be running PHP on a Windows Server machine you'll probably have to port over some functionality. One of the key things that you'll have to port over is something that mimics the .htaccess functionality of prompting users for user/pass based upon the directory.

In your application you might have a directory that is for admin, such as www.myexample.com/admin. This directory might only be accessible to users that you want to specify. In a *NIX environment you can do this with an .htaccess file (and its corresponding .htpasswd) file. Unfortunately when  porting this to a Windows environment, these files don't do anything for you (unless you're running Apache on Windows).

Solution

Here's what you'll need.

  • a login page, login.aspx
  • a web.config file
  • ASP.NET 2.0 installed
  • A minor adjustment to IIS 6

Steps

1. Install PHP.

2. Create a web.config with the following in it.

<?xml version="1.0"?>
<configuration>
    <appSettings/>
    <connectionStrings/>
    <system.web>

      <compilation debug="true" />

      <authentication mode="Forms">
          <forms protection="All" loginUrl="~/login.aspx">
            <credentials passwordFormat="Clear" >
              <user name="admin" password="abc123"/>
              <user name="jdoe" password="123xyz" />
            </credentials>
          </forms>
        </authentication>
    </system.web>

        
  <location path="admin">
    <system.web>
      <authorization>
        <deny users="?"/>
        <allow users="*"/>
      </authorization>
    </system.web>    
  </location>
  
</configuration>

2. Create a login page with a login control. In that code behind (or in the page itself as I've done) set up the Authenticate Event to use Forms Authentication. This will ensure that its reading from the web.config file and not the default membership provider (SqlMembershipProvider).

<%@ Page Language="C#" AutoEventWireup="true"  %>
<script runat="server">

    protected void Page_Load(EventArgs e)
    {
        Page.SetFocus(loginControl); 
    }

    protected void loginControl_Authenticate(object sender, AuthenticateEventArgs e)
    {
        if (FormsAuthentication.Authenticate(loginControl.UserName, loginControl.Password))
        {
            FormsAuthentication.RedirectFromLoginPage(loginControl.UserName, false);
        }
    }
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Login ID="loginControl" runat="server" DisplayRememberMe="False" OnAuthenticate="loginControl_Authenticate">
        </asp:Login>
    
    </div>
    </form>
</body>
</html>

 

3. Now, remember, this site is a PHP site and it is being run with PHP. Therefore the first document that is being loaded is the index.php file. Therefore the ISAPI or CGI module for PHP Is being called before ASP.NET is ever initialized. Therefore, if we try to access the admin site, ASP.NET will NOT catch this and it will allow access. In order to get around this, we have to set the aspnet_isapi.dll module to execute first, therefore IIS will load ASP.NET which in turn will check the web.config file and not allow access to restricted directories.

Here's how to do it.

3a. Start IIS Manager (start --> Run --> inetmgr) Open the sites properties. Click on "Home Directory"

(click for larger)

iis6Config1 

Once on the Home Directory tab, click on the Configuration button.

(click for larger)

iis6Config2

Now click on "Insert" and enter the path to the aspnet_isapi.dll:

(%systemroot%/Microsoft.Net/Framework/v2.0.50727/aspnet_isapi.dll)

Then click OK, and it will look like this: (click for larger)

iis6Config3

Restart IIS and then give your application a test.

Visit the Admin directory and now you should be redirected to the login page.

Log in with the admin credentials that are in the web.config you'll then be authenticated.

What this does is force IIS to load ASP.NET first, regardless of what type of file is loaded. In this situation this is exactly what I want it to do. Load ASP.NET and run anything in the Web.config file. Therefore if the user attempts to load the /admin directory ASP.NET will notice that its a protected directory and it will deny access.

 

Adding a New Directory

If you want to add a new secured directory, you can add another <location> in the web.config.

Like so:

<?xml version="1.0"?>
<configuration>
    <appSettings/>
    <connectionStrings/>
    <system.web>

      <compilation debug="true" />

      <authentication mode="Forms">
          <forms protection="All" loginUrl="~/login.aspx">
            <credentials passwordFormat="Clear" >
              <user name="admin" password="abc123"/>
              <user name="jdoe" password="123xyz" />
            </credentials>
          </forms>
        </authentication>
    </system.web>

        
  <location path="admin">
    <system.web>
      <authorization>
        <deny users="?"/>
        <allow users="*"/>
      </authorization>
    </system.web>    
  </location>
  
  <location path="secretfolder">
    <system.web>
      <authorization>
        <deny users="?"/>
        <allow users="*"/>
      </authorization>
    </system.web>    
  </location>
  
  
</configuration>

Explanation

I've added a "secretfolder" location. Therefore, if a user wants to go to either the "admin" or "secretfolder" they will be authenticated. If they authenticate at the "admin" directory, they will automatically be allowed into the "secretfolder" directory.

You can set folder access to certain users, to learn how see this is accomplished, take a look at the great list of resources that ScottGu has set up .

 

Note, in IIS 7 this problem does not exist, but you do need to include this into your web.config to enable forms authentication. Here's the source of this info.

    <system.webServer>
        <modules>
            <remove name="FormsAuthenticationModule" />    
            <add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />    
            <remove name="UrlAuthorization" />    
            <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />    
            <remove name="DefaultAuthentication" />    
            <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />    
        </modules>
    </system.webServer>

 

Hopefully this helps anyone doing the same thing.

#    Comments [0] |