最新的 OAuth 2.0 RFC 6749 竟然是2012年发布的。 也从侧面说明了互联网的飞速发展。

四种授权模式

  1. 授权码模式(authorization code)
  2. 隐式授权模式 - 简化模式(implicit grant type)
  3. 密码模式(resource owner password credentials)
  4. 客户端模式(Client Credentials Grant)

可以用的轮子

OAuth 2.0 的规则比 1.0 精简了很多,但是真的根据规则去做代码实现的时候,还是会有点无从下手的感觉。
而且这些也是比较通用的东西,所以直接用 dotnet core 自家的开源实现 Security 就可以。
里面包含了完整的 认证(Authentication) 和 授权(Authorization) 两个部分,还包含一些 Google, Facebook, cookie 等 授权实现 的例子,也是可以直接拿来用的。

使用

因为dotnet core 2.0 相对 1.0 有了很大的改动,所以还是先放下官方文档:limitingidentitybyscheme

下面的示例简介:配置 cookiebearer 两种验证,bearerapi 用,cookie 给普通页面使用。

  1. 添加nuget包

默认添加的 Microsoft.AspNetCore.All(2.0) 包,已经都包含了。有洁癖的自己去摘~

  1. Stratup 里配置和启用 Authentication
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication()
.AddCookie(options => {
options.LoginPath = "/Account/Unauthorized/";
options.AccessDeniedPath = "/Account/Forbidden/";
})
.AddJwtBearer(options => {
options.Audience = "http://localhost:5001/";
options.Authority = "http://localhost:5000/";
});
// ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
// ...
app.UseAuthentication();
// ...
}
  1. 在 Controller 中验证

    1. 只支持 bearer
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    public class UserController : Controller
    1. 同时支持多种验证
    using Microsoft.AspNetCore.Authentication.Cookies;
    using Microsoft.AspNetCore.Authentication.JwtBearer;

    [Authorize(AuthenticationSchemes = MixedAuthSchemes)]
    public class HomeController : Controller
    private const string MixedAuthSchemes = CookieAuthenticationDefaults.AuthenticationScheme + "," + JwtBearerDefaults.AuthenticationScheme;
  2. 自定义规则选择验证方式

    目前没有想到对应的场景,但是应该会有这种奇葩的需求吧。

    // 定义
    services.AddAuthorization(options =>
    {
    options.AddPolicy("Over18", policy =>
    {
    policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
    policy.RequireAuthenticatedUser();
    policy.Requirements.Add(new MinimumAgeRequirement());
    });
    });

    // 使用
    [Authorize(Policy = "Over18")]
    public class RegistrationController : Controller

    // MinimumAgeRequirement 的实现,可以参考下面的代码。
    public class DenyAnonymousAuthorizationRequirement : AuthorizationHandler<DenyAnonymousAuthorizationRequirement>, IAuthorizationRequirement
    {
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DenyAnonymousAuthorizationRequirement requirement)
    {
    var user = context.User;
    var userIsAnonymous = user?.Identity == null || !user.Identities.Any(i => i.IsAuthenticated);
    if (!userIsAnonymous)
    {
    context.Succeed(requirement);
    }
    return Task.CompletedTask;
    }
    }

自己动手

  1. Auth Server Provider
  2. Auth + OpenID