>  기사  >  백엔드 개발  >  .Net 기반 SSO(Single Sign-On) 구현 솔루션

.Net 기반 SSO(Single Sign-On) 구현 솔루션

高洛峰
高洛峰원래의
2016-12-28 16:17:502047검색

얼마 전 친구가 SSO(Single Sign-On)에 대해 도움을 요청했습니다. 사실 이 개념은 오래 전부터 익숙했지만, 최근에는 실용적인 응용 프로그램이 거의 없었기 때문에 설명하기로 했습니다. 이 글을 통해 SSO 솔루션을 자세히 알아보시어 모든 분들께 도움이 되었으면 좋겠습니다. SSO 솔루션은 많지만 검색 결과가 실망스럽습니다. 대부분 서로 재게시되고 설명도 피상적입니다.
더 이상 고민하지 않고 본론으로 들어가겠습니다. 여러 사이트에서 중앙 집중식 확인과 중앙 집중식 여권 확인을 사용하는 것입니다. 아래 그림과 같습니다.

.Net 기반 SSO(Single Sign-On) 구현 솔루션

명확한 설명을 돕기 위해 먼저 이 글에 나오는 몇 가지 의미를 정의합니다.
주요사이트 : 여권중앙인증서버 http://www.passport.com/.
지점 사이트: http://www.a.com/, http://www.b.com/, http://www.c.com/
크리덴셜: 사용자 로그인 후 생성되는 데이터 식별, 승인된 사용자를 식별하는 데 사용되며 DEMO에서는 기본 사이트에 Cache를 사용하고 하위 사이트에 Session을 사용합니다.
토큰(Token) : 패스포트가 발행한 고유 식별자로, 각 지점에서 유통될 수 있습니다.
이제 Single Sign-On 프로세스를 설명합니다.
시나리오 1. 익명 사용자: 익명 사용자가 하위 사이트 a의 인증 페이지에 액세스합니다. 먼저 기본 사이트로 이동하여 사용자가 로그인할 수 있도록 허용합니다. 인증을 통과한 후 메인 사이트 자격 증명이 생성되고 동시에 토큰이 생성되어 하위 사이트 a로 다시 이동합니다. 이때 하위 사이트 a는 다음을 감지합니다. 사용자는 이미 토큰을 보유하고 있으므로 토큰을 사용하여 사용자 자격 증명을 얻기 위해 다시 기본 사이트로 이동합니다. 사용자는 인증 페이지에 액세스할 수 있습니다. 동시에 사용자를 다시 인증해야 하는 경우 지점 a의 로컬 자격 증명이 생성되며, 네트워크 상호 작용을 줄이기 위해 먼저 로컬 자격 증명을 확인합니다.
시나리오 2: 하위 사이트 a에 로그인한 사용자가 하위 사이트 b를 방문합니다. 사용자가 하위 사이트 a에 로그인했고 이미 토큰을 보유하고 있기 때문에 하위 사이트 b는 토큰을 사용하여 다음 사이트로 이동합니다. 기본 사이트에서 사용자 자격 증명을 얻으면 사용자는 인증 페이지에 액세스할 수 있습니다. 동시에 변전소 b의 로컬 자격 증명이 생성됩니다.

.Net 기반 SSO(Single Sign-On) 구현 솔루션

설계가 완료된 후 솔루션 구현의 핵심 사항은 다음과 같습니다.
토큰: 토큰은 메인 스테이션에서 발행되며, 메인 스테이션이 발행합니다. 토큰을 생성하고 동시에 사용자 자격 증명을 생성하고 토큰과 사용자 자격 증명 간의 대응을 기록하여 사용자가 제공한 토큰을 기반으로 해당 자격 증명에 응답합니다. 토큰은 다양한 도메인 간 하위 스테이션에서 순환되어야 합니다. 데모에서는 주 스테이션의 토큰 쿠키를 사용하고 Cookie.Domain="passport.com"을 지정합니다. 각 지점 사이트는 기본 사이트의 쿠키를 어떻게 공유합니까? 하위 사이트에서 기본 사이트 페이지로 리디렉션하면 페이지에서 쿠키를 읽고 이를 URL 매개변수 형식으로 다시 보냅니다. 물론 더 나은 토큰이 있는 경우 DEMO 코드에서 자세한 구현을 볼 수 있습니다. 구현, 공유해주세요.

//产生令牌 
string tokenValue = Guid.NewGuid().ToString().ToUpper(); 
HttpCookie tokenCookie = new HttpCookie("Token"); 
tokenCookie.Values.Add("Value", tokenValue); 
tokenCookie.Domain = "passport.com"; 
Response.AppendCookie(tokenCookie);

기본 사이트 자격 증명: 기본 사이트 자격 증명은 토큰, 자격 증명 데이터 및 만료 시간의 세 가지 필드를 포함하는 관계형 테이블입니다. 선택할 수 있는 구현 방법은 다양하며, 안정성이 필요하면 데이터베이스를 사용하고, DEMO에서는 Cache에서 DataTable을 사용했습니다. 다음 코드에 표시된 대로:

/// <summary> 
/// 初始化数据结构 
/// </summary> 
/// <remarks> 
/// ---------------------------------------------------- 
/// | token(令牌) | info(用户凭证) | timeout(过期时间) | 
/// |--------------------------------------------------| 
/// </remarks> 
private static void cacheInit() 
{ 
if (HttpContext.Current.Cache["CERT"] == null) 
{ 
DataTable dt = new DataTable(); 
dt.Columns.Add("token", Type.GetType("System.String")); 
dt.Columns["token"].Unique = true; 
dt.Columns.Add("info", Type.GetType("System.Object")); 
dt.Columns["info"].DefaultValue = null; 
dt.Columns.Add("timeout", Type.GetType("System.DateTime")); 
dt.Columns["timeout"].DefaultValue = DateTime.Now.AddMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings["timeout"])); 
DataColumn[] keys = new DataColumn[1]; 
keys[0] = dt.Columns["token"]; 
dt.PrimaryKey = keys; 
//Cache的过期时间为 令牌过期时间*2 
HttpContext.Current.Cache.Insert("CERT", dt, null, DateTime.MaxValue, TimeSpan.FromMinutes(double.Parse(System.Configuration.ConfigurationManager.AppSettings["timeout"]) * 2)); 
} 
}

하위 사이트 자격 증명: 하위 사이트 자격 증명은 주로 반복 확인 중에 네트워크 상호 작용을 줄이는 데 사용됩니다. 예를 들어 사용자는 하위 사이트 a에 로그인했습니다. 그리고 그가 하위 사이트 a를 다시 방문하면, 지점 a가 이미 사용자의 자격 증명을 가지고 있기 때문에 확인을 위해 메인 사이트로 이동하기 위해 토큰을 사용할 필요가 없습니다. 하위 사이트 자격 증명은 비교적 간단하며 세션이나 쿠키를 사용할 수 있습니다.
하위 사이트 SSO 페이지의 기본 클래스: SSO를 사용하는 하위 사이트의 페이지는 기사 시작 부분의 흐름도와 같은 일련의 논리적 판단 처리를 수행합니다. 여러 페이지가 있는 경우 각 페이지에 대해 이러한 논리를 작성하는 것은 불가능합니다. 그런 다음 이 논리 세트를 기본 클래스로 캡슐화하면 SSO를 사용하려는 모든 페이지가 이 기본 클래스를 상속할 수 있습니다. 다음 코드에 표시된 대로:

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Text.RegularExpressions; 
namespace SSO.SiteA.Class 
{ 
/// <summary> 
/// 授权页面基类 
/// </summary> 
public class AuthBase : System.Web.UI.Page 
{ 
protected override void OnLoad(EventArgs e) 
{ 
if (Session["Token"] != null) 
{ 
//分站凭证存在 
Response.Write("恭喜,分站凭证存在,您被授权访问该页面!"); 
} 
else 
{ 
//令牌验证结果 
if (Request.QueryString["Token"] != null) 
{ 
if (Request.QueryString["Token"] != "$Token$") 
{ 
//持有令牌 
string tokenValue = Request.QueryString["Token"]; 
//调用WebService获取主站凭证 
SSO.SiteA.RefPassport.TokenService tokenService = new SSO.SiteA.RefPassport.TokenService(); 
object o = tokenService.TokenGetCredence(tokenValue); 
if (o != null) 
{ 
//令牌正确 
Session["Token"] = o; 
Response.Write("恭喜,令牌存在,您被授权访问该页面!"); 
} 
else 
{ 
//令牌错误 
Response.Redirect(this.replaceToken()); 
} 
} 
else 
{ 
//未持有令牌 
Response.Redirect(this.replaceToken()); 
} 
} 
//未进行令牌验证,去主站验证 
else 
{ 
Response.Redirect(this.getTokenURL()); 
} 
} 
base.OnLoad(e); 
} 
/// <summary> 
/// 获取带令牌请求的URL 
/// 在当前URL中附加上令牌请求参数 
/// </summary> 
/// <returns></returns> 
private string getTokenURL() 
{ 
string url = Request.Url.AbsoluteUri; 
Regex reg = new Regex(@"^.*\?.+=.+$"); 
if (reg.IsMatch(url)) 
url += "&Token=$Token$"; 
else 
url += "?Token=$Token$"; 
return "http://www.passport.com/gettoken.aspx?BackURL=" + Server.UrlEncode(url); 
} 
/// <summary> 
/// 去掉URL中的令牌 
/// 在当前URL中去掉令牌参数 
/// </summary> 
/// <returns></returns> 
private string replaceToken() 
{ 
string url = Request.Url.AbsoluteUri; 
url = Regex.Replace(url, @"(\?|&)Token=.*", "", RegexOptions.IgnoreCase); 
return "http://www.passport.com/userlogin.aspx?BackURL=" + Server.UrlEncode(url); 
} 
}//end class 
}

사용자 종료: 사용자가 종료하면 기본 사이트 자격 증명과 현재 하위 사이트 자격 증명이 각각 지워집니다. 사이트 A를 종료해야 하고 사이트 B와 C도 종료해야 하는 경우 인터페이스를 확장하여 각 변전소의 자격 증명을 지울 수 있습니다.
기본 사이트의 만료된 자격 증명/토큰을 삭제합니다. (DataTable) 캐시["CERT"]의 시간 초과 필드가 현재 시간을 초과하는 기록을 정기적으로 삭제합니다.

.Net 기반 SSO(Single Sign-On) 구현 솔루션과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.