代码之家  ›  专栏  ›  技术社区  ›  superfly71

剖析ASP。OAuth承载者身份验证的NET MVC标识

  •  0
  • superfly71  · 技术社区  · 8 年前

    我正在学习如何放置Asp。Net MVC Identity 2.0工作。

    我有一个适用于OAuth Bearer的代码

        [HttpGet]
        [ActionName("Authenticate")]
        [AllowAnonymous]
        public String Authenticate(string user, string password)
        {
            if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(password))
            {
                return "Failed";
            }
    
            var userIdentity = UserManager.FindAsync(user, password).Result;
            if (userIdentity != null)
            {
                if (User.Identity.IsAuthenticated)
                {
                    return "Already authenticated!";
                }
    
                var identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
                identity.AddClaim(new Claim(ClaimTypes.Name, user));
                identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userIdentity.Id));
    
                AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
                var currentUtc = new SystemClock().UtcNow;
                ticket.Properties.IssuedUtc = currentUtc;
                ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(1));
    
                string AccessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
                return AccessToken;
            }
            return "Failed in the end";
        }
    

    这是Startup.Auth.cs的代码

        //This will used the HTTP header Authorization: "Bearer 1234123412341234asdfasdfasdfasdf"
        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    

    我已经查看了ClaimsIdentity和AuthenticationTicket的源代码,但我不知道如何为该身份注册票据。

    我的问题是,这张票是如何在欧文管道上注册的?

    如果可能的话,我的目标是撤销这张罚单。

    提前谢谢。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Community    7 年前

    首先,这里有一个 great tutorial on ASP.NET Identity 2 Taiseer Joudeh著。

    这是将承载令牌处理添加到OWIN应用程序管道的行。

    app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    

    此外,您自己编写了授权提供程序吗?我的启动代码看起来更像这样:

    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
    
    PublicClientId = "self";
    OAuthServerOptions = new OAuthAuthorizationServerOptions
    {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/Token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1440),     //TODO: change to smaller value in production, 15 minutes maybe
        Provider = new SimpleAuthorizationServerProvider(PublicClientId),
        RefreshTokenProvider = new SimpleRefreshTokenProvider()
    };
    
    app.UseOAuthAuthorizationServer(OAuthServerOptions);
    
    OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
    app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    

    然后,My SimpleAuthorizationServerProvider具有如下Grant方法:

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin") ?? "*";
    
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
    
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
    
        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
    
        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }
    
        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
        identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        identity.AddClaim(new Claim("sub", context.UserName));
    
        foreach (var role in userManager.GetRoles(user.Id))
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role));
        }
    
        var props = new AuthenticationProperties(new Dictionary<string, string>
        {
            {"as:client_id", context.ClientId ?? string.Empty}
        });
    
        var ticket = new AuthenticationTicket(identity, props);
        context.Validated(ticket);
    }
    

    几乎所有这些都是基于上面提到的教程。希望能有所帮助。

    使现代化 根据Taiseer的说法,没有标准的方式来撤销代币 on this page .

    正在从经过身份验证的用户撤消访问: 一旦用户获得长期访问令牌,就可以访问服务器资源 只要他的访问令牌未过期,就没有标准的方法 撤销访问令牌,除非授权服务器实现 强制您将生成的访问令牌存储在中的自定义逻辑 数据库并对每个请求进行数据库检查。但随着刷新 令牌,系统管理员可以通过删除 从数据库刷新令牌标识符,以便一旦系统请求 使用已删除刷新令牌的新访问令牌,授权 服务器将拒绝此请求,因为刷新令牌不再 可用(我们将提供更多详细信息)。

    然而 here is an interesting approach 这可能会满足你的需要。它只需要一点定制实现。