如何使用ASP.NET中MVC4唯一标识符的URL OpenID提供 [英] How to use OpenID providers with unique identifier URLs in ASP.NET MVC4

查看:1153
本文介绍了如何使用ASP.NET中MVC4唯一标识符的URL OpenID提供的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新的 SimpleMembershipProvider 在ASP.NET MVC4可以方便,内置支持两个流行的OpenID提供商(谷歌和雅虎)和三个OAuth的供应商(微软,Facebook的实施, 推特)。

The new SimpleMembershipProvider implemented in ASP.NET MVC4 allows easy, built-in support for two popular OpenID providers (Google and Yahoo) and three OAuth providers (Microsoft, Facebook, Twitter).

在<一个实现的供应商href=\"https://github.com/DotNetOpenAuth/DotNetOpenAuth/tree/master/src/DotNetOpenAuth.AspNet/Clients\"><$c$c>DotNetOpenAuth.AspNet.Clients与使用 SimpleMembershipProvider 都使用静态网址为他们的身份服务---那就是,所有用户都使用同一个众所周知的URL来访问供应商。用户的OpenID的标识符与用于访问该身份服务的URL分离

The providers implemented in DotNetOpenAuth.AspNet.Clients for use with the SimpleMembershipProvider all use static URLs for their identity services --- that is, all users use the same well-known URL to access the provider. The users' OpenID identifiers are separate from the URL used to access the identity service.

例如,谷歌的OpenID服务URL是 https://www.google.com/accounts/o8/id 为所有用户。

For example, Google's OpenID service URL is https://www.google.com/accounts/o8/id for all users.

这工作原理与 SimpleMembershipProvider 在MVC4,这里需要知道,不变,并注册在你的MVC应用程序启动时的身份提供者的网址。

This works with the SimpleMembershipProvider in MVC4, where the URL of the identity provider needs to be known, constant, and registered at the time your MVC app starts up.

问题是,其他OpenID提供通常使用用户的唯一OpenID识别为URL访问身份服务。

The problem is, other OpenID providers commonly use the user's unique OpenID identifier as the URL to access the identity service.

例如,AOL和Word preSS使用 https://openid.aol.com/ {用户名} HTTPS:/ /{username}.word$p$pss.com ,分别为。

For example, AOL and WordPress use https://openid.aol.com/{username} and https://{username}.wordpress.com, respectively.

如果您替换 SimpleMembershipProvider 用自己实现的 ExtendedMembershipProvider ,那么你可以滚你自己提供者实现,但随后不与MVC4 帐户控制器工作外的开箱。

If you replace the SimpleMembershipProvider with your own implementation of an ExtendedMembershipProvider, then you can roll your own provider implementations, but then it doesn’t work with the MVC4 Account controller out-of-the-box.

怎样才能实现一个新的OpenID的使用依赖方的 SimpleMembershipProvider ,当供应商使用的唯一标识符,在URL中的用户名?

How does one implement a new OpenID Relying Party using the SimpleMembershipProvider, when the provider uses unique identifiers with the username in the URL?

推荐答案

我已经开发了以下的解决方案,为我的作品,而我在案例分享它会帮助别人,但我真的想看看有没有更直接的方法还是最佳实践说我失踪了。

I’ve developed the following solution that works for me, and I’m sharing in case it will help others, but I would really like to see if there’s a more direct method or "best practice" that I’m missing.

基本上,你需要实现 OpenIdClient 是与初始化的 ProviderIdentifier 有包含关键字的URL __ __名

Basically, you need to implement an OpenIdClient that is initialized with a ProviderIdentifier that has a URL containing the keyword __username__.

在运行时,提供程序名称和用户名被传递给帐户控制器,其中供应商客户是按名称选择,用户名代替 __ __名之前关键字认证请求被发送到供应商。

At runtime, the provider name and user name are passed to the Account controller, where the provider client is selected by name, and the user name is substituted for the __username__ keyword before the authentication request is sent to the provider.

