2012-09-04 69 views
3

我有3個應用程序; OAuth 2.0生成令牌的認證服務器,請求令牌的OAuth客戶端,提供Restful API的OAuth資源服務器。這些都是MVC 3 Web應用程序。 我的問題是如何驗證從客戶端到達OAuth資源服務器的訪問令牌? 例如,OAuth客戶端使用Access令牌從OAuth服務器接收到響應。然後,客戶端在向OAuth資源服務器發出請求以調用其中一個API函數之前將此令牌添加到標頭中。 儘管我可以在標頭[認證]中看到acces標記,但我無法找到驗證此標記的方法。 因爲我使用MVC3通過Area來設計Restful API,所以我不能使用下面的函數,它與SOAP Web服務一起使用。如何驗證OAuth資源服務器中的訪問令牌

private static IPrincipal VerifyOAuth2(HttpRequestMessageProperty httpDetails, Uri requestUri, params string[] requiredScopes) { 
     // for this sample where the auth server and resource server are the same site, 
     // we use the same public/private key. 
     using (var signing = PixidoRest.MvcApplication.CreateAuthorizationServerSigningServiceProvider()) 
     { 
      using (var encrypting = PixidoRest.MvcApplication.CreateResourceServerEncryptionServiceProvider()) 
      { 
       var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(signing, encrypting)); 
       return resourceServer.GetPrincipal(httpDetails, requestUri, requiredScopes); 
      } 
     } 
    } 

因爲我不能路徑「HttpRequestMessageProperty」,我被困在那裏驗證AccesToken,我從客戶端接收。我如何在MVC 3 Restful API應用程序上驗證此作爲OAuth客戶端的資源服務器?

這裏是我的其他代碼:

internal static RSACryptoServiceProvider CreateResourceServerEncryptionServiceProvider() 
    { 
     var resourceServerEncryptionServiceProvider = new RSACryptoServiceProvider(); 
     resourceServerEncryptionServiceProvider.ImportParameters(ResourceServerEncryptionPrivateKey); 
     return resourceServerEncryptionServiceProvider; 
    } 

    /// <summary> 
    /// Creates the crypto service provider for the authorization server that contains the public key used to verify an access token signature. 
    /// </summary> 
    /// <returns>An RSA crypto service provider.</returns> 
    internal static RSACryptoServiceProvider CreateAuthorizationServerSigningServiceProvider() 
    { 
     var authorizationServerSigningServiceProvider = new RSACryptoServiceProvider(); 
     authorizationServerSigningServiceProvider.ImportParameters(AuthorizationServerSigningPublicKey); 
     return authorizationServerSigningServiceProvider; 
    } 

public class RequireAuthorization : ActionFilterAttribute 
{ 
    public string Scope { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext actionContext) 
    { 
     string[] scope = null; 
     if (!string.IsNullOrEmpty(Scope)) 
     { 
      scope = Scope.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); 
     } 

     var query = actionContext.RequestContext.HttpContext.Request; 
     var req = actionContext.HttpContext; 
     var authvalue = query.Headers["Authorization"]; 
     OAuthAuthorizationManager.VerifyOAuth2(query, query.Url.AbsoluteUri); 
     //var response = new HttpResponseMessageProperty() 
     //{ 
      //here is my question. 
     //}; 


     base.OnActionExecuting(actionContext); 

     //redirect page to 
     //if (CheckUrCondition) 
     //{ 
     //actionContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new 
     //{ 
     // controller = "Home", 
     // action = "Index" 
     //})); 
     ////} 
    } 

在此先感謝。

+0

你解決了嗎?如果是這樣,請分享! – gimix

回答

3

我有同樣的問題,並提出了以下自定義授權屬性,這對我來說很有用。請注意,我的示例依賴於注入了依賴注入的ResourceServer屬性。當然,你也可以讓它指向一個靜態實例。

using System; 
using System.Threading; 
using System.Web; 
using System.Web.Mvc; 

using DotNetOpenAuth.Messaging; 
using DotNetOpenAuth.OAuth2; 

/// <summary> 
/// Allows authorization to be applied to ASP.NET MVC methods where OAuth is used as the authorization mechanism. 
/// </summary> 
public class OAuthAuthorizeAttribute : AuthorizeAttribute 
{ 
    /// <summary> 
    /// Gets or sets the resource server that will be used to process the access token 
    /// that will be used to authorized. 
    /// </summary> 
    /// <value> 
    /// The resource server. 
    /// </value> 
    /// <remarks> 
    /// This property will most likely be set using dependency-injection. 
    /// </remarks> 
    public ResourceServer ResourceServer { get; set; } 

    /// <summary> 
    /// Gets or sets the scopes. 
    /// </summary> 
    /// <value> 
    /// The required scopes. 
    /// </value> 
    /// <remarks> 
    /// Multiple scopes can be used by separating them with spaces. 
    /// </remarks> 
    public string Scopes { get; set; } 

    /// <summary> 
    /// When overridden, provides an entry point for custom authorization checks. 
    /// </summary> 
    /// <param name="httpContext">The HTTP context, which encapsulates all HTTP-specific information about an individual HTTP request.</param> 
    /// <returns> 
    /// true if the user is authorized; otherwise, false. 
    /// </returns> 
    /// <exception cref="System.InvalidOperationException">Thrown when the <see cref="ResourceServer"/> property is <c>null</c>.</exception> 
    /// <exception cref="System.InvalidOperationException">Thrown when the <see cref="Scopes"/> property is <c>null</c>.</exception> 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (this.ResourceServer == null) 
     { 
      throw new InvalidOperationException("The ResourceServer property must not be null."); 
     } 

     try 
     { 
      this.StorePrincipalFromAccessToken(httpContext); 

      return this.AccessTokenIsAuthorizedForRequestedScopes(); 
     } 
     catch (ProtocolException) 
     { 
      return false; 
     } 
    } 

    /// <summary> 
    /// Processes HTTP requests that fail authorization. 
    /// </summary> 
    /// <param name="filterContext">Encapsulates the information for using <see cref="T:System.Web.Mvc.AuthorizeAttribute" />. The <paramref name="filterContext" /> object contains the controller, HTTP context, request context, action result, and route data.</param> 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     filterContext.Result = new HttpUnauthorizedResult(); 
    } 

    /// <summary> 
    /// Stores the principal contained in the current access token. 
    /// </summary> 
    /// <param name="httpContext">The HTTP context.</param> 
    protected virtual void StorePrincipalFromAccessToken(HttpContextBase httpContext) 
    { 
     httpContext.User = this.ResourceServer.GetPrincipal(); 
     Thread.CurrentPrincipal = httpContext.User; 
    } 

    /// <summary> 
    /// Check if the access token provided is authorized for the requested scopes. 
    /// </summary> 
    /// <returns></returns> 
    protected virtual bool AccessTokenIsAuthorizedForRequestedScopes() 
    { 
     return OAuthUtilities.SplitScopes(this.Scopes ?? string.Empty).IsSubsetOf(this.ResourceServer.GetAccessToken().Scope); 
    } 
} 

如下現在你可以使用這個屬性:

using System.Web.Mvc; 

public class DemoController : Controller 
{ 
    [OAuthAuthorize(Scopes = "public")] 
    public ActionResult Index() 
    { 
     return this.View(); 
    } 
} 
相關問題