webapi 中的本地登录

WebApi 身份验证方式

asp.net WebApi 中有三种身份验证方式

  • 个人用户账户。用户可以在网站注册,也可以使用 google, facebook 等外部服务登录。
  • 工作和学校账户。使用活动目录,Office 365等方式进行身份验证。
  • Windows 身份验证。在局域网中使用。

个人用户账户方式下又又两种登录方式:

  • 本地登录。用户在网站注册,网站保存用户的登录名和密码散列值。登录时,用户提供登录名和密码,网站使用 asp.net identity 系统进行身份验证。
  • 社交登录。使用 google, facebook 等外部服务登录。网站仍然为用户在数据库中创建一个记录,但是不会保存凭据。用户通过登录外部服务进行身份验证。

这两种登录方式的差别在于凭据流,不管采用哪个方式,WebApi 都使用 OAuth2 进行身份验证。

OAuth2 术语

  • Resource(资源)。受保护的数据。
  • Resource Server(资源服务器)。承载资源的服务器。
  • Resouce Owner(资源所有者)。可以授权访问资源的实体,用户是典型的资源所有者。
  • Client(客户端)。访问资源的应用程序。
  • Access token(访问令牌)。允许对资源进行访问的令牌。
  • Bearer token(不记名令牌)。这是访问令牌的一种,客户端不需要对其进行加密钥,不记名令牌应仅在 HTTPS 上使用,并且设置较短的有效时间。
  • Authorization server(授权服务器)。发出令牌的服务器。

实践中,资源访问器和授权访问器可以是同一个应用程序。

本地登录的凭据流程

对于本地登录方式,WebApi 使用 OAuth2 中定义的资源所有者密码授权类型。这种授权类型适用于资源所有者十分信任客户端的情形。

  1. 用户在客户端输入登录名和密码。
  2. 客户端将登录名和密码发送给授权服务器。
  3. 授权服务器对凭据进行验证,返回访问令牌。
  4. 客户端访问受保护的资源时,将令牌放在 HTTP Authorization 请求头中。

下图是实现这个流程的具体程序结构

在这里,WebApi的控制器是资源服务器。Authentication Filter 对令牌进行验证,Authorization Filter 决定是否授权。授权服务器和 Authentication Filter 通过 OWIN 中间件处理 OAuth2 标准规定的细节。

AccountController 使用 asp.net identity 管理用户数据。相关文件有:

  • \App_Start\IdentityConfig.cs
  • \Controllers\AccountController.cs
  • \Models\IdentityModels.cs
  • \Providers\ApplicationOAuthProvider.cs

配置授权服务器

在 Startup.Auth.cs 文件的 ConfigureAuth 方法中进行配置。

public void ConfigureAuth(IAppBuilder app)
{
    // 将数据库上下文和用户管理器配置为对每个请求使用单个实例
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

    // 使应用程序可以使用 Cookie 来存储已登录用户的信息
    // 并使用 Cookie 来临时存储有关使用第三方登录提供程序登录的用户的信息
    app.UseCookieAuthentication(new CookieAuthenticationOptions());
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

    // 针对基于 OAuth 的流配置应用程序
    PublicClientId = "self";
    OAuthOptions = new OAuthAuthorizationServerOptions
    {
        TokenEndpointPath = new PathString("/Token"),
        Provider = new ApplicationOAuthProvider(PublicClientId),
        AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
        AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
        //在生产模式下设 AllowInsecureHttp = false
        AllowInsecureHttp = true
    };

    // 使应用程序可以使用不记名令牌来验证用户身份
    app.UseOAuthBearerTokens(OAuthOptions);
}

 使用 TokenEndpointPath 属性配置授权服务器的终结点,应用程序通过这个URL获取不记名令牌。使用 Provider 属性配置接入到 OWIN 中间件的提供程序,用来处理中间件引发的事件。

配置使用不记名令牌

在 WebAppiConfig.Register 方法中配置 WebApi 使用不记名令牌。

public static void Register(HttpConfiguration config)
{
    // Web API 配置和服务
    // 将 Web API 配置为仅使用不记名令牌身份验证。
    config.SuppressDefaultHostAuthentication();
    config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

    // Web API 路由
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

这里使用 SuppressDefaultHostAuthentication 方法通知 web api 忽略请求进入webapi管道之前的验证,包括 iis 和 owin 中间件。使用 HostAuthenticationFilter 类对不记名令牌进行验证。

获取令牌

获取令牌的基本步骤为:

  1. 程序请求 ~/Token。
  2. OAuth 中间件调用提供程序的 GrantResourceOwnerCredentials 方法。
  3. 提供程序调用 ApplicationUserManager 验证凭据,创建 claims identity。
  4. 如果验证成功,提供程序创建身份验证票(authentication ticket),身份验证票用于生成令牌。

OAuth 中间件本身不了解用户账户的任何信息。提供程序用来协调中间件和 ASP.NET Identity。

访问资源

  • HostAuthentication 过滤器调用 OAuth 中间件对令牌进行验证
  • 中间件将令牌转换成 claims identity
  • 此时,请求处于已验证但未授权状态
  • authorization 过滤器检查claims identity。如果 claims 授权用户访问这个资源,则请求通过验证。默认情况下,只要请求已被验证,AuthorizeAttribute 就会授权。但是,你可以通过角色或其他声明进行验证。
  • 如果上述步骤成功,控制器返回受保护的资源。否则,返回 401 错误。

 

 

 原文地址:http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api

 

posted @ 2016-07-27 15:24  东北风!  阅读(2808)  评论(0编辑  收藏  举报