. Net Single Sign-On Design and Practice,. net Single Sign-On Practice

Source: Internet
Author: User

. Net Single Sign-On Design and Practice,. net Single Sign-On Practice

Preface

Recently it was my turn to share my knowledge in the morning meeting of the group. I suddenly thought of Single Sign-On. I am going to share with you how to implement Single Sign-On. The implementation scheme and Code may not be very rigorous. If you have any vulnerabilities or errors, please let us know.

At the beginning, I had no idea. I directly went to the blog park to see how others implemented the solution. I read several articles and found that the solution was a bit problematic, or it was not a single sign-on function.

Name Definition

To help describe the meanings of nouns in the following articles:

P site: log on to the authorization verification center in a unified manner. In the demo, the domain name is www.passport.com: 801.

Site A: Test website under different domain names. In demo, the domain name is www.a.com: 802.

Site B: Test website under different domain names. In demo, the domain name is www. B .com: 803.

Token: The key used by the user to access the P site

Ticket: the encrypted string used to save user information

Single Sign-on

If you need to log on to site A, you can log on to site P. After you log on to site P, you can jump back to site A. Then, you can access the page on Site B again, you do not need to perform the login operation to access the service normally.

Implementation

When A user is not logged on to site A, the system redirects to site P authorization center. Site P first checks the Cookie to determine whether the current logon is not in the logon status, and then redirects to the logon page for login, after successful login, the User Information Encryption ticket is attached to A's request address and returned. Site A decrypts ticket to obtain the user information, the decryption succeeds and is stored in the Session (so that the user is logged on to site A). The access passes. When the user accesses Site B again, for site B, if the user is not logged on, the user will also redirect to the P site authorization center. The P site checks the Cookie and determines that the current user is logged on, it encrypts the current user information into A ticket and attaches it to the request address of B to return the result. The subsequent operations are the same as those of Station A. After login, the user will access A or B again, user information is stored in sessions A and B, so the user will not request the P site again.

Simple Relationship Diagram

Lane Flowchart

Main logic description

Main logic of station

The user first accesses Site A. the Token is generated in Site A and saved to the Cache. Token is the key for A to access P. P must carry this Token when calling back to. A requests P and P to verify the Token and P calls back A. A checks whether the Token is the Token sent out. After the verification, the Token becomes invalid to prevent the Token from being used again.

The Token is generated by using MD5 encryption for different fields of the timestamp. Of course, you can add a salt for anti-counterfeiting.

/// <Summary> /// generate the key /// </summary> /// <param name = "timestamp"> </param> /// <returns> </returns> public static string CreateToken (DateTime timestamp) {StringBuilder securityKey = new StringBuilder (MD5Encypt (timestamp. toString ("yyyy"); securityKey. append (MD5Encypt (timestamp. toString ("MM"); securityKey. append (MD5Encypt (timestamp. toString ("dd"); securityKey. append (MD5Encypt (timestamp. toString ("HH"); securityKey. append (MD5Encypt (timestamp. toString ("mm"); securityKey. append (MD5Encypt (timestamp. toString ("ss"); return MD5Encypt (securityKey. toString ());}

When P calls back A, A verifies the Token. If the verification fails, the request is sent to site P for unified authorization verification.

