首页 文章

使用WebApi中的OAuth Bearer Tokens Generation和Owin将更多信息返回给客户端

提问于
浏览
58

我创建了一个WebApi和一个Cordova应用程序 . 我正在使用HTTP请求在Cordova应用程序和WebAPI之间进行通信 . 在WebAPI中,我实现了OAuth Bearer Token Generation .

public void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider(new UserService(new Repository<User>(new RabbitApiObjectContext()), new EncryptionService()))
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }

这是在 SimpleAuthorizationServerProvider 实现中

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
       context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

        // A little hack. context.UserName contains the email
        var user = await _userService.GetUserByEmailAndPassword(context.UserName, context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant", "Wrong email or password.");
            return;
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim("sub", context.UserName));
        identity.AddClaim(new Claim("role", "user"));

        context.Validated(identity);
    }

在从Cordova应用程序成功登录API后,我收到以下JSON

{"access_token":"some token","token_type":"bearer","expires_in":86399}

问题是,我需要有关用户的更多信息 . 例如,我在数据库中有一个UserGuid字段,我希望在登录成功后将其发送到Cordova应用程序,并在以后的其他请求中使用它 . 除了 "access_token", "token_type""expires_in" 之外,我可以包含其他信息以返回客户端吗?如果没有,我如何根据 access_token 获取API中的用户?


EDIT:

我想我找到了一个解决方法 . 我在 GrantResourceOwnerCredentials 中添加了以下代码

identity.AddClaim(new Claim(ClaimTypes.Name, user.UserGuid.ToString()));

之后,我像这样访问控制器内的GUID: User.Identity.Name

我也可以用自定义名称添加guid identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));

我仍然有兴趣知道是否有办法使用持票人令牌JSON将更多数据返回给客户端 .

2 回答

  • 41

    您可以根据需要添加任意数量的声明 .
    您可以从 System.Security.Claims 添加标准的声明集,也可以创建自己的声明集 .
    声明将在您的令牌中加密,因此只能从资源服务器访问它们 .

    如果您希望客户端能够读取令牌的扩展属性,则可以选择其他选项: AuthenticationProperties .

    假设您想添加一些内容,以便您的客户可以访问 . 这是要走的路:

    var props = new AuthenticationProperties(new Dictionary<string, string>
    {
        { 
            "surname", "Smith"
        },
        { 
            "age", "20"
        },
        { 
        "gender", "Male"
        }
    });
    

    现在,您可以使用上面添加的属性创建故障单:

    var ticket = new AuthenticationTicket(identity, props);
    context.Validated(ticket);
    

    这是您的客户将获取的结果:

    .expires: "Tue, 14 Oct 2014 20:42:52 GMT"
    .issued: "Tue, 14 Oct 2014 20:12:52 GMT"
    access_token: "blahblahblah"
    expires_in: 1799
    age: "20"
    gender: "Male"
    surname: "Smith"
    token_type: "bearer"
    

    另一方面,如果添加声明,您将能够在API控制器的资源服务器中读取它们:

    public IHttpActionResult Get()
    {
        ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
    
        return Ok();
    }
    

    您的 ClaimsPrincipal 将包含您在此处添加的新版权声明 guid

    identity.AddClaim(new Claim("guid", user.UserGuid.ToString()));
    

    如果你想了解更多关于owin,bearer tokens和web api的信息,那么有一个非常好的教程here,这个article将帮助你掌握 Authorization ServerResource Server 背后的所有概念 .

    UPDATE

    你可以找到一个有效的例子here . 这是一个自我托管的 Web Api Owin .
    还有's no database involved here. The client is a console application (there'是一个html JavaScript示例),它调用Web Api传递凭据 .

    正如Taiseer建议的那样,你需要覆盖 TokenEndpoint

    public override Task TokenEndpoint(OAuthTokenEndpointContext context)
    {
        foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
        {
            context.AdditionalResponseParameters.Add(property.Key, property.Value);
        }
    
        return Task.FromResult<object>(null);
    }
    

    从解决方案 - >属性启用'Multiple Startup Projects',您可以立即运行它 .

  • 84

    如果不需要,我建议不要在令牌上添加额外的声明,因为会增加令牌的大小,并且您将继续发送每个请求 . 由于LeftyX建议将它们添加为属性,但请确保在成功获取令牌时覆盖 TokenEndPoint 方法以将这些属性作为响应,没有此终点,属性将不会在响应中返回 .

    public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }
    
            return Task.FromResult<object>(null);
        }
    

    您可以在此处查看my repo以获取完整示例 . 希望它会有所帮助 .

相关问题