Single point access scheme summarizes

Single sign-on login credentials to first obtain a unified portal, then get authenticated login name, last login name to authenticate access to the system and create the session. It is also a convention manner, according to several such strings including a timestamp encrypted and a key, and decrypts data obtained agreed manner. Old-fashioned single-point domain name by way of the token is stored in the Cookie, the mode does not support cross-domain or IP mode, there are certain limitations. The use of the new single point redirection, the portal system to automatically attached by the application access interface, or IP protocol itself is not limiting.

The following several common way to sum up a single point.

CAS landing

CAS landing contains landing address, verify the address and exit address. Access system first needs to register an application by the service identification parameter.

The sample code is written in C #, other languages ​​can be rewritten. The underlying principle can be analyzed using a packet sniffer way.

When there is no session, went to visit CAS landing address for landing, the parameter service. After successful authentication, CAS will address the callback service and ticket parameters to the application. Carried out to verify the ticket and by obtaining service, verify successful return an XML response that contains user login name that is.

Generally the CAS address of the form:

Login: ...... / cas directory / login

Verify: ...... / cas directory / proxyValidate

Logout: ...... / cas directory / logout

public string getHost()

{

 Boolean https=Request.ServerVariables["HTTPS"].ToLower().Equals("on");

   String Host=Request.ServerVariables["HTTP_HOST"];

   return (https ? "https://" : "http://") + Host;

}

public String getEmployeeID ()

{

  string loginaspx =HttpUtility.UrlEncode(getHost()+Request.ServerVariables["PATH_INFO"]) ;

  string ticket = Request.QueryString["ticket"];

  if (ticket == null || ticket.Length == 0)

  {

      Response.Redirect(loginServer + "?service=" + loginaspx);

      return null;

  }

  string validateUrl = validateServer + "?ticket=" + ticket + "&service=" + loginaspx;

 ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);

   // return ticket validation, access to the username returned by the server

   try

   {

      StreamReader Reader = new StreamReader(new WebClient().OpenRead(validateUrl));

      string resp = Reader.ReadToEnd();

      NameTable nt = new NameTable();

      XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);

      XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);

     XmlTextReader reader = new XmlTextReader(resp, XmlNodeType.Element, context);

      string uid = null;

      while (reader.Read())

      {

          if (reader.IsStartElement())

          {

               string tag = reader.LocalName;

               if (tag == "user")

                   uid = reader.ReadString();

           }

       }

       reader.Close();

       return uid;

   }

   catch (Exception ee)

   {

        return null;

   }  

}

OAuth landing

OAuth landing approach, the portal will provide interfaces, generally provide the agreed appKey, appPassword, to obtain information in response to JSON. Similar to the CAS, the first step accessToken still need to get through the interface, and then verify accessToken get login name.

