Single Sign-on

Source: Internet
Author: User
Tags random seed
Simple implementation of Single Sign-On on ASP. NET
Download this article Source code

Basic System Architecture

Assume that a system includes three independent websites: Service Customer Service Center, shop online shopping center, and office online office center. The Service manages the customer's information, logon and logout processes. No matter whether the customer accesses any page of the system, the system will go to the logon interface. After the user logs on, the system will automatically transfer to the page requested by the customer. In addition, you can seamlessly switch between systems. You do not need to log on again. Single Sign-On (SSO) is implemented in system ).

We know that the real-time status of users usually uses application, session, cookie, and storage. These cannot beProgram. We must check the real-time status of users through inter-site communication.

Simple implementation

This figure describes the process for users to access the system.

Step 1: assume that the user accesses any page of shop or office. The website where the page is located will check the user's real-time status. If the user has logged on, return the information on the any page to the user. If the user has not logged on, it will automatically go to the Service's validate page to verify that the user is in service status. That is, the shop or office sends a request to the service, requiring the service to return the user's real-time status.

Step 2: Validate verifies the real-time status of the user. if the user has logged on, the service returns the real-time status of the user to the synchronization page synchronous of the shop or office, notify shop or office to synchronize user status. If the user does not log on, the customer page is automatically displayed, prompting the user to log on.

Step 3: The user completes the logon process. After the user successfully logs on, the system automatically returns to the validate page and notifies shop or office synchronous to synchronize the user status.

Step 4: After the user status is synced, the user status becomes online on the local site to access the any page.

In the above process. We know that no matter which site the user accesses, the user only needs to log on once to ensure that the user's real-time status in the service is online and there is no need to perform the second login process.

Now our ideas are clear. The specific implementation will be inCodeThe analysis is complete.

Code Analysis

From the above process, we can see that the Shop and Office Code in the system is completely similar. As long as the shop can be implemented, the Office can also be cloned. So our key analysis objects are shop and Service Code.

1. Web. config and project. CS of the shop

In shop web. config, We have configured service sites and shop sites to facilitate modification during deployment.

<Deleetask>
<Add key = "service" value = "http: // localhost: 8001"/>
<Add key = "website" value = "http: // localhost: 8002"/>
</Appsettings>

Reference in the project class.

Using system;
Using system. configuration;

Namespace amethysture. SSO. Shop
{
Public class project
{
Public static string service = configurationsettings. deleettings ["service"];
Public static string website = configurationsettings. deleettings ["website"];
}
}

2. Global. CS of shop

Shop's global. CS defines four session variables, which are used to identify users. Pass identifies the user's real-time status. Security is used to save the communication between the service and shop. The URL stores the page of the previous request to ensure that the page can be forwarded to the user's request after the user logs on.

Protected void session_start (Object sender, eventargs E)
{
This. session. Add ("userid", 0 );
This. session. Add ("pass", false );
This. session. Add ("security ","");
This. session. Add ("url ","");
}

3. Any. CS of shop

Shop's any. CS does not contain code, because the any class inherits from page. For the convenience of code analysis, we concentrate the code into page. CS.

Using system;
Using system. Web;

Namespace amethysture. SSO. Shop
{
Public class any: amethysture. SSO. Shop. Page
{
}
}

4. Page. CS of the shop

The page class has two methods: mermervalidate and initialize. The customervalidate user checks the real-time status of the user, and initialize is the information sent to the user after logon on the page. Our focus is customervalidate.

Customervalidate is a very simple process. It uses conditional statements to check the pass status. If pass is set to no, it indicates that the user has not logged on. The page jumps to the Service's validate page. We want to analyze the saved URL and the submitted website and security parameters. The role of the URL has been clarified previously, just to ensure that the user can return to the original page after login. The website ensures that the site is accepted by the service and that the service knows which site requested the user's real-time status. This is a simple example. In the following validate, the website is not verified to be an accepted request site, but it should be verified in actual applications, because shop and service are equivalent to servers and clients, the server must check whether the client is allowed for security reasons. Security is very important. Shop sends a request to the service. It does not need to ensure that the request has not been tampered with. However, when the service responds to the shop request, it must ensure that the response data has not been tampered. Security is designed to ensure data security.

In the code, security is generated by hash a random number. Uncertainty. And confidentiality. We can see that security is saved in the session and sent to the service at the same time. We regard this security as plaintext. As we can see later, security is sent back to shop as ciphertext after the service is hashed again. If we process the Security stored in the session with the same hash method and then wait for the string to be the same as the ciphertext returned by the service, to some extent, we can ensure that the data returned by the service is not modified.

Using system;
Using system. Web;
Using system. Security. cryptography;
Using system. text;