贡献的微软DotNetOpenAuth OpenID提供商类继承的基类<一href=\"https://github.com/DotNetOpenAuth/DotNetOpenAuth/blob/master/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs\"><$c$c>DotNetOpenAuth.AspNet.Clients.OpenIdClient,它实现了OpenID提供商类所需的 IAuthenticationClient 接口。与<起始href=\"https://github.com/DotNetOpenAuth/DotNetOpenAuth/blob/master/src/DotNetOpenAuth.AspNet/Clients/OpenID/GoogleOpenIdClient.cs\">source对于谷歌提供因为它有一个直观的实现,自定义,以使该使用的自定义网址提供商工作的 GenericOpenIdClient 类。

The DotNetOpenAuth OpenID provider classes contributed by Microsoft inherit the base class DotNetOpenAuth.AspNet.Clients.OpenIdClient, which implements the IAuthenticationClient interface required for OpenID provider classes. Starting with the source for the Google provider because it has a straight-forward implementation, customize it to make a GenericOpenIdClient class that works with providers using custom URLs.

要在运行时创建自定义的网址,我们会接受OpenID的用户名作为URI的片段,并与用户名替换的所有实例__名__ 中的URL用户提交的。供应商需要以在应用程序启动的URL进行登记,所以在运行时,我们不能只是注册一个供应商的URL时,用户名是众所周知的。

To create the custom URL at runtime, we’ll accept the OpenID user name as a URI fragment, and replace all instances of __username__ in the URL with the user name submitted by the user. Providers need to be registered with URLs during application startup, so we can't just register a provider URL at runtime when the user name is known.

我们将使用OpenID的选择提交表单我们的帐户与<$ C控制器的 ExternalLogin 行动$ C>提供商表格值设置格式提供商提供者的名称和用户名; {用户名} 。的OpenID选择器内置了从psented给用户一个文本框$ P $与输入到替换 {用户名} 的所有实例的逻辑。在服务器端,我们会从用户名分裂提供者的名称,从这些应用程序启动时注册的名称查找供应商,并设置 GenericOpenIdClient.UserName 属性提交的用户的用户名。

We'll use OpenID Selector to submit a form to our Account controller’s ExternalLogin action with the provider form value set to the provider name and username in the format provider;{username}. OpenId Selector has logic built in to substitute all instances of {username} with input from a textbox presented to the user. On the server side, we’ll split the provider name from the username, look up the provider by name from those registered at application startup, and set the GenericOpenIdClient.UserName property to the username submitted by the user.

在创建认证请求发送到OpenID提供商,我们将检查 GenericOpenIdClient.UserName 属性,并集,我们会重新提供者URL通过发送请求之前的用户名。为了做到这一点,我们需要覆盖 RequestAuthentication()方法来创建我们的自定义URL的认证请求。 __名__ 使用而不是{用户名} 在这里,因为 {} 是主机名无效字符,所以创建的URL包括他们变得有问题的时候,我们需要将它们注册为通用供应商的标识符。

When the authentication request is created to send to the OpenID provider, we’ll check the GenericOpenIdClient.UserName property, and if set, we’ll recreate the provider URL using the username before sending the request. In order to do so, we need to override the RequestAuthentication() method to create the authentication request with our custom URL. __username__ is used instead of {username} here because { and } aren't valid characters for a hostname, so creating URLs including them becomes problematic when we need to register them as generic provider identifiers.

/GenericOpenIdClient.cs

namespace DotNetOpenAuth.AspNet.Clients
{
    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Xml.Linq;
    using DotNetOpenAuth.OpenId;
    using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
    using DotNetOpenAuth.OpenId.RelyingParty;

    public class GenericOpenIdClient : OpenIdClient
    {
        #region Constants and Fields

        /// <summary>
        /// The openid relying party.
        /// </summary>
        /// <remarks>
        /// Pass null as applicationStore to specify dumb mode. Create a protected field to use internally; we can't access the private base class field.
        /// </remarks>
        protected static readonly OpenIdRelyingParty RelyingParty = new OpenIdRelyingParty(applicationStore: null);

        /// <summary>
        /// The provider identifier.
        /// </summary>
        /// <remarks>
        /// Create a protected field to use internally; we can't access the private base class field.
        /// </remarks>
        protected readonly Identifier providerIdentifier;

