Dotnetopenauth与自定义的身份提供单点登录 [英] Dotnetopenauth single sign on with custom identity provider

查看:358
本文介绍了Dotnetopenauth与自定义的身份提供单点登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图来设置DotNetOpenAuth样品有一个自定义提供了一个工作SSO解决方案。我使用这似乎是工作的罚款OpenIdProviderMvc示例项目。

I'm trying to setup the DotNetOpenAuth samples to have a working SSO solution with a custom provider. I'm using OpenIdProviderMvc sample project which appears to be working fine.

我的问题是OpenIdRelyingPartyMvc示例项目设立的消费者,在这种情况下,我不能将它配置为使用OpenIdProvider。

My problems is setting up the "consumer", in this case the OpenIdRelyingPartyMvc sample project, I cannot configure it to use the OpenIdProvider.

我试图建立这样对消费者的web.config端点:

I tried to setup an endpoint on the consumer's web.config like this:

<trustedProviders rejectAssertionsFromUntrustedProviders="true">
    <add endpoint="http://localhost:4864/OpenID/Provider" />
</trustedProviders>

但我得到的是没有OpenID端点发现。错误(其实,我不是什么穿上OpenID的中...很确定)

But all I get is "No OpenID endpoint found." errors (actually, I'm not quite sure on what to put on the OpenID box...)

此项目几乎没有证件。有人能指出我朝着正确的方向吗?

This project is virtually undocumented. Can someone point me in the right direction?

至少有一个供应商和消费者的工作和互相交谈?

At least to have a provider and consumer working and talking to each other?

推荐答案

让我们开始:

1打开Visual Studio 2010转到文件>新建>项目>网络> ASP.NET MVC 3应用程序:

1- Open Visual Studio 2010 go to File > New > Project > Web > ASP.NET MVC 3 Application:

然后选择互联网应用程序一定要有剃须刀作为你的视图引擎,然后单击确定:

then Choose Internet Application be sure to have Razor as your View engine and Click Ok:

2 - <一个href=\"https://docs.google.com/leaf?id=0Bz8gXQfIEQb6NjczOWZlYWMtMDFlYS00MjVjLTgzN2ItNDY4OWJkMDM3OTU2&sort=name&layout=list&num=50\">Download资产文件夹 ,它包含 DotNetOpenAuth DLL和OpenID的选择文件,我们将使用

2- Download Assets folder , it contains DotNetOpenAuth dll and OpenID-Selector files that we will use ,

如果你想要去这些项目和更多的细节发现它们随意。

Feel free if you want to go to these projects and discover them in more details.

解压缩到你想要的文件夹

Extract it to the folder you want

  a - Add the DotNetOpenAuth.dll to references in your site.

  b- Delete all files/folders in Site Content folder.

  c- Copy Assets Content files/folders to the site Content .

  d- Copy the  Assets Script files to the site Script.

您的项目将是这样的:

3转到视图>共享> _Layout.cshtml,并与这个新的头取代,我们只是增加了新的样式和脚本:

3- Go to Views > Shared > _Layout.cshtml and replace the with this new head , we just added the new styles and scripts:

<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" 
     rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")"
     type="text/javascript"></script>
    <link href="@Url.Content("~/Content/openid-shadow.css")"
     rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/openid.css")" 
     rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/openid-en.js")" 
     type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/openid-jquery.js")" 
     type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            openid.init('openid_identifier');
        });
    </script>
</head>

4-转到模型> AccountModels.cs,导航到公共类LogOnModel

4- Go to Models > AccountModels.cs , navigate to public class LogOnModel

和加入,我们将用它来从OpenID的选择。

and Add OpenID attribute that we will use it to hold the returned OpenID from OpenID-Selector

您的类将是这样的:

public class LogOnModel
{
    [Display(Name = "OpenID")]
    public string OpenID { get; set; }

    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }
}

导航到公共类RegisterModel并加入OpenID的属性。

