我的问题是设置“消费者”,在这种情况下,OpenIdRelyingPartyMvc示例项目,我无法配置它使用OpenIdProvider.
我试图在消费者的web.config上设置一个端点,如下所示:
<trustedProviders rejectAssertionsFromUntrustedProviders="true"> <add endpoint="http://localhost:4864/OpenID/Provider" /> </trustedProviders>
但是我得到的只是“没有找到OpenID端点”.错误(实际上,我不太确定放在OpenID框上…)
这个项目几乎没有文件.有人可以指向正确的方向吗?
至少要有一个供应商和消费者互相工作和交谈?
解决方法
1-打开Visual Studio 2010转到文件>新>项目>网络> ASP.NET MVC 3应用:
那么选择Internet应用程序一定要把Razor看作是你的View引擎,然后点击Ok:
2-Download Assets folder,它包含我们将使用的DotNetOpenAuth dll和OpenID-Selector文件,
如果你想去这些项目,并发现更多的细节,请随时随地.
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并用这个新的头替换,我们刚刚添加了新的样式和脚本:
<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
并添加OpenID属性,我们将使用它来保存OpenID-Selector中返回的OpenID
你的课程将如下所示:
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属性
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中的“服务”部分
并修改CreateUser并添加GetUser以通过OpenID(您的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中
using System.Security.Cryptography; using System.Text;
然后将此函数添加到AccountModels.cs中,此函数将用于将OpenID转换为GUID
注意:随时使用更好的哈希系统,MD5有一些碰撞问题.
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); }
public MembershipCreateStatus CreateUser(string userName,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,true,StringToGUID(OpenID),out status); return status; }
在这里,我们使用MemberShip ProviderUserKey存储OpenID和这里的技巧,我们将OpenID字符串转换为GUID以供CreateUser和GetUser方法使用.
现在让我们将这个函数添加到AccountModels.cs中,这将通过OpenID获取用户:
public MembershipUser GetUser(string OpenID) { return _provider.GetUser(StringToGUID(OpenID),true); }
5-去视图>帐户> logon.cshtml
用这个替换所有的标记,我们正在将OpenID-Selector集成到logon视图中:
@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-现在让我们运行该项目,然后点击[登录]链接,你会得到这样的页面:
7-转到控制器> AccountController.cs并添加以下使用:
using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
然后将此属性添加到AccountController.cs中:
private static OpenIdRelyingParty openid = new OpenIdRelyingParty();
然后将此函数添加到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 – 现在运行项目单击[登录]链接,然后单击Google提供程序
它可能会要求您登录或要求您允许访问您的信息
你会得到一个这样的页面:
您可以看到它显示您的OpenID和一个指示这是尚未注册的新用户的按钮,
在[新用户,注册]按钮之前,我们需要修改注册表视图和控制器来访问OpenID信息.
9-转到控制器> AccountController.cs替换[ActionResult Register()]:
public ActionResult Register(string OpenID) { ViewBag.PasswordLength = MembershipService.MinPasswordLength; ViewBag.OpenID = OpenID; return View(); }
并修改[ActionResult Register(RegisterModel model)]来使用OpenID
创建用户:
[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,用以下替换标记:
@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,让我们点击[新用户,注册]按钮,你会得到这个:
13-点击[注销]并使用相同的OpenID重新登录,你将会看到这样的页面:
14-点击绿色按钮,你会得到一个这样的页面:
恭喜 !现在,您已将OpenID集成到您的项目中.