【问题标题】:Redirect user to custom page when s/he is not authorized when using ADFS and ASP.NET MVC使用 ADFS 和 ASP.NET MVC 时,当他/他未被授权时将用户重定向到自定义页面
【发布时间】:2015-09-03 14:27:43
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

    标签: asp.net-mvc adfs


    【解决方案1】:

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

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

    在 401 页面中做你的授权工作。

    【讨论】:

    • 不幸的是,这不起作用。在这种情况下使用的实际错误代码是 401.2,它似乎永远不会与 customErrors 的 401 匹配。另外我相信它是 redirect 而不是 path,您不能直接重定向到 .cshtml 页面(没有 http处理程序)。控制器操作可以(redirect="Error/Unauthorized"),但再次尝试,重定向永远不会发生。
    【解决方案2】:

    如果有人不得不处理这个问题,这就是我要显示自定义未经授权页面的方式。

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

    首先将 web.config 中的自定义“您未被授权”页面“列入白名单”

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

    注意:如果您使用 resharper,它将突出显示“错误/未授权”路径不存在。忽略它,这是因为如果您使用网络表单,该路径将映射到物理文件,但使用 MVC 时,情况并非如此。

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

    <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>
        ....
    

    【讨论】:

      猜你喜欢
      • 2011-06-17
      • 1970-01-01
      • 2012-06-11
      • 2012-10-28
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 2014-03-31
      相关资源
      最近更新 更多