OpenIdRelyingParty 响应始终失败

OpenIdRelyingParty response is always Failed

我正在尝试让 OpenId 登录在 ASPX 网络应用程序中运行,但我不知道出了什么问题。

首先这是一个有效的版本,但我不能使用它,因为 Yadis 由于重定向而无法验证依赖方,这会导致 openID 服务器发出类似 "Are you sure you want to send the data to suspicious client?" 的警告。

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        OpenIdRelyingParty openId = new OpenIdRelyingParty();

        IAuthenticationResponse response = openId.GetResponse();
        ValidateLogin(response);

        if (response == null || response.Status != AuthenticationStatus.Authenticated)
        {
            logger.Info("Not logged in.");
            Login(openId); //<-- this is why yadis discovery fails. When parsing the the page finding <meta http-equiv="X-XRDS-Location" content="https://testServer.domain.cz/openidtrial/Content/yadis.xml" />
        }

    }
}

void DoTry(string identifier, Action action)
{
    try
    {
        action();
    }
    catch (Exception exception)
    {
        logger.ErrorException("Error getting response " + identifier, exception);
    }
}

void Login(OpenIdRelyingParty openId)
{
    var request = openId.CreateRequest(Identifier.Parse("https://openId.server.address"));
    request.AddExtension(new ClaimsRequest()
    {
        Nickname = DemandLevel.Request
    });

    logger.Info("sending request");
    request.RedirectToProvider();
}

void ValidateLogin(IAuthenticationResponse response)
{
    logger.Info(string.Format("response is null: {0}", response == null));
    if (response != null)
    {
        logger.Info(string.Format("response status is: {0}", response.Status));
    }
    if (response != null && response.Status == AuthenticationStatus.Authenticated)
    {
        logger.Info("authorization request received");
        logger.Info("ClaimedIdentifier " + response.ClaimedIdentifier);

        //var claimUntrusted = response.GetUntrustedExtension<ClaimsResponse>();
        var claim = response.GetExtension<ClaimsResponse>();
        //logger.Info(string.Format("claimUntrusted is {0}", claimUntrusted != null ? "value" : "null"));
        logger.Info(string.Format("claim is {0}", claim != null ? "value" : "null"));
        DoTry("claim", () => logger.Info("claim nick " + claim.Nickname));
        //DoTry("claim untrusted", () => logger.Info("untrusted claim nick " + claimUntrusted.Nickname));
    }
}

日志文件内容如下:

Info|12:19:06,198|38-|Message:response is null: True| <--start up
Info|12:19:06,214|38-|Message:Not logged in.|
Info|12:19:07,602|38-|Message:sending request| <--auto redirection
Info|12:19:14,248|18-|Message:response is null: True| <-- Yadis discovery
Info|12:19:14,248|18-|Message:Not logged in.|
Info|12:19:14,497|18-|Message:sending request|
Info|12:19:16,853|38-|Message:response is null: True|
Info|12:19:16,853|38-|Message:Not logged in.|
Info|12:19:17,134|38-|Message:sending request|
Info|12:19:17,633|21-|Message:response is null: False|
Info|12:19:17,633|21-|Message:response status is: Failed|
Info|12:19:17,633|21-|Message:Not logged in.|
Info|12:19:17,898|21-|Message:sending request|
Info|12:19:18,085|38-|Message:response is null: True|
Info|12:19:18,085|38-|Message:Not logged in.|
Info|12:19:18,335|38-|Message:sending request|
Info|12:19:19,910|18-|Message:response is null: True|
Info|12:19:19,910|18-|Message:Not logged in.|
Info|12:19:20,176|18-|Message:sending request|
Info|12:19:20,909|38-|Message:response is null: False| <-- successful login
Info|12:19:20,909|38-|Message:response status is: Authenticated|
Info|12:19:20,909|38-|Message:authorization request received|
Info|12:19:20,909|38-|Message:ClaimedIdentifier ***identifier***|
Info|12:19:20,909|38-|Message:claim is value|
Info|12:19:20,909|38-|Message:claim nick testnick|

我试图通过删除自动重定向来解决重定向问题。我添加了一个按钮,它将手动进行重定向。代码的更改部分如下:

protected void Page_Load(object sender, EventArgs e)
{
    //logger.Info(string.Format("request Path: {0}", Request.Url.AbsolutePath));
    //logger.Info(string.Format("Host name: {0}, Host IP: {1}", Request.UserHostName, Request.UserHostAddress));
    if (!IsPostBack)
    {
        OpenIdRelyingParty openId = new OpenIdRelyingParty();

        IAuthenticationResponse response = openId.GetResponse();
        ValidateLogin(response);

        if (response == null || response.Status != AuthenticationStatus.Authenticated)
        {
            logger.Info("Not logged in.");
            //Login(openId);
        }

    }
}

protected void Login_Click(object sender, EventArgs e)
{
    OpenIdRelyingParty openId = new OpenIdRelyingParty();
    Login(openId);
}

但是使用这个的时候,response.Status是always AuthenticationStatus.Failed after authentication

日志文件的内容如下:

Info|12:14:41,481|36-|Message:response is null: True| <--start up
Info|12:14:41,497|36-|Message:Not logged in.|
Info|12:14:55,490|18-|Message:sending request| <--login button clicked
Info|12:15:01,543|18-|Message:response is null: True| <-- yadis discovery
Info|12:15:01,543|18-|Message:Not logged in.|
Info|12:15:03,540|28-|Message:response is null: True|
Info|12:15:03,540|28-|Message:Not logged in.|
Info|12:15:03,633|21-|Message:response is null: False| <-- response received
Info|12:15:03,633|21-|Message:response status is: Failed|
Info|12:15:03,633|21-|Message:Not logged in.|

我还尝试使用 static OpenIdRelyingParty openId 而不是在方法中创建新实例。 - 没有帮助

我也试过在这样的会话中存储 openId - 没有帮助:

OpenIdRelyingParty OpenId
{
    get
    {
        if (HttpContext.Current.Session["openIdSession"] == null)
        {
            logger.Info("Creating OpenId");
            HttpContext.Current.Session["openIdSession"] = new OpenIdRelyingParty();
        }
        return (OpenIdRelyingParty)HttpContext.Current.Session["openIdSession"];
    }
}

有人知道哪里出了问题吗?

我的问题已经解决了。 我从上面的 post 中获取了原始代码(第一个,它是可操作的但不是 "user-friendly" 因为 yadis 发现失败并且我添加了一个显式的 XRDS 请求处理。 添加一个 ashx 处理程序来处理 yadis 可能会更好,但这也有效。

代码如下:

protected void Page_Load(object sender, EventArgs e)
{
    //XRDS request handling that solves the yadis discovery problem
    if (Request.AcceptTypes.Any(a => a.Contains("xrds")))
    {
        Response.Clear();
        Response.ContentType = "application/xrds+xml";
        string path = Server.MapPath(Request.ApplicationPath + "/Content/yadis.xml");
        logger.Info(string.Format("yadis path: {0}", path));
        Response.WriteFile(path);
        Response.End();
        return;
    }

    if (!IsPostBack)
    {
        OpenIdRelyingParty openId = new OpenIdRelyingParty();

        IAuthenticationResponse response = openId.GetResponse();
        ValidateLogin(response);

        if (response == null || response.Status != AuthenticationStatus.Authenticated)
        {
            logger.Info("Not logged in.");
            Login(openId); //<-- this is why yadis discovery failed.
        }

    }
}