单点登录(跨域)
2015-08-11 23:44 Carl Xing 阅读(837) 评论(0) 编辑 收藏 举报工程目录如下图
站点Site为应用站点,SSOAuth为授权站点。
一、先看Site站点:
1、Auth目录下允许匿名用户,看Auth目录web.config
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <authorization> <allow users="*"/> </authorization> </system.web> </configuration>
根目录及其它目录阻止匿名访问,看根目录web.config
<configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> <authentication mode="Forms"> <forms name=".SiteAuth" loginUrl="~/auth/login.aspx"/> </authentication> <authorization> <deny users="?"/> </authorization> </system.web> </configuration>
登录地址为~/auth/login.aspx,这个页面其实是中转跳转到SSOAuth的Login.aspx。其中“http://www.ssoauth.com/login.aspx”就是认证站点的认证地址。
namespace Site.Auth { public partial class Login : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!string.IsNullOrEmpty(Request.QueryString["ReturnUrl"])) { string redirectUrl = "http://www.ssoauth.com/login.aspx?returnUrl=" + HttpUtility.UrlEncode( Request.Url.Scheme+"://"+Request.Url.Host+Request.QueryString["ReturnUrl"] ); Response.Redirect(redirectUrl); } } } }
再看auth目录下的login.ashx,因为认证站点需跨域访问,故返回类型符合jsonp
namespace Site.Auth { /// <summary> /// Login1 的摘要说明 /// </summary> public class Login1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/json"; string callback = context.Request.QueryString["callback"]; if (!string.IsNullOrEmpty(context.Request.QueryString["sid"])) { //todo -- check the sid is valid //add forms cookie FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "auth", DateTime.Now, DateTime.Now.AddMinutes(1), false, "siteTicketUserData"); HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName); cookie.Path = "/"; cookie.Expires = DateTime.Now.AddSeconds(30); cookie.Value = FormsAuthentication.Encrypt(ticket); context.Response.Cookies.Add(cookie); string json = "{\"status\":\"success\"}"; context.Response.Write(callback + "(" + json + ")"); } else { string json = "{\"status\":\"fail\"}"; context.Response.Write(callback + "(" + json + ")"); } } public bool IsReusable { get { return false; } } } }
二、SSOAuth站点
Login.aspx后台:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.Security; namespace SSOAuth { public partial class Login : System.Web.UI.Page { /// <summary> /// 返回路径 /// </summary> public string ReturnUrl { get { return Request.QueryString["returnUrl"]; } } /// <summary> /// 站点登录地址 /// </summary> public string SiteLogin { get; set; } /// <summary> /// 票据 /// </summary> public string Sid { get; set; } protected void Page_Load(object sender, EventArgs e) { HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (cookie == null) { loginField.Visible = true; return; } else { loginField.Visible = false; LoginSite(cookie); } } private void LoginSite(HttpCookie cookie) { Sid = cookie.Value; if (!string.IsNullOrEmpty(ReturnUrl)) { SetSiteLogin(); if (!string.IsNullOrEmpty(SiteLogin)) { divScript.Visible = true; } } } private void SetSiteLogin() { Uri hostUri = new Uri(ReturnUrl); string hostName = hostUri.Host; switch (hostName) { case "www.site1.com": SiteLogin = "http://www.site1.com/auth/login.ashx"; break; case "www.site2.com": SiteLogin = "http://www.site2.com/auth/login.ashx"; break; default: SiteLogin = null; break; } } protected void btnLogin_Click(object sender, EventArgs e) { FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "auth", DateTime.Now, DateTime.Now.AddMinutes(2), false, tbUserName.Text); HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName); cookie.Path = "/"; cookie.Value = FormsAuthentication.Encrypt(ticket); Response.Cookies.Add(cookie); LoginSite(cookie); } } }
Login.aspx前台
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="SSOAuth.Login" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script type="text/javascript" src="js/jquery-1.6.4.min.js"></script> </head> <body> <form id="form1" runat="server"> <div> <fieldset id="loginField" runat="server" visible="false"> <legend>Login</legend> <div> <label>UserName</label> <asp:TextBox ID="tbUserName" runat="server"></asp:TextBox> </div> <div> <asp:Button ID="btnLogin" runat="server" Text="Login" OnClick="btnLogin_Click" /> </div> </fieldset> </div> <div runat="server" id="divScript" visible="false"> <script type="text/javascript"> $(function () { $.ajax({ url: "<%=SiteLogin %>", data: { sid: "<%=Sid%>" }, dataType: "jsonp", jsonpCallback: "callback", success: function (data) { if (data.status == "success") { window.location.href = "<%=ReturnUrl%>"; } } }); }) </script> </div> </form> </body> </html>
三、配置
1、将Site项目配置2个站点 “www.site1.com”和"www.site2.com".
2、将SSOAuth项目配置站点名为"www.ssoauth.com".
3、访问 www.site1.com 即跳转到SSOAuth去登录,点击登录即跳转回访问页。此时再访问www.site2.com已无须再登录。