SSO - 未找到OpenID端点

时间:2012-09-13 17:02:08

标签: c# asp.net-mvc openid single-sign-on dotnetopenauth

我正在努力让SSO openid与dotnetopenauth合作。

我有两个单独的项目,分别进行调试(在localhost上但有两个不同的端口),一个充当提供者,一个充当依赖方。

依赖方正在localhost:1903上运行。 提供程序正在localhost:3314上运行。

依赖方代码:

    public ActionResult Authenticate()
    {
        UriBuilder returnToBuilder = new UriBuilder(Request.Url);
        returnToBuilder.Path = "/OpenId/";
        returnToBuilder.Query = null;
        returnToBuilder.Fragment = null;

        Uri returnTo = returnToBuilder.Uri;
        returnToBuilder.Path = "/";
        Realm realm = returnToBuilder.Uri;
        realm = "http://localhost:3314/OpenId/";
        returnTo = new Uri("http://localhost:3314/OpenId/");
        var response = openid.GetResponse();

        if (response == null) {
            if (Request.QueryString["ReturnUrl"] != null && User.Identity.IsAuthenticated) {
            } else {
                string strIdentifier = "testidentifier";
                var request = openid.CreateRequest(
                    strIdentifier,
                    realm,
                    returnTo);

                var fetchRequest = new FetchRequest();
                request.AddExtension(fetchRequest);
                request.RedirectToProvider();
            }
        } else {
            switch (response.Status) {
                case AuthenticationStatus.Canceled:
                    //stuff got cancelled for some reason
                    break;
                case AuthenticationStatus.Failed:
                    //response.Exception.Message;
                    break;
                case AuthenticationStatus.Authenticated:
                    //a bunch of applying roles that i don't think we care about
                    break;
            }
        }

        return new EmptyResult();
    }

提供商代码:

    public ActionResult Index()
    {
        IAuthenticationRequest iR = (IAuthenticationRequest)Request;

        if (iR.IsReturnUrlDiscoverable(ProviderEndpoint.Provider.Channel.WebRequestHandler) != RelyingPartyDiscoveryResult.Success) {
            iR.IsAuthenticated = false;
            return new EmptyResult();
        }

        if (iR.IsDirectedIdentity) {
            if (User.Identity.IsAuthenticated) {
                iR.LocalIdentifier = BuildIdentityUrl();
                iR.IsAuthenticated = true;
            } else {
                if (iR.Immediate || ImplicitAuth) {
                    iR.IsAuthenticated = false;
                } else {
                    if (!Request.Path.EndsWith("Login", StringComparison.OrdinalIgnoreCase)) {
                        return RedirectToAction("Login", "User");
                    }
                }
            }
        } else {
            string userOwningOpenIdUrl = ExtractUserName(iR.LocalIdentifier);

            iR.IsAuthenticated = userOwningOpenIdUrl == User.Identity.Name;

            if (!iR.IsAuthenticated.Value && !ImplicitAuth && !iR.Immediate) {
                if (!Request.Path.EndsWith("Login", StringComparison.OrdinalIgnoreCase)) {
                    return RedirectToAction("Login", "User");
                }
            }
        }

        if (iR.IsAuthenticated.Value) {
            var fetchRequest = iR.GetExtension<FetchRequest>();

            if (fetchRequest != null) {
                var fetchResponse = new FetchResponse();
                //roles and stuff

                iR.AddResponseExtension(fetchResponse);
            }
        }

        return new EmptyResult();
    }

我在openid.CreateRequest方法上运行依赖方代码时收到错误。我启用了我的提供程序代码的调试,它永远不会被命中。

研究错误,我发现了很多关于代理问题的建议,但这对我来说应该不是问题,因为我只会去localhost。

也许这是相当明显的事情,但我不知道自己做错了什么。

提前感谢您的帮助!

编辑:仅供参考,我从DotNetOpenAuth样本中获得了此代码。

3 个答案:

答案 0 :(得分:2)

好吧,我最终手动逐步完成了源代码并稍微弄清了问题。

原来dumdum有些正确 - 我的第一个问题是它确实需要一个URI作为标识符,所以一旦我将我的标识符更改为http://localhost:3314/OpenId/(即使这本身无效)我已经克服了那个例外。

第二个问题是我忘了向web.config添加信息 - 因此localhost未列入白名单,CreateRequest在那里失败。

在我解决了这两个问题之后,我的提供商代码被打得很好 - 我在那里遇到了其他错误,但那是我想象的单独问题。

Web.Config中:

<configSections>
  <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth">
    <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/>
    <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/>
    <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/>
    <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true"/>
    </sectionGroup>
</configSections>

<dotNetOpenAuth>
<openid>
  <relyingParty>
    <security requireSsl="false">
      <!-- Uncomment the trustedProviders tag if your relying party should only accept positive assertions from a closed set of OpenID Providers. -->
      <!--<trustedProviders rejectAssertionsFromUntrustedProviders="true">
        <add endpoint="https://www.google.com/accounts/o8/ud" />
      </trustedProviders>-->
    </security>
    <behaviors>
      <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
           with OPs that use Attribute Exchange (in various formats). -->
      <add type="DotNetOpenAuth.OpenId.RelyingParty.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth"/>
      <!--<add type="DotNetOpenAuth.OpenId.RelyingParty.Behaviors.GsaIcamProfile, DotNetOpenAuth" />-->
    </behaviors>
    <!-- Uncomment the following to activate the sample custom store.  -->
    <!--<store type="OpenIdRelyingPartyWebForms.CustomStore, OpenIdRelyingPartyWebForms" />-->
  </relyingParty>
</openid>
<messaging>
  <untrustedWebRequest>
    <whitelistHosts>
      <!-- since this is a sample, and will often be used with localhost -->
      <add name="localhost"/>
    </whitelistHosts>
  </untrustedWebRequest>
</messaging>
<!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
<reporting enabled="true"/>
</dotNetOpenAuth>

答案 1 :(得分:1)

我不确定你是否和我有同样的问题,但是......对于我来说,如果我输入类似“bob”这样的用户名,我就会出现这个错误。当我输入有效的开放ID,例如dumdum@yahoo.com时,它已经过了这个问题。似乎需要关闭完全不可能的开放ID的异常处理。

答案 2 :(得分:0)

我最近遇到了同样的问题,事实证明问题不在我的应用程序中,而是在openID服务器端。 当调用openID服务器时,它返回500 - 内部服务器错误,我的应用程序引发协议异常 - 在openId.CreateRequest(Identifier.Parse(openIdServer))行找不到OpenID端点。

我联系了修复内部服务器错误的OpenID服务器的管理员,一切正常(如错误)。

为什么DotNetOpenAuth会提出这样一个愚蠢的例外,这是一个问题......