navigate to public class RegisterModel and Add OpenID attribute

public class RegisterModel
{

    [Display(Name = "OpenID")]
    public string OpenID { get; set; }

    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email address")]
    public string Email { get; set; }

    [Required]
    [ValidatePasswordLength]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage =
    "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

然后到服务节AccountModels.cs

Then go to Services section in AccountModels.cs

和修改CREATEUSER和添加的getUser通过OpenID的获取用户,你的界面

and Modify the CreateUser and Add GetUser to get the user by OpenID , your Interface

会是这样的:

public interface IMembershipService
{
    int MinPasswordLength { get; }
    bool ValidateUser(string userName, string password);
    MembershipCreateStatus CreateUser(string userName, string password,
                                      string email, string OpenID);
    bool ChangePassword(string userName, string oldPassword, string newPassword);
    MembershipUser GetUser(string OpenID);
}

这些使用添加到AccountModels.cs

Add these using to AccountModels.cs

using System.Security.Cryptography;
using System.Text;

然后添加此功能可将AccountModels.cs,该功能将被用于在OpenID的转换为GUID

Then Add This Function to the AccountModels.cs , this function will be used to convert the OpenID to GUID

请注意:随意使用散列更好地为你的系统,MD5有一些冲突问题。

Note: feel free to use better hashing to your system , MD5 had some collision issues.

public Guid StringToGUID(string value)
{
    // Create a new instance of the MD5CryptoServiceProvider object.
    MD5 md5Hasher = MD5.Create();
    // Convert the input string to a byte array and compute the hash.
    byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(value));
    return new Guid(data);
}

还要修改CREATEUSER功能看起来是这样的:

Also Modify The CreateUser Function to look like this:

public MembershipCreateStatus CreateUser(string userName, string password, 
                                         string email , string OpenID)
{
    if (String.IsNullOrEmpty(userName)) throw 
    new ArgumentException("Value cannot be null or empty.", "userName");
    if (String.IsNullOrEmpty(password)) throw 
    new ArgumentException("Value cannot be null or empty.", "password");
    if (String.IsNullOrEmpty(email)) throw
    new ArgumentException("Value cannot be null or empty.", "email");

    MembershipCreateStatus status;
    _provider.CreateUser(userName, password, email, null, null, true,
                            StringToGUID(OpenID), out status);
    return status;
}

下面我们使用会员卡ProviderUserKey存储OpenID和的伎俩在这里,我们转换的OpenID字符串GUID由CREATEUSER和方法的getUser使用。

Here we are using the MemberShip ProviderUserKey to store the OpenID and the trick here that we convert the OpenID string to GUID to be used by CreateUser and GetUser methods.

现在让我们来添加这个功能AccountModels.cs将由OpenID的获取用户:

Now let us add this function to AccountModels.cs that will get the user by OpenID:

public MembershipUser GetUser(string OpenID)
{
    return _provider.GetUser(StringToGUID(OpenID), true);
}

5去查看>帐户> LogOn.cshtml

5- go to Views > Account > LogOn.cshtml

这一个替换所有的标记,我们正在整合OpenID的选择登录查看:

replace all the markup with this one ,we are integrating OpenID-Selector to LogOn View:

@model OpenIDMVC3.Models.LogOnModel
@{
    ViewBag.Title = "Log On";
}
<h2>
    Log On</h2>
<p>
    Please enter your username and password. @Html.ActionLink("Register", "Register")
    if you don't have an account.
</p>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript">
</script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
   type="text/javascript"></script>
<form action=
"Authenticate?ReturnUrl=@HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"])"
 method="post" id="openid_form">
