using System;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.ServiceModel.Channels;
using System.Threading;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using DotNetOpenAuth.OAuth2;
namespace ProjectName.Web.Controllers.ActionFilters
{
/// <summary>
/// ActionFilter to authorize requests using OAuth2
/// </summary>
public class OAuth2Authorize : AuthorizationFilterAttribute
{
/// <summary>
/// Called when [authorization].
/// </summary>
/// <param name="actionContext">The action context.</param>
public override void OnAuthorization(HttpActionContext actionContext)
{
// get public / private key from certificate
var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
var signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, "CN=*.yourdomain.com, OU=Domain Control Validated, O=*.yourdomain.com", false);
var cert = signingCert[0];
store.Close();
var publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
var privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
using (var signing = publicKey)
using (var encrypting = privateKey)
{
base.OnAuthorization(actionContext);
// TODO FIXME dnoa doesn't support HttpRequestMessage - manually creating HttpRequestMessageProperty until they do
var request = new HttpRequestMessageProperty();
request.Headers[HttpRequestHeader.Authorization] = actionContext.Request.Headers.Authorization.ToString();
var requestUri = actionContext.Request.RequestUri;
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(signing, encrypting));
IPrincipal result;
var response = resourceServer.VerifyAccess(request, requestUri, out result);
if (response != null)
{
actionContext.Response = actionContext.ControllerContext.Request.CreateResponse(HttpStatusCode.Forbidden);
return;
}
var principal = null; // create your principal using result.Identity.Name if needed
Thread.CurrentPrincipal = principal;
}
}
}
}