        #endregion

        #region Constructors and Destructors

        public GenericOpenIdClient(string providerName, Identifier providerIdentifier)
            : base(providerName, providerIdentifier) 
        {
            this.providerIdentifier = providerIdentifier; // initialize our internal field as well
        }

        #endregion

        #region Public Properties

        public String UserName { get; set; }

        #endregion

        #region Protected Properties

        /// <summary>
        /// The provider Identifier with the "__username__" keyword replaced with the value of the UserName property.
        /// </summary>
        protected Identifier ProviderIdentifier
        {
            get
            {
                var customIdentifier = String.IsNullOrWhiteSpace(this.UserName) ?
                    this.providerIdentifier :
                    Identifier.Parse(HttpUtility.UrlDecode(this.providerIdentifier).Replace("__username__", this.UserName));
                return customIdentifier;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Gets the extra data obtained from the response message when authentication is successful.
        /// </summary>
        /// <param name="response">
        /// The response message. 
        /// </param>
        /// <returns>A dictionary of profile data; or null if no data is available.</returns>
        protected override Dictionary<string, string> GetExtraData(IAuthenticationResponse response)
        {
            FetchResponse fetchResponse = response.GetExtension<FetchResponse>();
            if (fetchResponse != null)
            {
                var extraData = new Dictionary<string, string>();
                extraData.AddItemIfNotEmpty("email", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email));
                extraData.AddItemIfNotEmpty("country", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.Country));
                extraData.AddItemIfNotEmpty("firstName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.First));
                extraData.AddItemIfNotEmpty("lastName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.Last));

                return extraData;
            }

            return null;
        }

        public override void RequestAuthentication(HttpContextBase context, Uri returnUrl)
        {
            var realm = new Realm(returnUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped));
            IAuthenticationRequest request = RelyingParty.CreateRequest(ProviderIdentifier, realm, returnUrl);

            // give subclasses a chance to modify request message, e.g. add extension attributes, etc.
            this.OnBeforeSendingAuthenticationRequest(request);

            request.RedirectToProvider();
        }

        /// <summary>
        /// Called just before the authentication request is sent to service provider.
        /// </summary>
        /// <param name="request">
        /// The request. 
        /// </param>
        protected override void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request)
        {
            // Attribute Exchange extensions
            var fetchRequest = new FetchRequest();
            fetchRequest.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
            fetchRequest.Attributes.AddOptional(WellKnownAttributes.Contact.HomeAddress.Country);
            fetchRequest.Attributes.AddRequired(WellKnownAttributes.Name.First);
            fetchRequest.Attributes.AddRequired(WellKnownAttributes.Name.Last);

            request.AddExtension(fetchRequest);
        }

        #endregion
    }

    /// <summary>
    /// The dictionary extensions.
    /// </summary>
    internal static class DictionaryExtensions
    {
        /// <summary>
        /// Adds the value from an XDocument with the specified element name if it's not empty.
        /// </summary>
        /// <param name="dictionary">
        /// The dictionary. 
        /// </param>
        /// <param name="document">
        /// The document. 
        /// </param>
        /// <param name="elementName">
        /// Name of the element. 
        /// </param>
        public static void AddDataIfNotEmpty(
            this Dictionary<string, string> dictionary, XDocument document, string elementName)
        {
            var element = document.Root.Element(elementName);
            if (element != null)
            {
                dictionary.AddItemIfNotEmpty(elementName, element.Value);
            }
        }

        /// <summary>
        /// Adds a key/value pair to the specified dictionary if the value is not null or empty.
        /// </summary>
        /// <param name="dictionary">
        /// The dictionary. 
        /// </param>
        /// <param name="key">
        /// The key. 
        /// </param>
        /// <param name="value">
        /// The value. 
        /// </param>
        public static void AddItemIfNotEmpty(this IDictionary<string, string> dictionary, string key, string value)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            if (!string.IsNullOrEmpty(value))
            {
                dictionary[key] = value;
            }
        }
    }
}