<input type="hidden" name="action" value="verify" />
<div>
    <fieldset>
        <legend>Login using OpenID</legend>
        <div class="openid_choice">
            <p>
                Please click your account provider:</p>
            <div id="openid_btns">
            </div>
        </div>
        <div id="openid_input_area">
            @Html.TextBox("openid_identifier")
            <input type="submit" value="Log On" />
        </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>
        <div>
            @if (Model != null)
            {
                if (String.IsNullOrEmpty(Model.UserName))
                {
                <div class="editor-label">
                    @Html.LabelFor(model => model.OpenID)
                </div>
                <div class="editor-field">
                    @Html.DisplayFor(model => model.OpenID)
                </div>
                <p class="button">
                    @Html.ActionLink("New User ,Register", "Register", 
                                         new { OpenID = Model.OpenID })
                </p>
                }
                else
                {
                    //user exist 
                <p class="buttonGreen">
                    <a href="@Url.Action("Index", "Home")">Welcome , @Model.UserName, 
                    Continue..." </a>
                </p>

                }
            }
        </div>
    </fieldset>
</div>
</form>

@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors 
                                                    and try again.")
@using (Html.BeginForm())
{
    <div>
        <fieldset>
            <legend>Or Login Normally</legend>
            <div class="editor-label">
                @Html.LabelFor(m => m.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.UserName)
                @Html.ValidationMessageFor(m => m.UserName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(m => m.Password)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(m => m.Password)
                @Html.ValidationMessageFor(m => m.Password)
            </div>
            <div class="editor-label">
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe)
            </div>
            <p>
                <input type="submit" value="Log On" />
            </p>
        </fieldset>
    </div>
}

6现在让我们运行该项目,然后点击[登录]链接,你会得到这样的页面:

6- Now let us run the project , then click the [Log On] link , you will get like this page:

7转到控制器> AccountController.cs这些使用添加:

7- Go to Controllers > AccountController.cs and Add these using:

using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;

那么这个属性添加到AccountController.cs:

Then Add this Attribute to AccountController.cs:

private static OpenIdRelyingParty openid = new OpenIdRelyingParty();

那么这个函数添加到AccountController.cs:

Then Add this Function to AccountController.cs:

[ValidateInput(false)]
public ActionResult Authenticate(string returnUrl)
{
    var response = openid.GetResponse();
    if (response == null)
    {
        //Let us submit the request to OpenID provider
        Identifier id;
        if (Identifier.TryParse(Request.Form["openid_identifier"], out id))
        {
            try
            {
                var request = openid.CreateRequest(
                                        Request.Form["openid_identifier"]);
                return request.RedirectingResponse.AsActionResult();
            }
            catch (ProtocolException ex)
            {
                ViewBag.Message = ex.Message;
                return View("LogOn");
            }
        }

        ViewBag.Message = "Invalid identifier";
        return View("LogOn");
    }

    //Let us check the response
    switch (response.Status)
    {

        case AuthenticationStatus.Authenticated:
            LogOnModel lm = new LogOnModel();
            lm.OpenID = response.ClaimedIdentifier;
            // check if user exist
            MembershipUser user = MembershipService.GetUser(lm.OpenID);
            if (user != null)
            {
                lm.UserName = user.UserName;
                FormsService.SignIn(user.UserName, false);
            }

            return View("LogOn", lm);

        case AuthenticationStatus.Canceled:
            ViewBag.Message = "Canceled at provider";
            return View("LogOn");
        case AuthenticationStatus.Failed:
            ViewBag.Message = response.Exception.Message;
            return View("LogOn");
    }

    return new EmptyResult();
}

8 - 现在运行的项目点击[登录]链接,然后点击一个像谷歌提供商

8 - Now run the project click [Log On] link and click a provider like Google

它可能会要求您登录或询问您是允许访问您的信息

it may ask you to sign in or ask you to allow access to your information

您将得到一个网页是这样的:

you will get a page like this :

正如你可以看到它显示你的OpenID和一个按钮,表明这是尚未注册的新用户,

As you can see it displays your OpenID and a button that indicate that this is a new user not registered yet,

命中[新用户,注册]按钮之前,我们需要修改注册视图和控制器访问OpenID的信息。

