WebApi OWIN 相同的令牌对两个不同的服务实例有效

WebApi OWIN same token valid for two different instances of service

我已经使用 OWIN 库创建了 WebApi selfhost 服务。除了一些身份验证问题外,一切都很好。我在服务器上启动了两个服务实例,结果发现从一个服务获得的令牌对第二个服务有效!据我所知,令牌由 OWIN 使用一些保护密钥进行验证。问题是:

  1. 如何使密钥对其他服务实例无效?我尝试使用 Generate-MachineKey 生成自定义密钥,但结果是一样的。
  2. OWIN 使用的保护密钥是什么?它存储在某个地方吗?
  3. 此密钥是否因应用程序而异?

设置:

var oAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/token"),
    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(accessTokenExipreMinutes),
    Provider = new AuthorizationServerProvider(),
    AllowInsecureHttp = allowInsecureHttp
};

appBuilder.UseOAuthBearerTokens(oAuthOptions);  

授权服务器提供商:

class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.TryGetFormCredentials(out string clientId, out string clientSecret);

        var result = Validate(clientId, clientSecret);
        if (result)
        {
            context.Validated(clientId);
            return;
        }

        context.Rejected();
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        try
        {
            ClaimsIdentity oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            var props = new AuthenticationProperties();
            var ticket = new AuthenticationTicket(oAuthIdentity, props);

            context.Validated(ticket);
        }
        catch (Exception ex)
        {
            context.Rejected();
        }

        return Task.FromResult(true);
    }
}

OAuthAuthorizationServerOptions 中有一个名为 AccessTokenFormat 的 属性,它将 AuthenticationTicket 转换为 byte[],反之亦然。此选项加密令牌。您可以为不同的应用程序实例使用不同的密钥设置此选项,这样它们就无法读取彼此的令牌。

这就是你设置的方式AccessTokenFormat

using Microsoft.Owin.Security.DataProtection; 
using Microsoft.Owin.Security.DataHandler;

IDataProtector dataProtecter = app.CreateDataProtector("YOUR_KEY");
var ticketDataFormat = new TicketDataFormat(dataProtecter);
new OAuthAuthorizationServerOptions
{
    TicketDataFormat = ticketDataFormat
};

Owin 的默认设置是使用您的 Machine Key 来创建 TicketDataFormat,因此您也可以在 web.config 中为您的实例设置不同的 Machine Key。