Skip to content
This repository has been archived by the owner on Dec 14, 2017. It is now read-only.

Commit

Permalink
spiked introspection support
Browse files Browse the repository at this point in the history
  • Loading branch information
leastprivilege committed Nov 2, 2015
1 parent 8e36d69 commit b236226
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 2 deletions.
2 changes: 1 addition & 1 deletion source/AccessTokenValidation.Tests/packages.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.0.0" targetFramework="net45" />
<package id="IdentityModel" version="1.1.0" targetFramework="net45" />
<package id="IdentityModel" version="1.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
Expand Down
5 changes: 5 additions & 0 deletions source/AccessTokenValidation/AccessTokenValidation.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
<DocumentationFile>..\..\build\IdentityServer3.AccessTokenValidation.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="IdentityModel.Net45, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\IdentityModel.1.2.1\lib\net45\IdentityModel.Net45.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocol.Extensions, Version=1.0.2.33, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.2.206221351\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll</HintPath>
<Private>True</Private>
Expand Down Expand Up @@ -96,6 +100,7 @@
<Compile Include="Plumbing\InMemoryValidationResultCache.cs" />
<Compile Include="Plumbing\IValidationResultCache.cs" />
<Compile Include="Plumbing\StringExtensions.cs" />
<Compile Include="Plumbing\IntrospectionEndpointTokenProvider.cs" />
<Compile Include="Plumbing\ValidationEndpointTokenProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Plumbing\PreserveAccessTokenMiddleware.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,29 @@ public IdentityServerBearerTokenAuthenticationOptions() : base("Bearer")
/// <c>true</c> if access token is preserved; otherwise, <c>false</c>.
/// </value>
public bool PreserveAccessToken { get; set; }

/// <summary>
/// Gets or sets the client id for accessing the introspection endpoint.
/// </summary>
/// <value>
/// The client id.
/// </value>
public string ClientId { get; set; }

/// <summary>
/// Gets or sets the client secret for accessing the introspection endpoint.
/// </summary>
/// <value>
/// The client secret.
/// </value>
public string ClientSecret { get; set; }

/// <summary>
/// Gets or sets the HTTP handler for accessing the introspection endoint.
/// </summary>
/// <value>
/// The introspection HTTP handler.
/// </value>
public WebRequestHandler IntrospectionHttpHandler { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,18 @@ private static OAuthBearerAuthenticationOptions ConfigureEndpointValidation(Iden
{
AuthenticationMode = options.AuthenticationMode,
AuthenticationType = options.AuthenticationType,
AccessTokenProvider = new ValidationEndpointTokenProvider(options, loggerFactory),
Provider = new ContextTokenProvider(options.TokenProvider),
};

if (!string.IsNullOrEmpty(options.ClientId) || options.IntrospectionHttpHandler != null)
{
bearerOptions.AccessTokenProvider = new IntrospectionEndpointTokenProvider(options, loggerFactory);
}
else
{
bearerOptions.AccessTokenProvider = new ValidationEndpointTokenProvider(options, loggerFactory);
}

return bearerOptions;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright 2015 Dominick Baier, Brock Allen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using IdentityModel.Client;
using Microsoft.Owin.Logging;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;

namespace IdentityServer3.AccessTokenValidation
{
internal class IntrospectionEndpointTokenProvider : AuthenticationTokenProvider
{
private readonly IntrospectionClient _client;
private readonly IdentityServerBearerTokenAuthenticationOptions _options;
private readonly ILogger _logger;

public IntrospectionEndpointTokenProvider(IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
{
_logger = loggerFactory.Create(this.GetType().FullName);

if (string.IsNullOrWhiteSpace(options.Authority))
{
throw new Exception("Authority must be set to use validation endpoint.");
}

var baseAddress = options.Authority.EnsureTrailingSlash();
baseAddress += "connect/introspect";
var introspectionEndpoint = baseAddress;

var handler = options.IntrospectionHttpHandler ?? new WebRequestHandler();

if (options.BackchannelCertificateValidator != null)
{
// Set the cert validate callback
var webRequestHandler = handler as WebRequestHandler;
if (webRequestHandler == null)
{
throw new InvalidOperationException("Invalid certificate validator");
}

webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate;
}

if (!string.IsNullOrEmpty(options.ClientId))
{
_client = new IntrospectionClient(
introspectionEndpoint,
options.ClientId,
options.ClientSecret ?? "",
handler);
}
else
{
_client = new IntrospectionClient(
introspectionEndpoint,
innerHttpMessageHandler: handler);
}

_options = options;
}

public override async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
if (_options.EnableValidationResultCache)
{
var cachedClaims = await _options.ValidationResultCache.GetAsync(context.Token);
if (cachedClaims != null)
{
SetAuthenticationTicket(context, cachedClaims);
return;
}
}

IntrospectionResponse response;
try
{
response = await _client.SendAsync(new IntrospectionRequest { Token = context.Token });
if (response.IsError)
{
_logger.WriteError("Error returned from introspection endpoint: " + response.Error);
return;
}
}
catch (Exception ex)
{
_logger.WriteError("Exception while contacting introspection endpoint: " + ex.ToString());
return;
}

var claims = new List<Claim>();
foreach (var claim in response.Claims)
{
claims.Add(new Claim(claim.Item1, claim.Item2));
}

if (_options.EnableValidationResultCache)
{
await _options.ValidationResultCache.AddAsync(context.Token, claims);
}

SetAuthenticationTicket(context, claims);
}

private void SetAuthenticationTicket(AuthenticationTokenReceiveContext context, IEnumerable<Claim> claims)
{
var id = new ClaimsIdentity(
claims,
_options.AuthenticationType,
_options.NameClaimType,
_options.RoleClaimType);

context.SetTicket(new AuthenticationTicket(id, new AuthenticationProperties()));
}
}
}
1 change: 1 addition & 0 deletions source/AccessTokenValidation/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="IdentityModel" version="1.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Protocol.Extensions" version="1.0.2.206221351" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
Expand Down
1 change: 1 addition & 0 deletions source/IdentityServer3.AccessTokenValidation.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<dependency id="Owin" version="1.0"/>
<dependency id="Microsoft.Owin.Security.Jwt" version="3.0.1" />
<dependency id="Microsoft.AspNet.WebApi.Client" version="5.2.3" />
<dependency id="IdentityModel" version="1.2.1" />
<dependency id="Microsoft.IdentityModel.Protocol.Extensions" version="1.0.2.206221351" />
</dependencies>
</metadata>
Expand Down

0 comments on commit b236226

Please sign in to comment.