要注册建成贡献的微软新DotNetOpenAuth类供应商,取消现有的Microsoft,Facebook,微博,和谷歌供应商,并添加调用注册内置雅虎提供商。在OpenID提供我们即将实现不需要钥匙,但你需要获得来自OAuth的供应商(微软,脸谱,和Twitter)键,如果你想使用它们。在OpenID的选择包中可用的提供的其他部分可以被添加到您的喜好。

To register the providers built into the new DotNetOpenAuth classes contributed by Microsoft, uncomment the existing Microsoft, Facebook, Twitter, and Google providers, and add a call to register the built-in Yahoo provider. The OpenID providers we’re about to implement don’t need keys, but you’ll need to obtain keys from the OAuth providers (Microsoft, Facebook, and Twitter) if you want to use them. The rest of the providers available in the OpenID Selector package can be added to your liking.

/App_Start/AuthConfig.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotNetOpenAuth.AspNet.Clients;
using DotNetOpenAuth.OpenId.RelyingParty;
using Microsoft.Web.WebPages.OAuth;
using Mvc4ApplicationOpenAuth.Models;

namespace Mvc4ApplicationOpenAuth
{
    public static class AuthConfig
    {
        public static void RegisterAuth()
        {
            // To let users of this site log in using their accounts from other sites such as Microsoft, Facebook, and Twitter,
            // you must update this site. For more information visit http://go.microsoft.com/fwlink/?LinkID=252166

            //OAuthWebSecurity.RegisterMicrosoftClient(
            //    clientId: "",
            //    clientSecret: "");

            //OAuthWebSecurity.RegisterTwitterClient(
            //    consumerKey: "",
            //    consumerSecret: "");

            //OAuthWebSecurity.RegisterFacebookClient(
            //    appId: "",
            //    appSecret: "");

            OAuthWebSecurity.RegisterGoogleClient();
            OAuthWebSecurity.RegisterYahooClient();
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("Aol", "https://openid.aol.com/__username__"), "Aol", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("LiveJournal", "https://__username__.livejournal.com/"), "LiveJournal", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("WordPress", "https://__username__.wordpress.com/"), "WordPress", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("Blogger", "https://__username__.blogspot.com/"), "Blogger", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("VeriSign", "https://__username__.pip.verisignlabs.com/"), "VeriSign", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("ClaimID", "https://claimid.com/__username__"), "ClaimID", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("ClickPass", "https://clickpass.com/public/__username__"), "ClickPass", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("Google Profile", "https://www.google.com/profiles/__username__"), "Google Profile", new Dictionary());
            OAuthWebSecurity.RegisterClient(new GenericOpenIdClient("MyOpenID", "https://__username__.myopenid.com/"), "MyOpenID", new Dictionary());
        }
    }
}

最后,我们需要解析提交给帐户提供商形式值控制器 ExternalLogin 通过OpenID的选择行动检查对于;分隔符,表示用户名是present。如果是这样,那么我们解析出供应商和用户名。

Last, we need parse the provider form value submitted to the Account controller’s ExternalLogin action by OpenID Selector to check for the ";" delimiter indicating a username is present. If so, then we parse out the provider name and username.

/Controllers/AccountController.cs

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
    if (provider.Contains(';'))
    {
        string[] providerParts = provider.Split(';');
        if (providerParts.Length == 2)
        {
            AuthenticationClientData clientData;
            if (OAuthWebSecurity.TryGetOAuthClientData(providerParts[0], out clientData))
            {
                var genericClient = clientData.AuthenticationClient as GenericOpenIdClient;
                if (genericClient != null)
                {
                    provider = providerParts[0];
                    genericClient.UserName = providerParts[1];
                }
            }
        }
    }

    return new ExternalLoginResult(provider, Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
}


用户界面

