WebApi OWIN 相同的令牌对两个不同的服务实例有效
WebApi OWIN same token valid for two different instances of service
我已经使用 OWIN 库创建了 WebApi selfhost 服务。除了一些身份验证问题外,一切都很好。我在服务器上启动了两个服务实例,结果发现从一个服务获得的令牌对第二个服务有效!据我所知,令牌由 OWIN 使用一些保护密钥进行验证。问题是:
- 如何使密钥对其他服务实例无效?我尝试使用 Generate-MachineKey 生成自定义密钥,但结果是一样的。
- OWIN 使用的保护密钥是什么?它存储在某个地方吗?
- 此密钥是否因应用程序而异?
设置:
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。
我已经使用 OWIN 库创建了 WebApi selfhost 服务。除了一些身份验证问题外,一切都很好。我在服务器上启动了两个服务实例,结果发现从一个服务获得的令牌对第二个服务有效!据我所知,令牌由 OWIN 使用一些保护密钥进行验证。问题是:
- 如何使密钥对其他服务实例无效?我尝试使用 Generate-MachineKey 生成自定义密钥,但结果是一样的。
- OWIN 使用的保护密钥是什么?它存储在某个地方吗?
- 此密钥是否因应用程序而异?
设置:
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。