Simple implementation of single sign-on in ASP.

Source: Internet
Author: User
Tags random seed

Basic architecture of the system

Let's assume that a systems system includes three separate sites for service customer Service center, shop Online shopping center, and Office Online Office Center. Service manages customer information, login and logoff procedures. The system will go to the login screen regardless of the client's access to any page of system, and automatically transfer to the customer's last requested page after the user logs in. And the user can then seamlessly switch between the system. You do not need to log in again. That is, single sign-on SSO is implemented in System sign-on.

We know that the user's immediate state is usually using application, Session, cookie, and storage. These are not accessible across sites in the program. We must communicate between sites to confirm the user's immediate status.

  A simple implementation

, which describes the process by which a user accesses the system.


The first step is to assume that the user has visited any of the shop or office pages. The site where the page is located will check the user's immediate status. If the user is already logged in, the information for the any page is returned to the user. If the user is not logged in yet, automatically goes to the service's validate page to verify the user's service status. That is, shop or office makes a request to the service that requires the service to return the user's immediate status.

In the second step, validate verifies the user's immediate status, and if the user is already logged in, the service returns the user's immediate status to the shop or Office Sync page synchronous, notifying the shop or office of synchronizing the user state. If the user is not logged in, it automatically turns to the customer page, prompting the user to sign in.

The third step, the user completes the login process, when the user successfully login, automatically back to the Validate page, notify shop or office synchronous for user State synchronization.

The fourth step, after the user state synchronization completes, at the local site, the user status becomes online status, can access any page.

In the process above. We know that no matter which site the user visits, the user only needs to log in once, to ensure that the user in the immediate state of the service is online, no longer require a second logon process.

Now we have a clear idea of the implementation we will be doing in code analysis.
Code Analysis

As we can see from the above process, the code for shop and office in the system is quite similar. As long as the shop can be implemented, office can also clone the same. So our focus is on the code of Shop and service.



1. Web. config and Project.cs

In the shop's web. config, we configured the Service site and store site so that we could easily modify it when we deployed it.





References are made in the project class.

Using System;
Using System.Configuration;

Namespace Amethysture.SSO.Shop
{
public class Project
{
public static string service = configurationsettings.appsettings["service"];
public static string WebSite = configurationsettings.appsettings["WebSite"];
}
}


2, Shop of Global.cs

Shop Global.cs defines four session variables, which the UserID uses to identify a user. Pass identifies the user's immediate status, and security's communication to keep the service and shop is not counterfeit. The URL saves the last requested page, ensuring that the user can go to the requested page after they log 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, Shop of Any.cs

Shop Any.cs does not contain code, because the any class inherits from the page, for code Analysis convenience, we put the code into Page.cs.

Using System;
Using System.Web;

Namespace Amethysture.SSO.Shop
{
public class Any:Amethysture.SSO.Shop.Page
{
}
}


4, Shop of Page.cs

The page class has two methods, Customervalidate and initialize. The Customervalidate user checks the user's immediate state, and initialize is the information sent to the user after the page is logged in. Our focus is on the customervalidate.

Customervalidate is a very simple process, using conditional statements to check the status of the pass, if Pass is no, it means that the user is not logged in, the page jumps to the service's validate page. What we want to analyze is the URL that is saved and the website and security several parameters that are submitted. The role of the URL is already clear in the previous, just to ensure that the user log back to the original page. The website is to ensure that the site is accepted by the service and that the service knows which site is requesting the user's immediate status. Because this example is a simple example, there is no validation in the following validate whether the website is an accepted request site, but this should be verified in practical 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 a very important point. The shop sends a request to the service and does not need to ensure that the request has not been tampered with, but the service answer shop request must ensure that the data that is answered is not tampered with. Security is designed to keep your data safe.

In code, security is generated by hashing a randomly generated number. is uncertain. and confidentiality. We can see that security is also saved in session and sent to service. We take this security as a clear text. In the back we can see that security in the service after another hash as a cipher sent back to shop. If we pass the session saved security through the same hash method and wait until the string is the same as the cipher returned by the service, we can guarantee to some extent that the service response data has not been modified.

Using System;
Using System.Web;
Using System.Security.Cryptography;
Using System.Text;

Namespace Amethysture.SSO.Shop
{
public class Page:System.Web.UI.Page
{
private void Customervalidate ()
{
BOOL Pass = (bool) this. session["Pass"];
if (! Pass)
{
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)
{
Security + = (int) o + "O";
}
This. session["security"] = security;
This. session["URL"] = this. Request.rawurl;
This. Response.Redirect (Project.service + "/validate.aspx? Website= "+ project.website +" &security= "+ Security);
}
}

protected virtual void Initialize ()
{
This. Response.Write ("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 that our page has been transferred to the service's validate page, we turn to the service code. In global we also define four session variables, which are similar to the use of a shop's session. Website is the site information that holds the immediate state of the requesting user. So that you can return to the correct request site after logging in.

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 Validate.cs

First, save the parameters passed by the shop to the session. If the user is not logged in, go to the customer page to sign in. If the user is already logged in. The user's immediate state is passed back to the shop site. As mentioned above, the security is re-hashed once back to the shop, to ensure that the data is not modified.

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. Service Customer.cs and Login.cs

The customer is primarily a form for login, where the code is not posted. Here is an analysis of the login code, this code is when the login is done directly at the service (website is a null value), the page will not go to shop or office site. So the service site should be paused. If the system is perfect, it should show a turn-by-link for a set of word systems. Below we see, when the pass is true, the page goes back to the Validate page, through the above analysis, we know that the page will turn to shop synchronous page, the user state synchronization.

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, Shop of Synchronous.cs

Well, we've completed the login in the service and passed the user status back to the shop site. We then look at how the user state is synchronized. First, if security in the session is an empty string, it is clearly wrong that the shop site did not send a request to the service and the service sent the request back to the store. This visit was made by the client and was denied access. The same security and insecurity are different, which means that the request and the response are mismatched. Perhaps the answer was tampered with, so the answer was also rejected. When the test security passed, we guarantee that Serive completed the response, and returned the exact parameters, the following is read out the parameters synchronization shop site and the user's immediate status of the 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, Shop of Page.cs

We know that the page does not refresh after a period of time, the session will expire, when we have been visiting shop, how to ensure that the service session will not expire? Very simply, we returned to look at the shop's Page.cs. By using a nested service page within all shop pages, you can ensure that the service can be refreshed with the page of your shop. One thing to note is that the session of the service must be guaranteed to be no less than the session timeout for all shop and office. This can be configured in Web. config.&lt;br&gt;&lt;br&gt;&lt;/p&gt;

This. Response.Write (" ");


  Summary

A complete login is complete. Let's say we're going to jump to any page of office now, what's the system going to do? Any (user not logged in)->validate (user is logged in)->synchronous (sync)->any. This time, the user does not have to log in the process. We log in once, making the service user status logged in, and no matter how many Web sites are used, as long as these sites are guaranteed to conform to the shop's features, these sites can maintain the service's user status while being able to get the user's status through the service. That means we've implemented SSO.

Reprinted from: http://www.cnblogs.com/oec2003/archive/2007/05/18/751016.html

Simple implementation of single sign-on in ASP.

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.