该UI实现由与开源的OpenID选择更加容易。 下载OpenID的选择并自定义为与 OAuthWebSecurity使用类。


  1. 在您的Web应用程序创建一个新的的OpenID 文件夹: /内容/ OpenID的

  2. 复制 CSS 图片 images.large 和<从code> images.small 文件夹
    OpenID的选择下载到 /内容/ OpenID的文件夹,然后包括
    在你的项目中的文件。

  3. 从OpenID的选择下载的 JS 文件夹,复制 OpenID的jquery.js和 OpenID的en.js 来您的Web应用程序的 /脚本文件夹,然后包括文件,您的项目。

  4. 打开 OpenID的en.js 文件和自定义它,因此提供的网址是
    供应商的名称,您将添加在 AuthConfig.cs 文件。对于
    自定义网址提供商,使用格式提供商; {用户名}

  1. Create a new openid folder in your web app at: /Content/openid
  2. Copy the css, images, images.large, and images.small folders from the openid-selector download to the /Content/openid folder, then include the files in your project.
  3. From the openid-selector download's js folder, copy openid-jquery.js and openid-en.js to your web app's /Scripts folder, then include the files your project.
  4. Open the openid-en.js file and customize it so the provider URLs are the provider names you will add in your AuthConfig.cs file. For providers with custom URLs, use the format Provider;{username}:

/Scripts/openid-en.js

var providers_large = {
    google : {
        name : 'Google',
        url : 'Google'
    },
    facebook : {
        name : 'Facebook',
        url : 'Facebook',
    },
    twitter: {
        name: 'Twitter',
        url: 'Twitter'
    },
    microsoft : {
        name : 'Microsoft',
        url : 'Microsoft'
    },
    yahoo : {
        name : 'Yahoo',
        url : 'Yahoo'
    },
    aol : {
        name : 'Aol',
        label : 'Enter your Aol screenname.',
        url : 'Aol;{username}'
    }
};

var providers_small = {
    livejournal: {
        name : 'LiveJournal',
        label : 'Enter your Livejournal username.',
        url: 'LiveJournal;{username}'
    },
    wordpress : {
        name : 'WordPress',
        label : 'Enter your WordPress.com username.',
        url: 'WordPress;{username}'
    },
    blogger : {
        name : 'Blogger',
        label : 'Your Blogger account',
        url: 'Blogger;{username}'
    },
    verisign : {
        name : 'VeriSign',
        label : 'Your VeriSign username',
        url: 'VeriSign;{username}'
    },
    claimid : {
        name : 'ClaimID',
        label : 'Your ClaimID username',
        url: 'ClaimID;{username}'
    },
    clickpass : {
        name : 'ClickPass',
        label : 'Enter your ClickPass username',
        url: 'ClickPass;{username}'
    },
    google_profile : {
        name : 'Google Profile',
        label : 'Enter your Google Profile username',
        url: 'Google Profile;{username}'
    },
    myopenid: {
        name: 'MyOpenID',
        label: 'Enter your MyOpenID username.',
        url: 'MyOpenID;{username}'
    }
};

openid.locale = 'en';
openid.sprite = 'en'; // reused in german& japan localization
openid.demo_text = 'In client demo mode. Normally would have submitted OpenID:';
openid.signin_text = 'Log in';
openid.image_title = 'Log in with {provider}';
openid.no_sprite = true;
openid.img_path = '/Content/openid/images/';

OpenID的选择不来与微软或Twitter图像,因此下载您喜欢的<一个href=\"http://i.microsoft.com/global/ImageStore/PublishingImages/logos/ms-mark/microsoft_logo_90x16.png\">Microsoft和微博(蓝白色)标志,将其转换为GIF格式为100x60像素,然后把它们在 /内容/openid/images.large 文件夹中。阅读在OpenID的选择的说明的README.txt 如果你想,如果单独的图像使用一个单一的精灵形象,而不是文件。设置 openid.no_sprite = FALSE; OpenID的en.js 如果您使用精灵

OpenID Selector doesn’t come with images for Microsoft or Twitter, so download your favorite Microsoft and Twitter (blue on white) logos, convert them to GIFs at 100x60 pixels, then drop them in the /Content/openid/images.large folder. Read the instructions in the OpenID Selector README.txt file if you want to use a single sprite image instead if separate images. Set openid.no_sprite = false; in openid-en.js if you use the sprite.

