使用ADFS和ASP.NET MVC时,如果未授权用户,则将用户重定向到自定义页面

时间:2015-09-03 14:27:43

标签: asp.net-mvc adfs

我的ADFS配置排除了不属于一组组的所有用户。

在某些情况下,用户使用ADFS登录到Web应用程序(Web应用程序B),并且会获得一组不包含Web应用程序A中接受的任何组的声明。

用户然后转到Web应用程序A,重定向到ADFS,用户已经有一个用于ADFS的cookie,因此他不会被要求提供新的用户/密码组合,并且他会立即使用相同的声明进行重定向(Web应用程序) B的主张)到网络应用程序A.

这将触发网络应用A中的401,这是正确的。

我们如何将用户重定向到解释刚刚发生的事情的页面(使用“使用其他帐户登录”按钮)?

作为参考,排除所有不属于一组组的用户的web.config配置是:

<authentication mode="None" />
<authorization>
  <allow roles="GroupA,GroupB,GroupC,GroupD"/>
  <deny users="*" />
</authorization>

2 个答案:

答案 0 :(得分:0)

指定要重定向到401的页面:

<customErrors mode="On">
    <error code="401" path="401.cshtml" />
</customErrors>

在401页面中执行您的授权。

答案 1 :(得分:0)

如果有人必须处理此问题,我就是这样展示自定义未经授权的页面。

创建一个自定义的未经授权的页面,可能会在那里放一个注销按钮,我把它放在ErrorController中并将操作命名为Unauthorized。

第一个“白名单”是web.config中自定义的“您未经授权”页面

<location path="Error/Unauthorized">
    <system.web>
        <authorization>
            <allow Users="*"/>
        </authorization>
    </system.web>
</location>

注意:如果您使用resharper,它将突出显示路径“Error / Unauthorized”不存在。只是忽略它,这是因为如果你使用webforms,路径将映射到物理文件,但MVC不是这种情况。

如果您想允许用户注销以便他/她可以使用其他帐户登录,您还应该设置一个注销网址,因为没有任何组的要求:

<location path="Home/Logout">
    <system.web>
        <authorization>
            <allow Users="*"/>
        </authorization>
    </system.web>
</location> 

您现在应该使用401 Unauthorized来处理到达“管道”末尾的请求,其中用户已经过身份验证,并将其重定向到自定义的未经授权的页面:

在global.asax中注册EndRequest上的事件并进行检查,将响应更改为302 Found(临时重定向)到自定义的未授权页面:

构造函数:

protected MvcApplication(){
  EndRequest+=(s, e) => 
  {
    if (Response.StatusCode == 401 && User.Identity.IsAuthenticated)
    {
      Response.StatusCode = 302;
      Response.Headers.Add("Location", VirtualPathUtility.ToAbsolute("~/Error/Unauthorized"));
    }
  }
}

System.Web.VirtualPathUtility在这里非常有用,因为它会扩展〜并生成完整的URL

位置标头只是浏览器获得302响应时使用的标头名称。然后它将对URL进行请求,即标头值。

我确信WSFederationAuthenticationModule会通过web.config中的设置来满足这种情况,但我真的找不到它。

这里的参考是将web.config中的所有设置放在一起:

<configuration>
 ...
    <location path="Error/Unauthorized">
        <system.web>
            <authorization>
                <allow Users="*"/>
            </authorization>
        </system.web>
    </location>
    <location path="Home/Logout">
        <system.web>
            <authorization>
                <allow Users="*"/>
            </authorization>
        </system.web>
    </location> 
    <system.web>
        <authentication mode="None" />
        <authorization>
           <allow roles="GroupA,GroupB,GroupC,GroupD"/>
           <deny users="*" />
        </authorization>
        ...
    </system.web>
    <system.identityModel>
    ....