[CSHARP]View plaincopy
- // Generate a token
- String tokenvalue = guid. newguid (). tostring (). toupper ();
- Httpcookie tokencookie = new httpcookie ("token ");
- Tokencookie. Values. Add ("value", tokenvalue );
- Tokencookie. Domain = "passport.com ";
- Response. appendcookie (tokencookie );
Master site credential: The master site credential is a relational table that contains three fields: Token, credential data, and expiration time. There are multiple implementation methods to choose from. If you require reliability, you can use the database. If you require performance, you can use the cache. In the demo, I use the datatable in the cache. The following code is used:
[CSHARP]View plaincopy
- /// <Summary>
- /// Initialize the Data Structure
- /// </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. etettings ["timeout"]);
- Datacolumn [] keys = new datacolumn [1];
- Keys [0] = DT. Columns ["token"];
- DT. primarykey = keys;
- // The cache expiration time is the token expiration time * 2
- Httpcontext. current. cache. insert ("Cert", DT, null, datetime. maxvalue, timespan. fromminutes (double. parse (system. configuration. configurationmanager. appsettings ["timeout"]) * 2 ));
- }
- }
Substation credential: Substation creden are mainly used to reduce network interaction during repeated verification. For example, if a user has logged on to substation A and accessed substation A again, you do not need to use the token to go to the master site for verification, because substation A already has the user's credential. The substation creden。 are relatively simple and can be used with session and cookie.
Substation SSO Page Base: The sub-station uses SSO pages to perform a series of logic judgment processes, such as the flowchart at the beginning of the article. If there are multiple pages, it is impossible to write such logic for each page. OK, then this logic is encapsulated into a base class. Any page that uses SSO can inherit this base class. The following code is used:
[CSHARP]View plaincopy
- 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>
- Publicclass authbase: system. Web. UI. Page
- {
- Protectedoverride void onload (eventargs E)
- {
- If (session ["token"]! = NULL)
- {
- // The substation credential exists.
- Response. Write ("congratulations, the substation credential exists. You are authorized to access this page! ");
- }
- Else
- {
- // Token Verification Result
- If (request. querystring ["token"]! = NULL)
- {
- If (request. querystring ["token"]! = "$ Token $ ")
- {
- // Hold the token
- String tokenvalue = request. querystring ["token"];
- // Call WebService to obtain the master site credential
- SSO. sitea. refpassport. tokenservice = new SSO. sitea. refpassport. tokenservice ();
- Object o = tokenservice. tokengetcredence (tokenvalue );
- If (o! = NULL)
- {
- // The token is correct.
- Session ["token"] = O;
- Response. Write ("congratulations, the token exists. You are authorized to access this page! ");
- }
- Else
- {
- // Token Error
- Response. Redirect (this. replacetoken ());
- }
- }
- Else
- {
- // Token not held
- Response. Redirect (this. replacetoken ());
- }
- }
- // Token verification is not performed, go to the master site for verification
- Else
- {
- Response. Redirect (this. gettokenurl ());
- }
- }
- Base. onload (E );
- }
- /// <Summary>
- /// Obtain the URL with the token request
- /// Append the token request parameter to the current URL
- /// </Summary>
- /// <Returns> </returns>
- Privatestring 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 the token from the URL
- /// Remove the token parameter from the current URL
- /// </Summary>
- /// <Returns> </returns>
- Privatestring 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 logout:When the user exits, the master site creden。 and the current substation creden。 are cleared. If you want Site A to exit and site B and Site C to exit, you can expand the interface to clear the creden。 of each substation.
Master site expiration credential/token clearing: Records whose timeout field exceeds the current time in the able cache ["Cert.
Click here to download the demo
1. Configure the site in IIS
Configure four sites to point to the corresponding directory and specify the host headers of the four 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.
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/127.0.0.1/