before hitting [New User ,Register] button we need to modify the Register view and controller to access OpenID information.

9转到控制器> AccountController.cs本替换[的ActionResult寄存器()]:

9- Go to controllers > AccountController.cs replace the [ActionResult Register ()] by this :

public ActionResult Register(string OpenID)
{
    ViewBag.PasswordLength = MembershipService.MinPasswordLength;
    ViewBag.OpenID = OpenID;
    return View();
}

和修改[的ActionResult寄存器(RegisterModel模式)使用OpenID的时候

And Modify the [ActionResult Register(RegisterModel model)] to use OpenID when

创建用户:

[HttpPost]
public ActionResult Register(RegisterModel model)
{
    if (ModelState.IsValid)
    {
        // Attempt to register the user
        MembershipCreateStatus createStatus =
        MembershipService.CreateUser(model.UserName, model.Password, 
                                        model.Email,model.OpenID);

        if (createStatus == MembershipCreateStatus.Success)
        {
            FormsService.SignIn(model.UserName, false);
            return RedirectToAction("Index", "Home");
        }
        else
        {
            ModelState.AddModelError("",
            AccountValidation.ErrorCodeToString(createStatus));
        }
    }

    // If we got this far, something failed, redisplay form
    ViewBag.PasswordLength = MembershipService.MinPasswordLength;
    return View(model);
}

10转到视图>帐户> Register.cshtml,这个替换标记:

10- Go to Views > Account > Register.cshtml , replace the markup by this :

@model OpenIDMVC3.Models.RegisterModel
@{
    ViewBag.Title = "Register";
}

<h2>Create a New Account</h2>
<p>
    Use the form below to create a new account. 
</p>
<p>
    Passwords are required to be a minimum of @ViewBag.PasswordLength 
    characters in length.
</p>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" 
  type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
   type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true, "Account creation was unsuccessful.
                                            Please correct the errors and try again.")
    <div>
        <fieldset>
            <legend>Account Information</legend>
            @if (ViewData["OpenID"] != null)
            {
            <div class="editor-label">
                @Html.Label("OpenID")
            </div>
            <div class="editor-label">
                @Html.Label((string)ViewBag.OpenID)
            </div>
            }
            <div class="editor-label">
                @Html.LabelFor(m => m.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.UserName)
                @Html.ValidationMessageFor(m => m.UserName)
            </div>

            <div class="editor-label">
                @Html.LabelFor(m => m.Email)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.Email)
                @Html.ValidationMessageFor(m => m.Email)
            </div>

            <div class="editor-label">
                @Html.LabelFor(m => m.Password)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(m => m.Password)
                @Html.ValidationMessageFor(m => m.Password)
            </div>

            <div class="editor-label">
                @Html.LabelFor(m => m.ConfirmPassword)
            </div>
            <div class="editor-field">
                @Html.PasswordFor(m => m.ConfirmPassword)
                @Html.ValidationMessageFor(m => m.ConfirmPassword)
            </div>

            <p>
                <input type="submit" value="Register" />
            </p>
        </fieldset>
    </div>
}

11-转到步骤8,让我们打[新用户,注册】按钮,你会得到这样的:

11- Go to step 8 and let us hit [New User ,Register] button , you will get this :

12注册的任何帐户你想你会得到这样的页面:

12- Register any account you want you will get like this page :

13-点击[注销]并使用相同的OpenID重新登录,你会得到这样的页面:

13- Click [Log Off] and login again using the same OpenID , you will get like this page:

正如你可以看到欢迎的绿色按钮来检测该用户注册。

As you can see the welcome green button detect that this user is registered .

14 - 点击绿色的按钮,你会得到一个页面是这样的:

14- Click the green button you will get a page like this :

恭喜!现在你已整合的OpenID到您的项目。

Congratulation ! , now you had integrated OpenID to your project.

参考

Reference

这篇关于Dotnetopenauth与自定义的身份提供单点登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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