Stack Overflow真正使用了哪些OpenID解决方案?

时间:2011-02-26 19:57:04

标签: oauth openid

我知道还有其他问题,但是它们已经过时了,我找不到任何可靠的答案。

Stack Overflow真正用于识别用户的是什么?网站DotNetOpenAuth声称它是。但对我来说,最(视觉上)相似的外观似乎是 OAuth C# Library

那它真正用于什么?或者我如何模仿相同的用户界面?

我想使用ASP.NET MVC创建完全相同的OpenID身份验证。

2 个答案:

答案 0 :(得分:17)

StackOverflow使用DotNetOpenAuth

来自blog

  

但幸运的是,我们与Andrew Arnott进行了精彩对话,Andrew Arnott是我们使用的开源DotNetOpenAuth库的主要作者

答案 1 :(得分:15)

我能够在相当短的时间内在我的网站(www.mydevarmy.com)上使用DotNetOpenAuth获取OpenID身份验证(请注意,我对ASP.NET,MVC总共noob ,DotNetOpenAuth等)。

DotNetOpenAuth附带了各种样本,他们甚至有一个ASP.NET MVC示例,但是他们只在该示例中提供了一个View和Controller,并且它们实际上没有一个模型,即 M 在MVC :)。随后我在SO上问了以下问题:

What are the responsibilities of the components in an MVC pattern for a simple login

那么非常简单 OpenID登录在MVC中会如何?好吧,我们来看看......

<强> 1。您需要一个模型:

public class User
{
    [DisplayName("User ID")]
    public int UserID{ get; set; }

    [Required]
    [DisplayName("OpenID")]
    public string OpenID { get; set; }
}

public class FormsAuthenticationService : IFormsAuthenticationService
{
    public void SignIn(string openID, bool createPersistentCookie)
    {
        if (String.IsNullOrEmpty(openID)) throw new ArgumentException("OpenID cannot be null or empty.", "OpenID");

        FormsAuthentication.SetAuthCookie(openID, createPersistentCookie);
    }

    public void SignOut()
    {
        FormsAuthentication.SignOut();
    }
}  

<强> 2。您需要一个控制器:

[HandleError]
public class UserController : Controller
{
    private static OpenIdRelyingParty openid = new OpenIdRelyingParty();
    public IFormsAuthenticationService FormsService { get; set; }

    protected override void Initialize(RequestContext requestContext)
    {
        if (FormsService == null) 
        {
            FormsService = new FormsAuthenticationService(); 
        }

        base.Initialize(requestContext);
    }

    // **************************************
    // URL: /User/LogIn
    // **************************************
    public ActionResult LogIn()
    {
        if (User.Identity.IsAuthenticated)
        {
            return RedirectToAction("Profile", "User");
        }

        Identifier openID;
        if (Identifier.TryParse(Request.QueryString["dnoa.userSuppliedIdentifier"], out openID))
        {
            return LogIn(new User { OpenID = openID }, Request.QueryString["ReturnUrl"]);
        }
        else
        {
            return View();
        }
    }

    [HttpPost]
    public ActionResult LogIn(User model, string returnUrl)
    {
        string openID = ModelState.IsValid?model.OpenID:Request.Form["openid_identifier"];

        if (User.Identity.IsAuthenticated)
        {
            return RedirectToAction("Profile", "User");
        }
        else if (!string.IsNullOrEmpty(openID))
        {
            return Authenticate(openID, returnUrl);
        }
        else if(ModelState.IsValid)
        {
            ModelState.AddModelError("error", "The OpenID field is required.");
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

    // **************************************
    // URL: /User/LogOut
    // **************************************
    public ActionResult LogOut()
    {
        if (User.Identity.IsAuthenticated)
        {
            FormsService.SignOut();
        }

        return RedirectToAction("Index", "Home");
    }

    // **************************************
    // URL: /User/Profile
    // **************************************
    [Authorize]
    public ActionResult Profile(User model)
    {
        if (User.Identity.IsAuthenticated)
        {
            // ------- YOU CAN SKIP THIS SECTION ----------------
            model = /*some code to get the user from the repository*/;

            // If the user wasn't located in the database
            // then add the user to our database of users
            if (model == null)
            {
                model = RegisterNewUser(User.Identity.Name);
            }
            // --------------------------------------------------

            return View(model);
        }
        else
        {
            return RedirectToAction("LogIn");
        }
    }

    private User RegisterNewUser(string openID)
    {
        User user = new User{OpenID = openID};

        // Create a new user model

        // Submit the user to the database repository

        // Update the user model in order to get the UserID, 
        // which is automatically generated from the DB.
        // (you can use LINQ-to-SQL to map your model to the DB)

        return user;
    }

    [ValidateInput(false)]
    private ActionResult Authenticate(string openID, string returnUrl)
    {
        var response = openid.GetResponse();
        if (response == null)
        {
            // Stage 2: user submitting Identifier
            Identifier id;
            if (Identifier.TryParse(openID, out id))
            {
                try
                {
                    return openid.CreateRequest(openID).RedirectingResponse.AsActionResult();
                }
                catch (ProtocolException ex)
                {
                    ModelState.AddModelError("error", "Invalid OpenID.");

                    ModelState.AddModelError("error", ex.Message);
                    return View("LogIn");
                }
            }
            else
            {
                ModelState.AddModelError("error", "Invalid OpenID.");
                return View("LogIn");
            }
        }
        else
        {
            // Stage 3: OpenID Provider sending assertion response
            switch (response.Status)
            {
                case AuthenticationStatus.Authenticated:
                    Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
                    FormsAuthentication.SetAuthCookie(response.FriendlyIdentifierForDisplay, true);
                    if (!string.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Profile", "User");
                    }
                case AuthenticationStatus.Canceled:
                    ModelState.AddModelError("error", "Authentication canceled at provider.");
                    return View("LogIn");
                case AuthenticationStatus.Failed:
                    ModelState.AddModelError("error", "Authentication failed: " + response.Exception.Message);
                    return View("LogIn");
            }
        }
        return new EmptyResult();
    }
}

第3。您需要一个视图:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<YourProject.Models.User>" %>

<asp:Content ID="loginTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Log in - YourWebSiteName
</asp:Content>
<asp:Content ID="loginContent" ContentPlaceHolderID="MainContent" runat="server">
        <p>
            <%--- If you have a domain, then you should sign up for an affiliate id with MyOpenID or something like that ---%>
            Please log in with your OpenID or <a href="https://www.myopenid.com/signup?affiliate_id=????">create an
                OpenID with myOpenID</a> if you don't have one.
        </p>
        <% 
        string returnURL = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
        if (returnURL == null)
        {
            returnURL = string.Empty;
        }

        using (Html.BeginForm("LogIn", "User", returnURL))
        {%>
            <%= Html.LabelFor(m => m.OpenID)%>:
            <%= Html.TextBoxFor(m => m.OpenID)%>
            <input type="submit" value="Log in" />
        <% 
        } %>

        <%--- Display Errors ---%>
        <%= Html.ValidationSummary()%>
</asp:Content>

请注意,我没有向您提供Profile视图,但这应该很简单,以便弄明白。