namespace amethysture. SSO. shop
{< br> public class page: system. web. UI. page
{< br> private void customervalidate ()
{< br> bool pass = (bool) This. session ["pass"];
If (! Pass)
{< br> string SECURITY = "";
Random Seed = new random ();
Security = seed. next (1, Int. maxvalue ). tostring ();
byte [] value;
unicodeencoding code = new unicodeencoding ();
byte [] Message = code. getbytes (security);
sha512managed arithmetic = new sha512managed ();
value = arithmetic. computehash (Message);
Security = "";
foreach (byte o in value)
{< br> Security + = (INT) O + "O";
}< br> This. session ["security"] = security;
This. session ["url"] = This. request. rawurl;
This. response. redirect (project. service + "/validate. aspx? Website = "+ project. Website +" & Security = "+ Security);
}< BR >}

Protected virtual void initialize ()
{
This. response. Write ("<HTML> ");
This. response. Write ("This. response. Write ("<title> amethysture SSO project </title> ");
This. response. Write ("<LINK rel = stylesheet type = \" text/CSS \ "href = \" "+ project. Website +"/default.css \ "> ");
This. response. Write ("This. response. Write ("<body> ");
This. response. write ("<IFRAME width = \" 0 \ "Height = \" 0 \ "src = \" "+ project. service + "/customer. aspx \ "> </iframe> ");
This. response. Write ("<Div align = \" center \ "> ");
This. response. Write ("amethysture SSO shop any page ");
This. response. Write ("</div> ");
This. response. Write ("</body> ");
This. response. Write ("}

Protected override void oninit (eventargs E)
{
Base. oninit (E );
This. customervalidate ();
This. initialize ();
This. response. End ();
}
}
}

5. Service global. CS

Now we go to the Service's validate page. Let's look at the service code. In global, we also define four session variables, which are similar to the session usage of shop. Website is the site information that saves the real-time status of the requesting user. In order to return the correct site request after login.

Protected void session_start (Object sender, eventargs E)
{
This. session. Add ("userid", 0 );
This. session. Add ("pass", false );
This. session. Add ("website ","");
This. session. Add ("security ","");
}

6. Service's validate. CS

First, save the parameters passed by the shop to the session. If the user does not log on, go to the customer page to log on. If the user has logged on. Then, the user's real-time status is returned to the shop site. As mentioned above, security is re-hashed to the shop to ensure that the data is not modified by the workshop.

Private void customervalidate ()
{
Bool pass = (bool) This. session ["pass"];
If (this. Request. querystring ["website"]! = NULL) & (this. Request. querystring ["website"]! = ""))
{
This. session ["website"] = This. Request. querystring ["website"];
}
If (this. Request. querystring ["security"]! = NULL) & (this. Request. querystring ["security"]! = ""))
{
This. session ["security"] = This. Request. querystring ["security"];
}
If (PASS)
{
String userid = This. session ["userid"]. tostring ();
String website = This. session ["website"]. tostring ();
String SECURITY = This. session ["security"]. tostring ();
Byte [] value;
Unicodeencoding code = new unicodeencoding ();
Byte [] Message = code. getbytes (security );
Sha512managed arithmetic = new sha512managed ();
Value = arithmetic. computehash (Message );
Security = "";
Foreach (byte o in value)
{
Security + = (INT) O + "O ";
}
This. response. Redirect (website + "/Synchronous. aspx? Userid = "+ userid +" & pass = true & Security = "+ security );
}
Else
{
This. response. Redirect ("customer. aspx ");
}
}

7. Customer. CS and login. CS of the service

The customer is mainly a form for Logon. The code is not pasted here. Here we will analyze a piece of login code. This code will not go to the shop or office site when you log on directly to the Service (the website is null. Therefore, the service site should be suspended. If the system is perfect, the turn link of a group of word systems should be displayed here. The following shows that when pass is true, the page returns to the validate page. Through the above analysis, we know that the page will switch to the synchronous page of shop to synchronize the user status.

If (PASS)
{
If (this. session ["website"]. tostring ()! = "") & (This. session ["security"]. tostring ()! = ""))
{
This. response. Redirect ("Validate. aspx ");
}
Else
{
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("pass ");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
}
}
Else
{
This. response. Redirect ("customer. aspx ");
}

8. synchronous. CS of the shop

Now, we have logged on to the service and passed the user status back to the shop site. Let's see how the user status is synchronized. First, if the security in the session is a null string, it indicates that the shop site has not sent a request to the service, but the service has sent a request to the shop. This is obviously incorrect. The access was forged by the client, so the access was denied. If security and insecurity are the same, the request and response do not match. The response may have been changed by the response, so the response is also rejected. After the security check is passed, we ensure that serive has completed the response and returned the exact parameters. The following describes how to read the parameters to synchronize the real-time status of users on the shop site and service site.

String inuserid = This. Request. querystring ["userid"];
String inpass = This. Request. querystring ["pass"];
String insecurity = This. Request. querystring ["security"];

String SECURITY = This. session ["security"]. tostring ();
If (Security! = "")
{
Byte [] value;
Unicodeencoding code = new unicodeencoding ();
Byte [] Message = code. getbytes (security );
Sha512managed arithmetic = new sha512managed ();
Value = arithmetic. computehash (Message );
Security = "";
Foreach (byte o in value)
{
Security + = (INT) O + "O ";
}

If (SECURITY = insecurity)
{
If (inpass = "true ")
{
This. session ["userid"] = int. parse (inuserid );
This. session ["pass"] = true;
This. response. Redirect (this. session ["url"]. tostring ());
}
}
Else
{
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("data error ");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
}
}
Else
{
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("Access Error ");
This. response. Write ("");
This. response. Write ("");
This. response. Write ("");
}

9. Page. CS of the shop

We know that after the page is not refreshed for a period of time, the session will expire. How can we ensure that the Service session will not expire when we have been visiting the shop? It's easy. Let's look at the page. CS of shop. By using a <IFRAME> nested service page in all shop pages, the service can be refreshed at the same time as the shop page. Note that the Service session must be no less than the timeout time of all Shop and Office sessions. This can be configured in Web. config.

This. response. write ("<IFRAME width = \" 0 \ "Height = \" 0 \ "src = \" "+ project. service + "/customer. aspx \ "> </iframe> ");

Summary

A complete logon is complete. Next, let's assume that we want to jump to the any page of the office. What will happen to the system? Any (the user has not logged on)-> validate (the user has logged on)-> synchronous (synchronization)-> Any. That is to say, this time the user has not logged on. By using a single login, the service user is logged on, and no matter how many website applications there are, as long as these websites meet the features of shop, these websites can maintain the user status of the service and obtain the user status through the service. That is to say, we have implemented SSO.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.