REST服务的DotNetOpenAuth提供程序

REST服务的DotNetOpenAuth提供程序,rest,dotnetopenauth,Rest,Dotnetopenauth,我在ASP.NETMVC4Web应用程序的一个区域中创建了一个RESTAPI。API工作正常,我现在想保护它 有没有一个非常简单的例子来说明我是如何做到这一点的?我正在浏览下载的DotNetOpenAuth附带的示例,我完全迷恋它。几天前我也遇到了同样的问题。这个答案太长了,也许有更简单的方法 就我个人而言,我不再使用DNOA,因为它是为自我验证(即加密令牌)而设计的,所以您不需要在每次请求时都点击数据库。这样做的一个非常重要的副作用是,访问撤销不会立即生效,而只能在必须续订令牌之后生效。此外,

我在ASP.NETMVC4Web应用程序的一个区域中创建了一个RESTAPI。API工作正常,我现在想保护它


有没有一个非常简单的例子来说明我是如何做到这一点的?我正在浏览下载的DotNetOpenAuth附带的示例,我完全迷恋它。

几天前我也遇到了同样的问题。这个答案太长了,也许有更简单的方法

就我个人而言,我不再使用DNOA,因为它是为自我验证(即加密令牌)而设计的,所以您不需要在每次请求时都点击数据库。这样做的一个非常重要的副作用是,访问撤销不会立即生效,而只能在必须续订令牌之后生效。此外,访问令牌将变得相当长(大约500字节)

作为第一步,确保您知道自己需要什么:


OAuth/OAuth2一开始看起来很简单,但了解授权工作流是如何设计的很重要。此外,它们的术语可能会令人恼火,例如,“客户机”指的是我天真地称之为客户机应用程序的东西。它不是用户(在OAuth术语中称为“资源所有者”)。我的建议是:阅读。它看起来很枯燥,但读起来很有趣(你可以跳过一半…)

一个关键问题是:您需要两条腿的OAuth还是三条腿的OAuth(或者两者都需要?)。您需要支持哪些补助金类型

如果您基本上希望替换HTTP基本身份验证,那么简单的“资源所有者密码凭据流”就可以了。facebook/twitter类型的“让此应用程序访问我的个人资料信息”是三条腿的OAuth

nice附带了一个IBM文档


现在来看DNOA,看看
Samples/OAuthAuthorizationServer

一个好的入口点是
OAuthController.cs
文件。请注意,
Authorize
AuthorizeResponse
操作仅在您希望允许用户访问第三方应用程序(三腿OAuth)时才需要

在两条腿的场景中,用户直接访问OAuth
令牌
端点,只需请求一个访问令牌。在任何情况下,您都需要在REST应用程序中使用这样的控制器

内部工作的关键是
OAuth2AuthorizationServer
类(而不是
AuthorizationServer
类)。查看
code/OAuth2AuthorizationServer.cs
。它实现了
IAuthorizationServerHost

该类的一半处理数据存储(如果您使用的是不同的数据存储,您可能需要对其进行修改),另一半处理访问令牌的加密。您还需要为应用程序实现IAuthorizationServerHost

确保代码中有一行
#define SAMPLESONLY
,这样它将接受硬编码证书

要实际授权请求,编写一个自定义的
ActionFilterAttribute
很有帮助。下面是一些超级精简的代码,但不适合生产:

public sealed class BasicAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    private readonly OAuthResourceServer _authServer; 
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.Request.Headers.Authorization.Scheme == "Bearer"
            || actionContext.Request.Properties.ContainsKey("access_token"))
        {
            authenticatedUser = _authServer.VerifyOAuth2(request, required_claims);
            HttpContext.Current.User = authenticatedUser;
            Thread.CurrentPrincipal = authenticatedUser;
        }
    }
}

// See OAuthResourceServer/Code/OAuthAuthorizationManager.cs in DNOA samples
public sealed class OAuthResourceServer
{
    public IPrincipal VerifyOAuth2(HttpRequestMessage httpDetails, 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 = CreateAuthorizationServerSigningServiceProvider())
        {
            using (var encrypting = CreateResourceServerEncryptionServiceProvider())
            {
                var tokenAnalyzer = new StandardAccessTokenAnalyzer(signing, encrypting);
                var resourceServer = new ResourceServer(_myUserService, tokenAnalyzer);
                return resourceServer.GetPrincipal(httpDetails, requiredScopes);
            }
        }
    }
}
资源服务器仍然丢失

public sealed class MyResourceServer : ResourceServer
{
    public override System.Security.Principal.IPrincipal GetPrincipal([System.Runtime.InteropServices.OptionalAttribute]
        [System.Runtime.InteropServices.DefaultParameterValueAttribute(null)]
        HttpRequestBase httpRequestInfo, params string[] requiredScopes)
    {
        AccessToken accessToken = this.GetAccessToken(httpRequestInfo, requiredScopes);
        string principalUserName = !string.IsNullOrEmpty(accessToken.User)
            ? this.ResourceOwnerPrincipalPrefix + accessToken.User
            : this.ClientPrincipalPrefix + accessToken.ClientIdentifier;
        string[] principalScope = accessToken.Scope != null ? accessToken.Scope.ToArray() : new string[0];

        // Now your own code that retrieves the user 
        // based on principalUserName from the DB:
        return myUserService.GetUser(userName);
    }
}
接下来,修改web.config,以便DNOA不会抱怨开发中缺少SSL连接:

<configSections>
      <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth">
        <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
        <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
        <sectionGroup name="oauth2" type="DotNetOpenAuth.Configuration.OAuth2SectionGroup, DotNetOpenAuth">
          <section name="authorizationServer" type="DotNetOpenAuth.Configuration.OAuth2AuthorizationServerSection, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
        </sectionGroup>
        <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
        <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
      </sectionGroup>    
  </configSections>
  <dotNetOpenAuth>
    <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
    <reporting enabled="true" />
    <openid>
      <provider>
        <security requireSsl="false">
        </security>
      </provider>
    </openid>
    <oauth2>
      <authorizationServer >
      </authorizationServer>
    </oauth2>
    <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
    <messaging relaxSslRequirements="true">
      <untrustedWebRequest>
        <whitelistHosts>
          <!-- since this is a sample, and will often be used with localhost -->
          <add name="localhost"/>
        </whitelistHosts>
      </untrustedWebRequest>
    </messaging>
  </dotNetOpenAuth>