我想在WebForms应用程序中使用WSFederation和OWIN。即使我在所有页面上使用<authorization>
标记拒绝在web.config中进行未经授权的访问,应用程序也不会自动重定向到IDP。
在CookieAuthentication MW的情况下,应用程序会自动重定向到“登录”页面,但在WS-FederationAuth MW的情况下不会这样做。
同样适用于MVC。在MVC应用程序中,在使用[Authorize]属性装饰我的Action时,即使使用WS-FederationAuth MW,应用程序也会自动重定向到IDP。
在WebForms中将401转换为302吗?
我的示例代码:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
});
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = "http://localhost:53785/",
MetadataAddress = metatdataaddress,
}
);
}
答案 0 :(得分:2)
在WebForms应用程序中,您没有任何OWin属性,如[授权],可以告诉Owin身份验证中间件挑战(重定向)您的身份验证提供程序。这很容易解决。
首先,添加一个中间件,检查您的身份是否经过身份验证,如果没有强制质询重定向:
app.Use((context, next) =>
{
if (context.Authentication.User != null &&
context.Authentication.User.Identity != null &&
context.Authentication.User.Identity.IsAuthenticated)
{
return next();
}
else
{
// redirects to your provider
context.Authentication.Challenge(authenticationTypes);
return Task.FromResult(0);
}
});
// note that it has to run in the right stage
app.UseStageMarker(PipelineStage.Authenticate)
然后,如果您使用Cookie身份验证,则应将其设置为默认值。这意味着“如果你找到一个cookie,只要它有效而不是重定向到WsFed提供者就信任它”
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
现在,当从 WsFed 提供程序返回时,需要设置此cookie。对于WebForms,通常必须使用中间件上的通知手动完成。我的经验是.SignIn()不足以标记我们已经过身份验证,因此我们实际上重新建立了身份验证故障单:
new WsFederationAuthenticationOptions
{
Notifications = new WsFederationAuthenticationNotifications
{
SecurityTokenValidated = (notification) =>
{
var identity = notification.AuthenticationTicket.Identity;
var defaultName = identity.FindFirst("<claim-that-identifies-user>");
// Forcefully set a cookie so that the WsFed provider does not have to be consulted on every request as long as this cookie is valid
var ticket = new AuthenticationTicket(response.AuthenticationTicket.Identity, response.AuthenticationTicket.Properties);
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(1));
response.AuthenticationTicket = ticket;
response.OwinContext.Authentication.SignIn(new AuthenticationProperties(), response.AuthenticationTicket.Identity);
// context.Authentication.User.Identity.IsAuthenticated will now be true
return Task.FromResult(notification);
}
},