Wednesday, September 28, 2011

Setting up Thinktecture’s Identity Server

The following tutorial assumes the reader is familiar with the following technologies/concepts:

This post is a  how to setup Thinktecture’s StarterSTS Identity Server [B1].

1. Download the Source Code from the Codeplex site [at the time of this writing, the current version is B1 Refresh] and unzip it on your local drive.


2) Once the Solution is opened in Visual Studio, inside of the Tools solution folder you will find a Setup project. Run the project by right clicking on it, Selecting Debug –> Start new instance.


3) Set the Location of the Configuration Database as shown below.


You can find the file called IdentityServerConfiguration.sdf inside of the App_Data folder of the Website Project.



4) Select the certificate that will be used for SSL Encryption. **Note: If you already have IIS setup with SSL, you most definitely want to use the same certificate. I suspect you will, because if you are installing this Identity Server you must be very familiar with the Windows Identity Foundation configuration dance.


5) Select the certificate that will be used for Signing (You can use the same certificate)



After this is done, you might be thinking that you can run the [website] project now and it should just work, right? Thought WRONG! There is no free meal in this world. Our friend Dominick [Baier] has had this running on his machine for a while, so perhaps forgot about setting up IIS, the ASP.NET provider Database and all that business.



So, right after you download the source code, the Web Project Properties looks like so:


Notice the “[X] Use Custom Web Server” option is selected, and points to https://roadie/idsrv/. You want to change these setting as follows:

Switch the setting to Use Local IIS Web Server and enter a more appropriate URL (i.e.:http://[your machine’s fully qualified name]/idsrv), or if you are one cool cat, you may choose Use IIS Express (but then, you are on your own).

We are almost there, do not despair.


If you were to try to run the Website, you should get this “Yellow page of death”. And that is due to the fact (if you are one of those who do no read error pages) that the 1) you have not installed the standard ASP.NET Membership schema, and 2) the Identity under which IIS is running does not have access to said database (provided it existed). Follow these instructions to setup the ASP.NET application services schema.


After having installed the ASP.NET Schema on your SQL Server instance, go to SQL Server Management Studio, and under Security –> Logins, and make sure that the Identity under which your IIS Application Pool is running has a valid login in SQL Server and has the right access to the ASP.NET database. In my case, the App pool Identity is 'IIS APPPOOL\DefaultAppPool' and the database named "aspnetdb".image


Lastly, change the Website\Configuration\connectionStrings.config file to point to your ASP.NET application services database.

<add name="ProviderDB"
connectionString="data source=.\sqlexpress;Integrated Security=SSPI;Initial Catalog=aspnetdb"
providerName="System.Data.SqlClient" />
<add name="IdentityServerConfigurationEntities"
connectionString="metadata=res://Thinktecture.IdentityServer.Core/Repositories.SqlCompact.IdentityServerConfiguration.csdl|res://Thinktecture.IdentityServer.Core/Repositories.SqlCompact.IdentityServerConfiguration.ssdl|res://Thinktecture.IdentityServer.Core/Repositories.SqlCompact.IdentityServerConfiguration.msl;provider=System.Data.SqlServerCe.4.0;provider connection string=&quot;Data Source=|DataDirectory|\IdentityServerConfiguration.sdf&quot;"
providerName="System.Data.EntityClient" />


If you did everything right, you should now be able to run the application and get this page.


Accessing the Administration Mode of Identity Server

Out of the box, IdentityServer is configured to use the SqlMembershipProvider membership provider implementation. Therefore to login you have to:

  1. create a user (i.e.: Administrator)
  2. create a role called IdentityServerAdministrators.

Both of these can be accomplished by using the built-in Web Site Administration Tool (in Visual Studio, go to Project –>  ASP.NET Configuration).

[FYI] Contrary to what  Dominik Baier’s introductory video says [9:02] , the role the code is expecting is not “TokenServiceAdministrators”, but instead, IdentityServerAdministrators).

[Change for Improvement] This can be improved in the future by modifying the provided implementation of  ClaimsAuthorizationManager, and changing the AuthorizeAdministration Method (inside of Thinktecture.IdentityServer.Web.Security.AuthorizationManager)

protected virtual bool AuthorizeAdministration(Collection<Claim> resource, IClaimsIdentity id)
return (id.ClaimExists(ClaimTypes.Role, Constants.Roles.IdentityServerAdministrators));

The next article will describe how to create a configure your application (Relaying Party) to trust Identity Server as an Secure Token Service (STS).

Thursday, September 1, 2011

Where my data files at!?

A bit of context: As part of my team’s development workflow, we create/modify our Domain Model in code (entities such as Customer, Product, Order, etc.) and then generate the Database Model via a homegrown console app.  This allows us to  [efficiently]  code our Domain Model without having to worry about applying these changes to the lower layers of the system all the way to the database schema.

The [Schema Export] console app I mentioned automatically generates a fresh database by exploring our Domain Model – NHibernate makes this very easy - for the purpose of comparing and synchronizing with the Database Project , thus bringing our Persistence store up-to-date with our Domain Model.

The Problem: I had a need to find out the physical path was the instance of SQL Server installed on the server [c:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\] and thus were the data files for the database are placed [$SqlInstallPath\MSSQL\Data\].

The Solution:

The following T-SQL returned the path where the master database is located:

select physical_name from master.sys.databases dbs inner join master.sys.master_files files on dbs.database_id = files.database_id
where = 'master' and type_desc = 'ROWS'


c:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\master.mdf
(1 row(s) affected)

And the following function takes care of removing the filename and fiving you the path:

 private static string GetDbFilePath ( SqlConnection sqlConnection, string databaseName )
            string path = string.Empty;
                string datafilepathQuery =
                    string.Format (
                        @"select physical_name from 
              master.sys.databases dbs inner join master.sys.master_files files 
                on dbs.database_id = files.database_id
                where = '{0}' and type_desc = 'ROWS'", databaseName );
                using ( var sqlCmd = new SqlCommand ( datafilepathQuery, sqlConnection ) )
                    object datafilepath = sqlCmd.ExecuteScalar ();
                    path = datafilepath.ToString ();
                    path = path.Substring(0, path.LastIndexOf('\\'));
            catch ( Exception )
            return path;

This allowed me to subsequently run another command to create the database schema at the right location. That is all for today folks!

FYI: I will be writing a post – or series of posts – on how to improve your development workflow and thus adhering to my favorite tenet of the Agile Manifesto : “maximizing the amount of work not done”.