Step1帐户登录系统(5.使用Yahoo BBAuth登录网站)

        从系列之中的上一篇文章,我介绍了如何支持Windows Live ID来登录自己的网站,这一篇按照顺序,我介绍如何支持使用Yahoo BBAuth来登录网站,和上面的一篇文章一样,我将会仅仅对具体的逻辑进行实现,不再重复基础的原理。

        关于Yahoo BBAuth的更多信息,请参考:Browser-Based Authentication

        可以先看Yahoo提供的BBAuth的原理示意图:

        第一步当然也是到Yahoo! Developer Network Home注册你的程序,注册界面大致是这样的:

        在注册完成之后,就可以在My Projects之中看到如下的应用程序信息:

        当然,Shared Secret需要点击链接才能看到,这里不得不要批评一下BBAuth的是,所有的信息注册之后没有看到什么地方可以修改,要改动一个什么(例如底下的访问数据列表),都需要重新注册一个应用程序,这样的设计似乎有点奇怪,还有一点,就是Yahoo提供的文档虽然不怎么样(我曾经因为一个时间格式问题被折磨了好久),各个范例和源码其实是很多的,只是不太好找,可能是我的英文功底不够吧。

        好,闲话少说,在经过注册之后,得到了这样几个参数:appid,secret,这几个参数在程序之中需要使用的。

        先看如何得到用来让用户登录的转向地址,这个非常容易,那几个参数也是现成的,只是格式是严格要求的,一定不能出错,否则反正Yahoo的BBAuth服务器反正就是给你出个错,让你摸不着头脑了,详细的代码还是在下面看看代码吧。

        得到转向地址并转向给Yahoo之后,就可以将用户转向到Yahoo的公共登录界面,用户登录之后,就会出现关于登录许可的提示,用户只有点击同意才能继续登录的过程。

 

        登录完成之后,就开始Yahoo的服务器的就开始回转到你的Web应用程序,回传之后,根据请求的参数,需要按顺序完成以下步骤:

        1.检查回传得Token是否正常;

        2.根据回传的Token向Yahoo的服务器请求WSSID;

        3.根据WSSID向Ymail接口请求用户的E-mail地址;

        得到E-mail地址之后,就完成了整个登录过程。

        下面是实现过程的代码:

 

