Some days ago a friend asked me to help do a single point of login, in fact, this concept has long been familiar, but the practical application of very few, rare recently patronagejob, so decided to use this article to describe in detail an SSO solution, we hope to help. There are many solutions to SSO, but the results are disappointing, most of them are reproduced, and the description is also a quick walkthrough.
Gossip less, get to the point, my idea is to use a centralized authentication method, multiple sites centralized Passport authentication. As shown in the following:
For the convenience of a clear description, first define a few nouns, the article appears in the following meanings.
Master : Passport centralized authentication server http://www.passport.com/ .
Sub-stations :http://www.a.com/,http://www.b.com/,http://www.c.com/
voucher : Data ID generated after user login, used to identify authorized users, can be in many ways, the main station in the demo I am using the cache, sub-station use session.
tokens : A passport-issued unique identification that can circulate in each sub-station.
OK, now describe the single sign-on process:
Situation one, anonymous user: Anonymous user access to a licensing page on the station A, first jump to the main station let the user enter the account number, password to log in, verify through the generation of Master station credentials, at the same time generate tokens, jump back to the station A, at this time station a detected that the user has a token, then use the token to go to When successful, allows the user to access the authorization page. At the same time, the local credentials of station A are generated, and when the user needs to authenticate again, the local credentials are checked to reduce network interaction.
Scenario two, in the station a login user access sub-station B: Because the user has logged in at Station A, has a token, so the station B will use the token to go to the master station to obtain the user credentials, to obtain the success of allowing users to access the authorization page. Generate local credentials for station B at the same time.
After the design is complete, here are some key points of the scenario implementation:
Token: The token is issued by the master, the master issue token generates user credentials at the same time, and the correspondence between the token and the user credential is recorded to correspond to the credential according to the token provided by the user, and the token is circulated in each cross-domain station, so the token in the demo uses the master's cookie. and specify cookie.domain= "passport.com". How does each station share the master's cookie? From the sub-station redirect to the main station page, and then the page read the cookie and return the URL parameters, you can see the detailed implementation in the demo code, of course, if there is a better way to implement the token to share.
Generate tokens
String tokenvalue = Guid.NewGuid (). ToString (). ToUpper ();
HttpCookie Tokencookie = new HttpCookie ("Token");
TOKENCOOKIE.VALUES.ADD ("Value", Tokenvalue);
Tokencookie.domain = "passport.com";
Response.appendcookie (Tokencookie);
Master Credentials : The master credential is a relational table that contains three fields: token, credential data, expiration time. There are a variety of implementations to choose from, require reliable use of the database, requirements for performance in the Cache,demo I use a DataTable in the cache. As shown in the following code:
<summary>
Initializing data structures
</summary>
<remarks>
/// ----------------------------------------------------
/// | Token (tokens) | Info (user credential) | Timeout (expiry time) |
/// |--------------------------------------------------|
</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 expiration time is token expiration
HttpContext.Current.Cache.Insert ("CERT", DT, NULL, DateTime.MaxValue, Timespan.fromminutes (double). Parse (system.configuration.configurationmanager.appsettings["Timeout"]) * 2));
}
}
Station voucher : The station voucher is mainly used to reduce the interaction of the network during duplicate authentication, for example, the user has logged on at station A, and when he accesses station a again, it is not necessary to use the token to authenticate with the master, because station a already has the user's credentials. The sub-station voucher is relatively simple, using session, cookie can be.
Sub-station SSO page base class : A page that uses SSO for a station will do a series of logical judgments, such as the flowchart at the beginning of the article. If there are multiple pages, it is not possible for each page to write one such logic, OK, then the set of logic into a base class, all the pages to use SSO to inherit the base class. As shown in the following code:
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>
Authorization page base class
</summary>
public class AuthBase:System.Web.UI.Page
{
protected override void OnLoad (EventArgs e)
{
if (session["Token"]! = NULL)
{
The presence of the station voucher
Response.Write ("Congratulations, the station voucher exists, you are authorized to access this page!") ");
}
Else
{
Token validation Results
if (request.querystring["Token"]! = NULL)
{
if (request.querystring["Token"]! = "$Token $")
{
Holding a token
String tokenvalue = request.querystring["Token"];
Call WebService to get the master station credentials
Sso. SiteA.RefPassport.TokenService tokenservice = new SSO. SiteA.RefPassport.TokenService ();
Object o = tokenservice.tokengetcredence (tokenvalue);
if (o! = null)
{
Token is correct
session["Token"] = O;
Response.Write ("Congratulations, the token exists, you are authorized to access the page!") ");
}
Else
{
Token error
Response.Redirect (This.replacetoken ());
}
}
Else
{
No token held
Response.Redirect (This.replacetoken ());
}
}
No token validation, go to master authentication
Else
{
Response.Redirect (This.gettokenurl ());
}
}
Base. OnLoad (e);
}
<summary>
Get URL with token request
Append the token request parameter to the current 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>
Remove a token from the URL
Remove the token parameter from the current 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
}
user exit: when the user exits, the master voucher and the current station voucher are emptied separately. If a site is required to exit, B and C sites also exit, you can expand the interface to clear each of the station credentials.
Master Expired Voucher/token purge : Timed purge (DataTable) cache[The timeout field exceeds the current time record in "CERT".
Click here to download demo
1. Configure the site in IIS
Configure 4 sites to point to the appropriate directories and specify the host headers for 4 sites, respectively:
http://www.passport.com/
http://www.a.com/
http://www.b.com/
http://www.c.com/
2. Modify the Hosts file to resolve the domain name to the local site
127.0.0.1 http://www.passport.com/
127.0.0.1 http://www.a.com/
127.0.0.1 http://www.b.com/
127.0.0.1 http://www.c.com/
Transferred from: http://www.cnblogs.com/zgx/archive/2009/07/31/1536059.html
ASP. NET Single Sign-on (SSO) solutions