Skip to content

Using Windows Authentication In SVN

I needed to run an SVN repository on a Windows 2003 Server machine. Installing SVN was pretty simple, but SVN doesn't know anything about Windows. By default, it wants to authenticate against user accounts on the local machine. Getting it to do something different was tricky.

Apache Setup

How do I get SVN to use Windows domain authentication? The short answer is...it won't. The slightly longer answer is...it can, with the help of the Apache web server and some modules. So I installed Apache and started tinkering.

The first step was to edit Apache's httpd.conf file. I needed to enable 4 modules near the top of the file, like this:

LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
LoadModule sspi_auth_module modules/mod_auth_sspi.so

mod_dav is the general-purpose DAV [^1] plugin. mod_dav_svn lets SVN communicate with clients using the DAV protocol. mod_auth_sspi lets clients authenticate against a Windows domain. And mod_authz_svn compares incoming URLs to the directives stored in a configuration file to determine if a user can perform the requested action.

I had to add a new <Location> tag to my httpd.conf file to make Apache aware of my intentions to expose an SVN repository:

  <Location /svn/repos>
    DAV svn
    SVNPath e:\svn\repos
    AuthName "SVN Server"
    AuthType SSPI
    SSPIAuth On
    SSPIAuthoritative On
    SSPIDomain NA
    SSPIOfferBasic on 
    Require valid-user 
    AuthzSVNAccessFile e:\svn\svnaccess.conf
  </Location>

The tag means that access will occur at http://my.server.com/svn/repos, and the repository will exist on disk at e:\svn\repos. Only valid Windows user IDs will be allowed by mod_auth_sspi, and the access rules found in e:\svn\svnaccess.conf will be applied to incoming requests by mod_authz_svn.

SVN Access File Setup

At this point, I could use an SVN client program (like Tortoise, NetBeans, or Eclipse) to reach my repository, but I wasn't being allowed to access anything. I needed to create the access file mentioned in the Apache directive above. The file looks like this:

[groups]
svn-admins = mydomain\cfreyer
developers = mydomain\anne, mydomain\bill, ...
qa_staff = mydomain\anne, mydomain\carl, ...
analysts = mydomain\mike, mydomain\eddie, ...
[release_mgt] = mydomain\jill, mydomain\david

[/]
@svn-admins = rw

[/project1/source]
@developers = rw
@qa_staff = r

[/project1/builds]
@release_mgt = rw
@developers = rw

[/project1/testsscripts]
@analysts = r
@qa_staff = rw

[/project1/reqirements]
@analysts = rw
@qa_staff = r
@developers = r
mydomain\billybob = r

[/project2]
....

The first part of this file is where groups are declared. It begins with the phrase [groups] on a line by itself. Then you create name = value pairs to represent groups. The name can be anything that is meaningful to you--probably a department name or functional responsibility within your organization. The values are a comma-separated list of user IDs. Depending on your setup, you might have case sensitivity issues with user names (I did). Be prepared to debug that by looking at the IDs recorded in the Apache access log.

After the [group] declaration, individual directories (i.e. projects) are declared. Each project is mentioned separately (i.e. [/myproject]). Groups and users are mentioned under the project, along with their access permissions. Its normally better to avoid putting user names inside each project (especially if you have many projects), but its allowed.

Cautions

Here are a few things I've learned the hard way:

  • The mod_auth_sspi plugin caches user credentials. If a user changes his domain password then tries to access the repository, it won't work. Best solution is to restart apache. Nightly Apache restart will help, but users can be impatient. I haven't found an easy way around this.
  • I've seen the case of my domain change on different users' machines. In other words, the Apache log will show mydomain\user1 on one day, and MYDOMAIN\user1 on another day. This forces me to duplicate the IDs in the [groups] section.

[^1] distributed authoring and versioning