The following is a C # code example, use a method of obtaining the user's online portal, to avoid repeating each login authentication.

    public class JsonObjectAccessToken

    {

        public int type;

        public string access_token;

    }

   public class JsonObjectSession

    {

        public string status;

        public string desc;

        public Dictionary<string, string> obj;

    }

  public String getEmployeeID ()

    {

       String appKey = configNode.Attributes["appKey"].Value;

       String appPassword = configNode.Attributes["appPassword"].Value;

       String serverName = configNode.Attributes [ "serverName"] Value;. // local log entry

      string redirectUrl=HostName+Request.ServerVariables["PATH_INFO"];         string ticket = Request.QueryString["code"];

        if (ticket == null || ticket.Length == 0)

        {

            // If the portal has landed return directly login information

            String loginUserResponse = UserInfo.Text.Replace("callback(", "").Replace(")", "");

            if (loginUserResponse != null && loginUserResponse.Equals("") == false)

            {

                JsonObjectSession loginUserObject = JsonConvert.DeserializeObject<JsonObjectSession>(loginUserResponse);

                if (loginUserObject != null && loginUserObject.status.Equals("1"))

                {

                    return loginUserObject.obj["LoginName"];

                }

            }

            if (Session["ticket"] != null)

            {

                ticket = Session["ticket"].ToString();

            }

            if (ticket == null || ticket.Length == 0)

            {

                Response.Redirect(serverName + "/OAuth2/OAuth?client_id=" + appKey + "&redirect_uri=" + redirectUrl + "&forcelogin=false&state=STATE");

                return null;

            }

        }

        Session["ticket"] = ticket;

        string validateUrl = serverName + "/OAuth2/access_token?client_id=" + appKey + "&client_secret="+appPassword+"&redirect_uri=" + redirectUrl+"&code="+ticket;

        // return ticket validation, access to the username returned by the server

        try

        {

            String accessTokenResponse = getResponse(validateUrl);

            JsonObjectAccessToken accessTokenObject = JsonConvert.DeserializeObject<JsonObjectAccessToken>(accessTokenResponse);

            if (accessTokenObject != null)

            {

                if (accessTokenObject.type == 1)

                {

                   String accessToken = accessTokenObject.access_token;

                    // request user information

                    String sessionUrl = serverName + "/SSOService.asmx/user_base_info?access_token=" + accessToken;

                    String sessionResponse = getResponse(sessionUrl).Replace("(","").Replace(")","");

                    JsonObjectSession sessionObject = JsonConvert.DeserializeObject<JsonObjectSession>(sessionResponse);

                    if (sessionObject.status.Equals("1"))

                    {

  return sessionObject.obj["UserLoginName"];

                    }

                    

                }

               if (Session["ticket"] != null) Session.Remove("ticket");

            }            

        }

        catch (Exception e)

        {

            Response.Write(e.StackTrace);            

        }

        return null;  

      

    }

    public static String getTimestamp()

    {

        System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));

        long t = (DateTime.Now.Ticks - startTime.Ticks) / 10000;

        return t.ToString();

    }

 public string getResponse(String url)

    {

        Stream stream = null;

        StreamReader Reader = null;

        string responseMsg = "";

        try

        {

   HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create (url); request.Method = "GET"; // The following can be custom request header

     request.ContentType = "text/json;charset=utf-8";

     request.Timeout = 1000;

     request.Referer = HostName;

     HttpWebResponse response = (HttpWebResponse)request.GetResponse();

     stream = response.GetResponseStream();

     Reader = new StreamReader (stream, System.Text.Encoding.GetEncoding ( "utf-8")); // Self transcoding

    responseMsg = Reader.ReadToEnd (); // this decision certainly does not appear EndofStream exception.

        }

        catch

        {

        }

        finally

        {

            if (Reader != null)

            {

                Reader.Close();

                Reader.Dispose();

            }

            Reader = null;

            if (stream != null)

            {

                stream.Close();

                stream.Dispose();

            }

            stream = null;

        } 

        return responseMsg;

    }

 

Custom encryption

    public string getMD5(String plainText)

    {

        System.Security.Cryptography.MD5 key=System.Security.Cryptography.MD5.Create();

        Byte[] bytes = key.ComputeHash(System.Text.Encoding.UTF8.GetBytes(plainText));

        System.Text.StringBuilder builder = new System.Text.StringBuilder();

        foreach(Byte _byte in bytes)

        {

            builder.Append(_byte.ToString("x2").ToUpper());

        }

        return builder.ToString();

    }

 

    String verify=Request.QueryString["verify"];

    String userName=Request.QueryString["userName"];

    String strSysDatetime=Request.QueryString["strSysDatetime"];

    String jsName=Request.QueryString["jsName"];

    String key=……;

  if (getMD5(userName + key + strSysDatetime + jsName).Equals(verify))

    {

          return userName;

    }

 

Account access between the gateway and each application system to achieve synchronization, including new users and delete users. A relatively complete system, will also involve synchronize passwords.

Way single-point nature is not very safe to be forged and simulated landing. Safety is the most critical part verification. Once a user name, it will be allowed to go back.

Guess you like

Origin www.cnblogs.com/yuxiaoxu/p/12232012.html
Recommended