重定向循环与 .Net MVC 授权属性与 ADFS 声明
Redirect loop with .Net MVC Authorize attribute with ADFS Claims
我在使用 .Net MVC 5 应用程序配置 ADFS 时遇到问题。
我已经在 VS 2015 中配置我的项目以使用声明并且它工作正常,但我有一个问题。
我可以登录,使用 ADFS,我可以检查用户角色等。当我尝试使用
时出现问题
[Authorize(Roles="somenonExistingRole")]
尽管我已经通过身份验证,但我被重定向到 ADFS 页面,当再次进行身份验证时,我被重定向到我的页面,在该页面发生循环。页面将我发送到 ADFS 门户,ADFS 将我重定向到门户,尝试几次后我从 ADFS 收到错误(针对许多请求)
我必须自己实现像角色提供者这样的东西吗?或者我需要配置一些额外的东西。也许我可以限制尝试次数?为什么在我的角色准备就绪后我会被重定向到 ADFS?
代码中实际上没有太多要显示的内容,按要求提供:
我正在测试的控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[Authorize]
public ActionResult About()
{
var u = HttpContext.User;
if (u.IsInRole("/"))
{
ViewBag.Message = "User is in role.";
}
else
{
ViewBag.Message = "User is NOT in role.";
}
return View();
}
[Authorize(Roles = "/nonexistingRole")]
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
和配置身份验证部分
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = adfsMetadata,
});
}
要解决循环问题,您应该重写 AuthorizeAttribute
。
默认情况下,当用户的角色不满足 AuthorizeAttribute
要求时,MVC returns 401 未授权。这将向身份提供者初始化重新身份验证请求。由于用户已经登录,AAD returns 到同一页面,然后发出另一个 401, 创建重定向循环 。在这里,我们覆盖了 AuthorizeAttribute 的 HandleUnauthorizedRequest 方法以显示在我们的应用程序上下文中有意义的内容。
这个class是在使用VS 2015创建一个新的MVC项目时生成的:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
//One Strategy:
//filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
//Another Strategy:
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new
{
controller = "Error",
action = "ShowError",
errorMessage = "You do not have sufficient priviliges to view this page."
})
);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
我在使用 .Net MVC 5 应用程序配置 ADFS 时遇到问题。
我已经在 VS 2015 中配置我的项目以使用声明并且它工作正常,但我有一个问题。
我可以登录,使用 ADFS,我可以检查用户角色等。当我尝试使用
时出现问题[Authorize(Roles="somenonExistingRole")]
尽管我已经通过身份验证,但我被重定向到 ADFS 页面,当再次进行身份验证时,我被重定向到我的页面,在该页面发生循环。页面将我发送到 ADFS 门户,ADFS 将我重定向到门户,尝试几次后我从 ADFS 收到错误(针对许多请求)
我必须自己实现像角色提供者这样的东西吗?或者我需要配置一些额外的东西。也许我可以限制尝试次数?为什么在我的角色准备就绪后我会被重定向到 ADFS?
代码中实际上没有太多要显示的内容,按要求提供: 我正在测试的控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[Authorize]
public ActionResult About()
{
var u = HttpContext.User;
if (u.IsInRole("/"))
{
ViewBag.Message = "User is in role.";
}
else
{
ViewBag.Message = "User is NOT in role.";
}
return View();
}
[Authorize(Roles = "/nonexistingRole")]
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
和配置身份验证部分
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = adfsMetadata,
});
}
要解决循环问题,您应该重写 AuthorizeAttribute
。
默认情况下,当用户的角色不满足 AuthorizeAttribute
要求时,MVC returns 401 未授权。这将向身份提供者初始化重新身份验证请求。由于用户已经登录,AAD returns 到同一页面,然后发出另一个 401, 创建重定向循环 。在这里,我们覆盖了 AuthorizeAttribute 的 HandleUnauthorizedRequest 方法以显示在我们的应用程序上下文中有意义的内容。
这个class是在使用VS 2015创建一个新的MVC项目时生成的:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
//One Strategy:
//filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
//Another Strategy:
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new
{
controller = "Error",
action = "ShowError",
errorMessage = "You do not have sufficient priviliges to view this page."
})
);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}