解耦自托管 OWIN 授权服务器
Decouple self-host OWIN authorization server
我有一个自托管的 OWIN 应用程序,配置为授权服务器和信号器资源服务器。
我的客户正在成功获取不记名令牌并在后续调用 signalR 集线器时出示它以供授权。
我的下一步是分离授权服务,以便它可以 运行 在自己的主机上。首先,我创建了一个单独的自托管应用程序,其中仅包含授权服务代码。在我的开发机器上它仍然是一个解决方案,但授权服务和 signalR 资源托管在不同的进程中。
授权流程仍在正常工作。令牌正在到达我的资源服务器,但现在从 signalR 集线器获得 401 未经授权。
在 ASP.Net Web API 中有很多解决此问题的支持,您可以在其中同步 machine.config 文件中的 machine.config 值。但这不是我的架构。 运行作为HttpListener下的自托管应用使用不同的加密方式,默认DPAPI。
似乎没有太多关于在自托管架构中解决这个问题的讨论。我的理论是,即使在同一台机器上的不同进程下,DPAPI 解密也会失败,所以我得到 401.
我想弄清楚是否有一些最小的方法来解决这个问题,或者我是否必须完全重构可能改用 JWT。
编辑:添加一些代码来帮助显示我的设置
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = false,
TokenEndpointPath = new PathString("/account/login"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider()
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
public void ConfigureOAuth(IAppBuilder app)
{
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
Provider = new ApplicationOAuthBearerAuthenticationProvider(),
});
}
发布我自己的解决方案,希望能帮助其他人。
我确实决定实施 JWT 解决方案而不是使用默认解决方案。无论如何,我认为这是更好的架构,将您的令牌加密与 OS 解耦。我使用了这个教程http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/
关键部分是创建您的自定义 OAuthAuthorizationServerProvider 和 ISecureDataFormat 以加密令牌,如教程中所示。这仅显示 OWIN 配置。
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = false,
TokenEndpointPath = new PathString("/account/login"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new JwtAuthorizationServerProvider(),
AccessTokenFormat = new CustomJwtFormat("https://foo.test.com")
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
您可能面临的另一个问题是获取 SignalR 的令牌,其中设置授权 header 并不像您想象的那么简单。碰巧本教程中基于 cookie 的实现也与 JWT 完美配合! http://blog.marcinbudny.com/2014/05/authentication-with-signalr-and-oauth.html#.VmWgMXarSCd
这里还是 OWIN 配置示例。
public void ConfigureOAuth(IAppBuilder app)
{
//app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
//{
// Provider = new ApplicationOAuthBearerAuthenticationProvider()
//});
var issuer = "https://foo.test.com";
var audience = "client_id";
var secret = TextEncodings.Base64Url.Decode("ABCDEF");
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { audience },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
},
Provider = new ApplicationOAuthBearerAuthenticationProvider()
});
}
FWIW,请考虑自托管 OWIN 授权服务器使用 DPAPI 保护,但 ASP.NET 应用程序默认使用 MachineKey 数据保护。
如果您需要让这两者协作,您可以在 OWIN 配置中指定这样的提供程序:
app.SetDataProtectionProvider(new DpapiDataProtectionProvider("myApp"));
只需确保将其添加到 IAppBuilder(两个项目)的两个配置方法中
HTH
我有一个自托管的 OWIN 应用程序,配置为授权服务器和信号器资源服务器。
我的客户正在成功获取不记名令牌并在后续调用 signalR 集线器时出示它以供授权。
我的下一步是分离授权服务,以便它可以 运行 在自己的主机上。首先,我创建了一个单独的自托管应用程序,其中仅包含授权服务代码。在我的开发机器上它仍然是一个解决方案,但授权服务和 signalR 资源托管在不同的进程中。
授权流程仍在正常工作。令牌正在到达我的资源服务器,但现在从 signalR 集线器获得 401 未经授权。
在 ASP.Net Web API 中有很多解决此问题的支持,您可以在其中同步 machine.config 文件中的 machine.config 值。但这不是我的架构。 运行作为HttpListener下的自托管应用使用不同的加密方式,默认DPAPI。
似乎没有太多关于在自托管架构中解决这个问题的讨论。我的理论是,即使在同一台机器上的不同进程下,DPAPI 解密也会失败,所以我得到 401.
我想弄清楚是否有一些最小的方法来解决这个问题,或者我是否必须完全重构可能改用 JWT。
编辑:添加一些代码来帮助显示我的设置
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = false,
TokenEndpointPath = new PathString("/account/login"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider()
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
public void ConfigureOAuth(IAppBuilder app)
{
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
Provider = new ApplicationOAuthBearerAuthenticationProvider(),
});
}
发布我自己的解决方案,希望能帮助其他人。
我确实决定实施 JWT 解决方案而不是使用默认解决方案。无论如何,我认为这是更好的架构,将您的令牌加密与 OS 解耦。我使用了这个教程http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/
关键部分是创建您的自定义 OAuthAuthorizationServerProvider 和 ISecureDataFormat 以加密令牌,如教程中所示。这仅显示 OWIN 配置。
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = false,
TokenEndpointPath = new PathString("/account/login"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new JwtAuthorizationServerProvider(),
AccessTokenFormat = new CustomJwtFormat("https://foo.test.com")
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
您可能面临的另一个问题是获取 SignalR 的令牌,其中设置授权 header 并不像您想象的那么简单。碰巧本教程中基于 cookie 的实现也与 JWT 完美配合! http://blog.marcinbudny.com/2014/05/authentication-with-signalr-and-oauth.html#.VmWgMXarSCd
这里还是 OWIN 配置示例。
public void ConfigureOAuth(IAppBuilder app)
{
//app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
//{
// Provider = new ApplicationOAuthBearerAuthenticationProvider()
//});
var issuer = "https://foo.test.com";
var audience = "client_id";
var secret = TextEncodings.Base64Url.Decode("ABCDEF");
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { audience },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
},
Provider = new ApplicationOAuthBearerAuthenticationProvider()
});
}
FWIW,请考虑自托管 OWIN 授权服务器使用 DPAPI 保护,但 ASP.NET 应用程序默认使用 MachineKey 数据保护。
如果您需要让这两者协作,您可以在 OWIN 配置中指定这样的提供程序:
app.SetDataProtectionProvider(new DpapiDataProtectionProvider("myApp"));
只需确保将其添加到 IAppBuilder(两个项目)的两个配置方法中
HTH