Skip to content

Commit

Permalink
Move the HttpModule to an own assembly and remove System.Web depdency.
Browse files Browse the repository at this point in the history
- Fixes Sustainsys#97, Closes Sustainsys#179.
- Improved config handling from code, no longer requires a <System.IdentityModel> section.
  • Loading branch information
AndersAbel committed Feb 17, 2015
2 parents 1c87e07 + 3b66d95 commit ed2d1ab
Show file tree
Hide file tree
Showing 57 changed files with 1,052 additions and 322 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Rosanna Wahlstr
Lisa Bylund
Sebastian Allard
Jozef Raschmann
Tor-Bj�rn Holmstr�m
84 changes: 84 additions & 0 deletions Kentor.AuthServices.HttpModule/CommandResultHttpExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using Kentor.AuthServices.WebSso;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IdentityModel.Services;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Kentor.AuthServices.HttpModule
{
/// <summary>
/// Extension methods to CommandResult to update a HttpResponseBase.
/// </summary>
public static class CommandResultHttpExtension
{
/// <summary>
/// Apply the command result to a bare HttpResponse.
/// </summary>
/// <param name="commandResult">The CommandResult that will update the HttpResponse.</param>
/// <param name="response">Http Response to write the result to.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HttpStatusCode")]
public static void Apply(this CommandResult commandResult, HttpResponseBase response)
{
if (commandResult == null)
{
throw new ArgumentNullException("commandResult");
}

if (response == null)
{
throw new ArgumentNullException("response");
}

response.Cache.SetCacheability((HttpCacheability)commandResult.Cacheability);

if (commandResult.HttpStatusCode == HttpStatusCode.SeeOther || commandResult.Location != null)
{
if (commandResult.Location == null)
{
throw new InvalidOperationException("Missing Location on redirect.");
}
if (commandResult.HttpStatusCode != HttpStatusCode.SeeOther)
{
throw new InvalidOperationException("Invalid HttpStatusCode for redirect, but Location is specified");
}

response.Redirect(commandResult.Location.OriginalString);
}
else
{
response.StatusCode = (int)commandResult.HttpStatusCode;
response.ContentType = commandResult.ContentType;
response.Write(commandResult.Content);

response.End();
}
}

/// <summary>
/// Establishes an application session by calling the session authentication module.
/// </summary>
[ExcludeFromCodeCoverage]
public static void SignInSessionAuthenticationModule(this CommandResult commandResult)
{
if(commandResult == null)
{
throw new ArgumentNullException("commandResult");
}

// Ignore this if we're not running inside IIS, e.g. in unit tests.
if (commandResult.Principal != null && HttpContext.Current != null)
{
var sessionToken = new SessionSecurityToken(commandResult.Principal);

FederatedAuthentication.SessionAuthenticationModule
.AuthenticateSessionSecurityToken(sessionToken, true);
}
}
}
}
36 changes: 36 additions & 0 deletions Kentor.AuthServices.HttpModule/HttpRequestBaseExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Kentor.AuthServices.WebSso;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Kentor.AuthServices.HttpModule
{
/// <summary>
/// Static class that hold extension methods for <see cref="HttpRequestBase"/>.
/// </summary>
public static class HttpRequestBaseExtensions
{
/// <summary>
/// Extension method to convert a HttpRequestBase to a HttpRequestData.
/// </summary>
/// <param name="requestBase">The request object used to populate the <c>HttpRequestData</c>.</param>
/// <returns>The <c>HttpRequestData</c> object that has been populated by the request.</returns>
public static HttpRequestData ToHttpRequestData(this HttpRequestBase requestBase)
{
if (requestBase == null)
{
throw new ArgumentNullException("requestBase");
}

return new HttpRequestData(
requestBase.HttpMethod,
requestBase.Url,
requestBase.ApplicationPath,
requestBase.Form.Cast<string>().Select((de, i) =>
new KeyValuePair<string, string[]>(de, ((string)requestBase.Form[i]).Split(','))));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{86A588E8-2E2D-4394-9545-24D8EA939CF2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Kentor.AuthServices.HttpModule</RootNamespace>
<AssemblyName>Kentor.AuthServices.HttpModule</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>..\Kentor.AuthServices.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin\Debug\Kentor.AuthServices.HttpModule.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.identitymodel.services" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\VersionInfo.cs">
<Link>VersionInfo.cs</Link>
</Compile>
<Compile Include="CommandResultHttpExtension.cs" />
<Compile Include="HttpRequestBaseExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Saml2AuthenticationModule.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Kentor.AuthServices\Kentor.AuthServices.csproj">
<Project>{93ba675e-a159-4701-b68b-c4b81015c556}</Project>
<Name>Kentor.AuthServices</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
<Link>CustomDictionary.xml</Link>
</CodeAnalysisDictionary>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using System.Net;
using System.Web;

namespace Kentor.AuthServices
namespace Kentor.AuthServices.HttpModule
{
/// <summary>
/// Http Module for SAML2 authentication. The module hijacks the
Expand Down Expand Up @@ -61,8 +61,8 @@ private static CommandResult RunCommand(HttpApplication application, ICommand co
{
try
{
return command.Run(new HttpRequestData(
new HttpRequestWrapper(application.Request)),
return command.Run(
new HttpRequestWrapper(application.Request).ToHttpRequestData(),
Options.FromConfiguration);
}
catch (AuthServicesException)
Expand Down
23 changes: 23 additions & 0 deletions Kentor.AuthServices.HttpModule/properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Kentor.AuthServices.HttpModule")]
[assembly: AssemblyDescription("SAML2 Authentication for ASP.NET")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("Kentor.AuthServices.HttpModule")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5466be68-ecee-4495-96e9-ee3a8ae14987")]

[assembly: CLSCompliant(true)]
7 changes: 4 additions & 3 deletions Kentor.AuthServices.Mvc/AuthServicesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Net;
using System.Web.Mvc;
using System.IdentityModel.Services;
using Kentor.AuthServices.HttpModule;
using Kentor.AuthServices.Configuration;
using Kentor.AuthServices.WebSso;

Expand Down Expand Up @@ -41,7 +42,7 @@ public static IOptions Options {
public ActionResult SignIn()
{
return CommandFactory.GetCommand(CommandFactory.SignInCommandName).Run(
new HttpRequestData(Request),
Request.ToHttpRequestData(),
Options)
.ToActionResult();
}
Expand All @@ -56,7 +57,7 @@ public ActionResult SignIn()
public ActionResult Acs()
{
var result = CommandFactory.GetCommand(CommandFactory.AcsCommandName).Run(
new HttpRequestData(Request),
Request.ToHttpRequestData(),
Options);

result.SignInSessionAuthenticationModule();
Expand All @@ -80,7 +81,7 @@ public ActionResult SignOut()
public ActionResult Index()
{
var result = CommandFactory.GetCommand(CommandFactory.MetadataCommand).Run(
new HttpRequestData(Request),
Request.ToHttpRequestData(),
Options);
return result.ToActionResult();
}
Expand Down
24 changes: 24 additions & 0 deletions Kentor.AuthServices.Mvc/CommandResultExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using Kentor.AuthServices.WebSso;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IdentityModel.Services;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace Kentor.AuthServices.Mvc
Expand Down Expand Up @@ -50,5 +54,25 @@ public static ActionResult ToActionResult(this CommandResult commandResult)
throw new NotImplementedException();
}
}

/// <summary>
/// Establishes an application session by calling the session authentication module.
/// </summary>
[ExcludeFromCodeCoverage]
public static void SignInSessionAuthenticationModule(this CommandResult commandResult)
{
if (commandResult == null)
{
throw new ArgumentNullException("commandResult");
}
// Ignore this if we're not running inside IIS, e.g. in unit tests.
if (commandResult.Principal != null && HttpContext.Current != null)
{
var sessionToken = new SessionSecurityToken(commandResult.Principal);

FederatedAuthentication.SessionAuthenticationModule
.AuthenticateSessionSecurityToken(sessionToken, true);
}
}
}
}
4 changes: 4 additions & 0 deletions Kentor.AuthServices.Mvc/Kentor.AuthServices.Mvc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Kentor.AuthServices.HttpModule\Kentor.AuthServices.HttpModule.csproj">
<Project>{86a588e8-2e2d-4394-9545-24d8ea939cf2}</Project>
<Name>Kentor.AuthServices.HttpModule</Name>
</ProjectReference>
<ProjectReference Include="..\Kentor.AuthServices\Kentor.AuthServices.csproj">
<Project>{93ba675e-a159-4701-b68b-c4b81015c556}</Project>
<Name>Kentor.AuthServices</Name>
Expand Down
2 changes: 1 addition & 1 deletion Kentor.AuthServices.Owin/Kentor.AuthServices.Owin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.Web" />
<Reference Include="System.identitymodel.services" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IdentityModel.Configuration;
using System.IdentityModel.Metadata;
using System.Linq;
using System.Text;
Expand Down
12 changes: 7 additions & 5 deletions Kentor.AuthServices.StubIdp/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Configuration;
using Kentor.AuthServices.Saml2P;
using Kentor.AuthServices.WebSso;
using Kentor.AuthServices.HttpModule;

namespace Kentor.AuthServices.StubIdp.Controllers
{
Expand All @@ -22,13 +23,14 @@ public ActionResult Index()
{
var model = AssertionModel.CreateFromConfiguration();

var decodedXmlData = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
.Unbind(new HttpRequestData(Request));
var requestData = Request.ToHttpRequestData();
if(requestData.QueryString["SAMLRequest"].Any())
{
var decodedXmlData = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
.Unbind(requestData);

var request = Saml2AuthenticationRequest.Read(decodedXmlData);
var request = Saml2AuthenticationRequest.Read(decodedXmlData);

if (request != null)
{
model.InResponseTo = request.Id;
model.AssertionConsumerServiceUrl = request.AssertionConsumerServiceUrl.ToString();
model.AuthnRequestXml = decodedXmlData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Kentor.AuthServices.HttpModule\Kentor.AuthServices.HttpModule.csproj">
<Project>{86a588e8-2e2d-4394-9545-24d8ea939cf2}</Project>
<Name>Kentor.AuthServices.HttpModule</Name>
</ProjectReference>
<ProjectReference Include="..\Kentor.AuthServices.Mvc\Kentor.AuthServices.Mvc.csproj">
<Project>{7d32f0a3-cec8-4dc6-a096-5905ea9c3770}</Project>
<Name>Kentor.AuthServices.Mvc</Name>
Expand Down
Loading

0 comments on commit ed2d1ab

Please sign in to comment.