如何在 OWIN 应用程序中使用 cookie 身份验证和 WsFederation 身份验证
How to use cookie authentication with WsFederation authentication in OWIN app
我正在制作一个 OWIN 应用程序来自行托管网站。我在身份验证部分遇到问题。我正在寻找的基本流程是:
- 检查请求是否有正确的 cookie。如果它有正确的 cookie,则获取
SecuritySessionToken
并构建 ClaimsIdentity
,然后 return AuthenticationTicket
.
- 如果 cookie 不存在,请告知 STS。
- 从 STS 获取 SAML 令牌并构建声明和身份验证票证。 (虽然我用的是WsFederation认证,这里不涉及ADFS。)
第 1 步对我来说效果很好。第 2 步和第 3 步是我遇到问题的地方。
这是我在启动时的配置方法class:
public void Configuration(IAppBuilder app)
{
CookieAuthenticationOptions options = new CookieAuthenticationOptions
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
CookieName = "MyCookieName",
CookiePath = "/cookiePath",
AuthenticationMode = AuthenticationMode.Active
};
// Not relevant how this module is made. It helps with
SessionAuthenticationModule module = this.CreateModule();
app.Use(typeof(MyCookieAuthenticationMiddleware), app, options, module);
WsFederationConfiguration fedConfig = new WsFederationConfiguration();
fedConfig.Issuer = "https://mySTS.com/NotRealUrl/";
SecurityTokenHandlerCollection handlerCollection = new SecurityTokenHandlerCollection(new List<SecurityTokenHandler>() { new SamlSecurityTokenHandler() });
WsFederationAuthenticationOptions wsFederationOptions = new WsFederationAuthenticationOptions
{
Configuration = fedConfig,
Wtrealm = "http://localhost/MyApp/NotRealUrl",
Wreply = "https://mySTS.com/NotRealUrl/Login",
SecurityTokenHandlers = handlerCollection,
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
};
app.Use(typeof(MyWsFederationAuthenticationMiddleware), app, wsFederationOptions);
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.Use<MyMiddleware>();
}
app.Use(typeof(MyCookieAuthenticationMiddleware), app, options, module);
之前的部分工作正常。也就是说,当 cookie 存在时,我使用自定义 cookie 身份验证中间件 (MyCookieAuthenticationMiddleware
) 生成 AuthenticationTicket
.
不起作用的部分是WsFederation身份验证中间件部分。我为此创建了自己的中间件 (MyWsFederationAuthenticationMiddleware
),这样我就可以查看发生了什么,因为直接 app.UseWsFederationAuthentication(wsFederationOptions)
对我不起作用。我正在查看 WsFederationAuthenticationHandler.cs
的源代码来指导我,但我仍然对一些总体概念感到困惑。
问题
- 我想我知道一般流程应该是什么(我在
顶部),但我不确定这如何准确地转化为
中间件管道。如果我没有 cookie,那么我会发现这个
在
AuthenticateCoreAsync()
在 MyCookieAuthenticationHandler
。但
我什么时候将其重定向到 STS 以获取 SAML 令牌?
我是否只是等待管道达到 AuthenticateCoreAsync()
MyWsFederationAuthenticationHandler
,如果用户不是
通过身份验证,然后获取令牌?
- 我实际上如何告诉它需要获取令牌的管道
来自STS?再看看
WsFederationAuthenticationHandler.cs
,好像他们的
ApplyResponseChallengeAsync()
的实施可能正在做
我想要的是?更具体地说,如果它是 401 状态代码,则
a WsFederationMessage
并使用该消息重定向到 STS?
- 假设我实际上可以将 STS 获取到 return 我想要的令牌,
return 到管道的哪个位置?
感谢和抱歉这么长的 post。
更新 1
我忘了说,当我 运行 我的代码使用 app.UseWsFederationAuthentication(wsFederationOptions)
(而不是我自己的 MyWsFederationAuthenticationMiddleware
)时,我得到了 400 "bad request - request too long" 错误。 URL 很长,看起来包含各种查询参数,包括 wtrealm、wctx、wa 和 wreply,每个参数都包含 url 编码的字符串。看起来 wctx 真的很长。我想这是一些 base64 编码的对象。不幸的是我真的不知道发生了什么。
我认为,问题是,两个中间件都有 AuthenticationMode
Active
您应该将 CookieAuthenticationOptions.AuthenticationType
更改为 CookieAuthenticationDefaults.AuthenticationType
,然后将 WsFederationAuthenticationOptions.AuthenticationMode
设置为被动。
我推荐一个自定义控制器。如果用户访问此控制器,您必须为 WsFederationAuthenticationDefaults.AuthenticationType
和 return 和 401 手动触发 OwinContext.Authentication
上的身份验证。这应该触发 [=18= 中的 ApplyResponseChallengeAsync
]
在 WsFederationAuthenticationOptions.Notifications
的 SecurityTokenValidated
方法中,您可以使用 CookieAuthenticationDefaults.AuthenticationType
类型的身份发出新的 AuthTicket。
现在,来自身份提供者的身份已通过 cookieauth 转换为本地身份。
我正在制作一个 OWIN 应用程序来自行托管网站。我在身份验证部分遇到问题。我正在寻找的基本流程是:
- 检查请求是否有正确的 cookie。如果它有正确的 cookie,则获取
SecuritySessionToken
并构建ClaimsIdentity
,然后 returnAuthenticationTicket
. - 如果 cookie 不存在,请告知 STS。
- 从 STS 获取 SAML 令牌并构建声明和身份验证票证。 (虽然我用的是WsFederation认证,这里不涉及ADFS。)
第 1 步对我来说效果很好。第 2 步和第 3 步是我遇到问题的地方。
这是我在启动时的配置方法class:
public void Configuration(IAppBuilder app)
{
CookieAuthenticationOptions options = new CookieAuthenticationOptions
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
CookieName = "MyCookieName",
CookiePath = "/cookiePath",
AuthenticationMode = AuthenticationMode.Active
};
// Not relevant how this module is made. It helps with
SessionAuthenticationModule module = this.CreateModule();
app.Use(typeof(MyCookieAuthenticationMiddleware), app, options, module);
WsFederationConfiguration fedConfig = new WsFederationConfiguration();
fedConfig.Issuer = "https://mySTS.com/NotRealUrl/";
SecurityTokenHandlerCollection handlerCollection = new SecurityTokenHandlerCollection(new List<SecurityTokenHandler>() { new SamlSecurityTokenHandler() });
WsFederationAuthenticationOptions wsFederationOptions = new WsFederationAuthenticationOptions
{
Configuration = fedConfig,
Wtrealm = "http://localhost/MyApp/NotRealUrl",
Wreply = "https://mySTS.com/NotRealUrl/Login",
SecurityTokenHandlers = handlerCollection,
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
};
app.Use(typeof(MyWsFederationAuthenticationMiddleware), app, wsFederationOptions);
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.Use<MyMiddleware>();
}
app.Use(typeof(MyCookieAuthenticationMiddleware), app, options, module);
之前的部分工作正常。也就是说,当 cookie 存在时,我使用自定义 cookie 身份验证中间件 (MyCookieAuthenticationMiddleware
) 生成 AuthenticationTicket
.
不起作用的部分是WsFederation身份验证中间件部分。我为此创建了自己的中间件 (MyWsFederationAuthenticationMiddleware
),这样我就可以查看发生了什么,因为直接 app.UseWsFederationAuthentication(wsFederationOptions)
对我不起作用。我正在查看 WsFederationAuthenticationHandler.cs
的源代码来指导我,但我仍然对一些总体概念感到困惑。
问题
- 我想我知道一般流程应该是什么(我在
顶部),但我不确定这如何准确地转化为
中间件管道。如果我没有 cookie,那么我会发现这个
在
AuthenticateCoreAsync()
在MyCookieAuthenticationHandler
。但 我什么时候将其重定向到 STS 以获取 SAML 令牌? 我是否只是等待管道达到AuthenticateCoreAsync()
MyWsFederationAuthenticationHandler
,如果用户不是 通过身份验证,然后获取令牌? - 我实际上如何告诉它需要获取令牌的管道
来自STS?再看看
WsFederationAuthenticationHandler.cs
,好像他们的ApplyResponseChallengeAsync()
的实施可能正在做 我想要的是?更具体地说,如果它是 401 状态代码,则 aWsFederationMessage
并使用该消息重定向到 STS? - 假设我实际上可以将 STS 获取到 return 我想要的令牌, return 到管道的哪个位置?
感谢和抱歉这么长的 post。
更新 1
我忘了说,当我 运行 我的代码使用 app.UseWsFederationAuthentication(wsFederationOptions)
(而不是我自己的 MyWsFederationAuthenticationMiddleware
)时,我得到了 400 "bad request - request too long" 错误。 URL 很长,看起来包含各种查询参数,包括 wtrealm、wctx、wa 和 wreply,每个参数都包含 url 编码的字符串。看起来 wctx 真的很长。我想这是一些 base64 编码的对象。不幸的是我真的不知道发生了什么。
我认为,问题是,两个中间件都有 AuthenticationMode
Active
您应该将 CookieAuthenticationOptions.AuthenticationType
更改为 CookieAuthenticationDefaults.AuthenticationType
,然后将 WsFederationAuthenticationOptions.AuthenticationMode
设置为被动。
我推荐一个自定义控制器。如果用户访问此控制器,您必须为 WsFederationAuthenticationDefaults.AuthenticationType
和 return 和 401 手动触发 OwinContext.Authentication
上的身份验证。这应该触发 [=18= 中的 ApplyResponseChallengeAsync
]
在 WsFederationAuthenticationOptions.Notifications
的 SecurityTokenValidated
方法中,您可以使用 CookieAuthenticationDefaults.AuthenticationType
类型的身份发出新的 AuthTicket。
现在,来自身份提供者的身份已通过 cookieauth 转换为本地身份。