注册JS和CSS文件作为一个新包。打开 /App_Start/BundleConfig.cs ,并在 RegisterBundles添加下面的脚本和样式包()方法。

Register the JS and CSS files as a new bundle. Open /App_Start/BundleConfig.cs and add the following script and style bundles in the RegisterBundles() method.

/App_Start/BundleConfig.cs

bundles.Add(new ScriptBundle("~/bundles/openid").Include(
    "~/Scripts/openid-jquery.js",
    "~/Scripts/openid-en.js"));

bundles.Add(new StyleBundle("~/Content/css/openid").Include("~/Content/openid/css/openid-shadow.css"));

我preFER的OpenID的选择器的影子的风格,所以我选择只使用了 OpenID的shadow.css CSS文件,并定制了下列类来工作,在MVC4登录模板。

I prefer the OpenID Selector's "shadow" style, so I elected use just the openid-shadow.css CSS file and customized the following classes to work in the MVC4 Login template.

/Content/css/openid/openid-shadow.css

/*#openid_form {
    width: 590px;
}*/

#openid_highlight {
    padding: 0px;
    background-color: #FFFCC9;
    float: left;
    border-radius: 5px; 
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
}

.openid_large_btn {
    width: 100px;
    height: 60px;
/* fix for IE 6 only: http://en.wikipedia.org/wiki/CSS_filter#Underscore_hack */
    _width: 104px;
    _height: 64px;

    border: 2px solid #DDD;
    border-right: 2px solid #ccc;
    border-bottom: 2px solid #ccc;
    margin: 3px;
    padding: 3px;
    float: left;
    border-radius: 5px; 
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    box-shadow: 2px 2px 4px #ddd;
    -moz-box-shadow: 2px 2px 4px #ddd;
    -webkit-box-shadow: 2px 2px 4px #ddd;
}

.openid_large_btn:hover {
    margin: 4px 3px 3px 6px;
    padding: 2px 3px 3px 0px;
    border: 2px solid #999;
    box-shadow: none;
    -moz-box-shadow: none;
    -webkit-box-shadow: none;
}

要创建一个通用的地方CSS脚本添加到页面的&LT; HEAD&GT; 标签中,添加一个在底部的&LT;头方式&gt; 标签

To create a generic place to add CSS scripts to the page's <head> tag, add a head section at the bottom of the <head> tag.

/Views/Shared/_Layout.cshtml

<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title - My ASP.NET MVC Application</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @RenderSection("head", false)
</head>

然后,在 /Views/Account/Login.cshtml 文件中,加入自定义登录视图我们在页面的底部注册的OpenID包previously到相应的部分。

Then, in the /Views/Account/Login.cshtml file, customize the Login view by adding the OpenID bundles we registered previously to the appropriate sections at the bottom of the page.

/Views/Account/Login.cshtml

<section class="social" id="socialLoginForm">
    @Html.Action("ExternalLoginsList", new { ReturnUrl = ViewBag.ReturnUrl })
</section>

@section Head {        
    @Styles.Render("~/Content/css/openid")
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/openid")
    <script type="text/javascript">
        $(function () {
            openid.init('provider');
        });
    </script>
}

用户界面的最后一个元素涉及与OpenID的选择形式替换默认 ExternalLogin 的形式。

/Views/Account/_ExternalLoginsListPartial.cshtml

using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { id = "openid_form" }))
{
    @Html.AntiForgeryToken()
    <input type="hidden" name="action" value="verify" />

    <h2>Use another service to log in.</h2>
    <br />
    <fieldset id="socialLoginList">
        <legend></legend>

        <div id="openid_choice">
            <div id="openid_btns"></div>
        </div>
        <div id="openid_input_area">
            <input id="provider" name="provider" type="text" value="" />
            <input id="openid_submit" type="submit" value="Log in"/>
        </div>
        <noscript>
            <p>OpenID is service that allows you to log-on to many different websites using a single indentity. Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p>
        </noscript>
    </fieldset>
}

这篇关于如何使用ASP.NET中MVC4唯一标识符的URL OpenID提供的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