ContractedBlock.gif ExpandedBlockStart.gif BBAuthServer.cs代码
  1    public class BBAuthServer:BaseServer
  2ExpandedBlockStart.gifContractedBlock.gif    {
  3        private string appid, secret, server, pathLogin, pathPwtoken_login;
  4        private int timeout=300;
  5        //采用Web.Config之中的XML节点作为构造函数参数
  6        public BBAuthServer(System.Xml.XmlNode node)
  7            : base(node)
  8ExpandedSubBlockStart.gifContractedSubBlock.gif        {
  9            for (int i = 0; i < node.Attributes.Count; i++)
 10ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 11                switch (node.Attributes[i].LocalName)
 12ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 13                    case "appid":
 14                        appid = node.Attributes[i].Value;
 15                        break;
 16                    case "secret":
 17                        secret = node.Attributes[i].Value;
 18                        break;
 19                    case "server":
 20                        server = node.Attributes[i].Value;
 21                        break;
 22                    case "pathLogin":
 23                        pathLogin = node.Attributes[i].Value;
 24                        break;
 25                    case "pathPwtoken_login":
 26                        pathPwtoken_login = node.Attributes[i].Value;
 27                        break;
 28                    case "timeout":
 29                        timeout = int.Parse(node.Attributes[i].Value);
 30                        break;
 31                }

 32            }

 33        }

 34        public bool checkRequest(HttpRequest Request)
 35ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 36            string ts = Request["ts"];
 37            string sig = Request["sig"];
 38            //先检查时间
 39            if (Math.Abs(long.Parse(ts) - ((long)((DateTime.UtcNow - new DateTime(197011)).TotalSeconds))) > timeout)
 40ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 41           //     throw new Exception("Error parsing timeout.");
 42            }

 43            //再检查签名
 44            string baseString = System.Text.RegularExpressions.Regex.Replace(Request.Url.PathAndQuery, "&sig=[^&]+""");
 45            if (System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(baseString + secret, "MD5").ToLower() != sig)
 46ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 47                throw new Exception("Signature mismatch:" + baseString);
 48            }

 49            return true;
 50        }

 51        public string getWSSID(string token,out string cookie)
 52ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 53            string ts = ((long)((DateTime.UtcNow - new DateTime(197011)).TotalSeconds)).ToString();
 54            string baseString = pathPwtoken_login+"appid=" + HttpUtility.UrlEncode(appid) + "&token=" + HttpUtility.UrlEncode(token) + "&ts=" + ts + "";
 55            string sig = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(baseString + secret, "MD5").ToLower();
 56            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(server + baseString + "&sig=" + sig));
 57            request.Method = "GET";
 58            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 59            XmlDocument doc = new XmlDocument();
 60            doc.Load(response.GetResponseStream());
 61            cookie = doc.SelectSingleNode("//*[local-name()='Cookie']").InnerText.Trim().Substring(2);
 62            return doc.SelectSingleNode("//*[local-name()='WSSID']").InnerText.Trim();
 63        }

 64        public string getUserName(string token,string wssid,string cookie)
 65ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 66            try
 67ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 68                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("http://mail.yahooapis.com/ws/mail/v1.1/soap?appid=" + HttpUtility.UrlEncode(appid) + "&WSSID=" + HttpUtility.UrlEncode(wssid)));
 69                request.Method = "POST";
 70                request.CookieContainer = new System.Net.CookieContainer();
 71                CookieCollection collection = new CookieCollection();
 72                request.CookieContainer.Add(new Uri("http://mail.yahooapis.com/"), new Cookie("Y", cookie));
 73                byte[] bytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"utf-8\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><SOAP-ENV:Body><GetUserData xmlns=\"urn:yahoo:ymws\"></GetUserData></SOAP-ENV:Body></SOAP-ENV:Envelope>");
 74                request.Headers.Add("SOAPAction""\"\"");
 75                request.ContentType = "application/soap+xml; charset=utf-8";
 76                request.ContentLength = bytes.Length;
 77                Stream rs = request.GetRequestStream();
 78                rs.Write(bytes, 0, bytes.Length);
 79                rs.Close();
 80                HttpWebResponse response = getResponse(request);
 81                XmlDocument doc = new XmlDocument();
 82                doc.Load(response.GetResponseStream());
 83                return doc.SelectSingleNode("//*[local-name()='defaultID']").InnerText;
 84ExpandedSubBlockStart.gifContractedSubBlock.gif                /**//*
 85                ymws ymwsInstance = new ymws();
 86                ymwsInstance.Url = "http://mail.yahooapis.com/ws/mail/v1.1/soap?appid=" + appid + "&wssid=" + wssid;
 87                ymwsInstance.CookieContainer = new System.Net.CookieContainer();
 88                CookieCollection collection = new CookieCollection();
 89                ymwsInstance.CookieContainer.Add(new Uri("http://mail.yahooapis.com/"), new Cookie("Y", cookie));
 90                GetUserDataResponse userData = ymwsInstance.GetUserData(new GetUserData());
 91                return userData.data.userSendPref.defaultID;*/

 92            }

 93            catch (Exception)
 94ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 95                return wssid;
 96            }

 97        }

 98        public override string getLoginUrl()//生成登录的URL
 99ExpandedSubBlockStart.gifContractedSubBlock.gif        {
100            string ts = ((long)((DateTime.UtcNow - new DateTime(197011)).TotalSeconds)).ToString();
101            string baseString = pathLogin+"appid=" + HttpUtility.UrlEncode(appid) + "&appdata=" + HttpUtility.UrlEncode(name) + "&send_userhash=1&ts=" + ts + "";
102            string sig = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(baseString + secret, "MD5").ToLower();
103            return server + baseString + "&sig=" + sig;
104        }

105        public override void parseHandle(HttpContext page)//处理回转请求
106ExpandedSubBlockStart.gifContractedSubBlock.gif        {
107            checkRequest(page.Request);//检查回传请求是不是合法
108            string cookie;
109            string wssid = getWSSID(page.Request["token"],out cookie);//先获取wssid
110            string name = getUserName(page.Request["token"], wssid, cookie);//通过wssid获取用户名
111            //检查完毕,开始获得用户的WSSID
112            AccountHelper.setUserInfo(page.Request["userhash"], name, this.name);
113            AccountHelper.returnOpener();
114            page.Response.End();
115        }

116        public static HttpWebResponse getResponse(HttpWebRequest request)
117ExpandedSubBlockStart.gifContractedSubBlock.gif        {
118            try
119ExpandedSubBlockStart.gifContractedSubBlock.gif            {
120                return (HttpWebResponse)request.GetResponse();
121            }

122            catch (WebException e)
123ExpandedSubBlockStart.gifContractedSubBlock.gif            {
124                HttpContext.Current.Response.Write(e.Message);
125                string result = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
126                HttpContext.Current.Response.Write(result);
127                HttpContext.Current.Response.End();
128            }

129            return null;
130        }

131    }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值