【问题标题】:DotNetOpenAuth Provider for REST Service用于 REST 服务的 DotNetOpenAuth 提供程序
【发布时间】:2013-02-15 16:26:31
【问题描述】:

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

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

【问题讨论】:

    标签: rest dotnetopenauth


    【解决方案1】:

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

    就我个人而言,我不再使用 DNOA,因为它旨在进行自我验证(即加密令牌),因此您无需在每次请求时都访问数据库。这样做的一个非常重要的副作用是访问撤销不会立即生效,而只有在必须更新令牌之后才会生效。此外,访问令牌会变得很长(大约 500 字节)。

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


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

    一个关键问题是:您需要 2-legged OAuth 还是 3-legged OAuth(或两者都需要?)。您需要支持哪些资助类型?

    如果您基本上想替换 H​​TTP 基本身份验证,简单的“资源所有者密码凭据流程”就可以了。 facebook/twitter 类型的“让此应用程序访问我的个人资料信息”是 3-legged OAuth。

    有一个很好的 grant type diagrams 附带的 IBM 文档。


    现在到DNOA,看看Samples/OAuthAuthorizationServer

    一个好的入口点是OAuthController.cs 文件。请注意,AuthorizeAuthorizeResponse 操作仅在您希望让您的用户能够访问第三方应用程序(3-legged OAuth)时才需要。

    在 2-legged 场景中,用户直接访问 OAuth token 端点并简单地请求访问令牌。无论如何,您的 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>
    

    【讨论】:

      猜你喜欢
      • 2011-02-24
      • 2011-07-28
      • 1970-01-01
      • 2012-07-11
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多