/// <Summary> /// authorization enumeration /// </summary> public enum AuthCodeEnum {Public = 1, login = 2} // <summary> // authorization filter /// </summary> public class AuthAttribute: actionFilterAttribute {// <summary> // permission Code // </summary> public AuthCodeEnum Code {get; set ;} /// <summary> /// verify the permission /// </summary> /// <param name = "filterContext"> </param> public override void OnActionExecuting (ActionExecutingContext fi LterContext) {var request = filterContext. httpContext. request; var session = filterContext. httpContext. session; // if there is identity information if (Common. currentUser = null) {if (Code = AuthCodeEnum. public) {return;} string reqToken = request ["Token"]; string ticket = request ["Ticket"]; Cache cache = HttpContext. current. cache; // ticket that does not get the Token or fails Token verification or does not get the callback from P will request P TokenModel tokenModel = cache again. get (C OnstantHelper. TOKEN_KEY) = null? Null :( TokenModel) cache. Get (ConstantHelper. TOKEN_KEY); if (string. IsNullOrEmpty (reqToken) | tokenModel = null | tokenModel. Token! = ReqToken | string. isNullOrEmpty (ticket) {DateTime timestamp = DateTime. now; string returnUrl = request. url. absoluteUri; tokenModel = new TokenModel {TimeStamp = timestamp, Token = AuthernUtil. createToken (timestamp)}; // Add the Token to the cache. The cache expiration time is designed to be 20 minutes. add (ConstantHelper. TOKEN_KEY, tokenModel, null, DateTime. now. addMinutes (20), Cache. noSlidingExpiration, CacheItemPriority. default, null); filterContext. result = new ContentResult {Content = GetAuthernScript (AuthernUtil. getAutherUrl (tokenModel. token, timestamp), returnUrl)}; return;} LoginService service = new LoginService (); var userinfo = service. getUserInfo (ticket); session [ConstantHelper. USER_SESSION_KEY] = userinfo; // If the verification succeeds, the Token is removed from the cache to ensure that each token can be used only once. remove (ConstantHelper. TOKEN_KEY );}} /// <summary> /// generate a jump script /// </summary> /// <param name = "authernUrl"> unified authorization address </param> /// <param name = "returnUrl"> callback address </param> // <returns> </returns> private string GetAuthernScript (string authernUrl, string returnUrl) {StringBuilder sbScript = new StringBuilder (); sbScript. append ("<script type = 'text/javascript '>"); sbScript. appendFormat ("window. location. href = '{0} & returnUrl =' + encodeURIComponent ('{1}'); ", authernUrl, returnUrl); sbScript. append ("</script>"); return sbScript. toString ();}}

Code Description: To facilitate the Token expiration time, use the Cache to access the Token and set the Token expiration time to two minutes. If the verification succeeds, the Token is removed from the cache.

Filter Retrieval

[Auth(Code = AuthCodeEnum.Login)]     public ActionResult Index()     {       return View();    }

Main logic of P Station

Station P receives the authorization request. Station P first uses Coookie to determine whether to log on. If it is not logged on, it jumps to the login page for login.

/// <Summary> /// authorization login verification /// </summary> /// <returns> </returns> [HttpPost] public ActionResult PassportVertify () {var cookie = Request. cookies [ConstantHelper. USER_COOKIE_KEY]; if (cookie = null | string. isNullOrEmpty (cookie. toString () {return RedirectToAction ("Login", new {ReturnUrl = Request ["ReturnUrl"], Token = Request ["Token"]});} string userinfo = cookie. toString (); var success = passports Ervice. AuthernVertify (Request ["Token"], Convert. ToDateTime (Request ["TimeStamp"]); if (! Success) {return RedirectToAction ("Login", new {ReturnUrl = Request ["ReturnUrl"], Token = Request ["Token"]});} return Redirect (passportservice. getReturnUrl (userinfo, Request ["Token"], Request ["ReturnUrl"]);}

If you have logged on, verify the Token.

/// <Summary> /// verify the token /// </summary> /// <param name = "token"> token </param> /// <param name = "timestamp"> timestamp </param> // <returns> </returns> public bool authernverken (string token, dateTime timestamp) {return AuthernUtil. createToken (timestamp) = token ;}

Test Description

1. Modify the host

127.0.0.1 www.passport.com

127.0.0.1 www.a.com

127.0.0.1 www. B .com

2. Deploy IIS

Pwww.passport.com: 801

Www.a.com: 802

Www. B .com: 803

3. Test account and webconfig

<Add key = "PassportCenterUrl" value = "http://www.passport.com: 801"/>

Username: admin Password: 123

Demo

: Source code

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Related Article

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.