One Time Token Service

  • 3290
  • 0

因為目前我們的Portal要與MOSS整合,所以就修改「簡單的One-Time Token方案,應用在整合各Web AP」,將它改成Web Service。

前言

因為目前我們的Portal要與MOSS整合,所以就修改「簡單的One-Time Token方案,應用在整合各Web AP」,將它改成Web Service。

實作

image

將原本寫在各AP中的Method抽出來包成Web Service,因為傳遞QueryString可能還會再加入額外的資訊,所以提供多個回傳的Method。
以下詳細說明各Method
GenerateTokenByUserID(string userId, string extendQueryString):輸入User ID及額外的QueryString(如fid=HRF110101),產生代表該user的token。
ParseTokenQueryStringGetUserID(string queryString):解析QueryString,傳出有效的User ID。
NameValues[] ParseQueryString(string queryString):解析QueryString,傳出解密後的QueryString Key Value
NameValues[] ParseQueryStringEx(string queryString):解析QueryString傳出解密後的QueryString Key Value並解析token取出有效的User ID。

使用方式如下,


//string tokenQueryString = OTPLib.OTPHelper.GenerateTokenByUserID(Context.User.Identity.Name);
//改Call Web Service
string tokenQueryString = (new OTPService.OTPHelper()).GenerateTokenByUserID(Context.User.Identity.Name, string.Empty );
lblToken.Text = tokenQueryString;
ClientScript.RegisterStartupScript(this.GetType(), "linkWebAp2", 
"__OpenOtherWebAP('WEBAP2', 'http://localhost:3449/OTPWebAP2/Login.aspx" + tokenQueryString + "');", true);


//解析看看是否有token的QUERYSTRING,表示是OTP,所以要做登入的動作
//string userId = OTPLib.OTPHelper.ParseTokenQueryString(Request.QueryString.ToString());
//改call web services
string userId = (new OTPService.OTPHelper()).ParseTokenQueryStringGetUserID(Request.QueryString.ToString());
if (!string.IsNullOrEmpty(userId))
{
    //有Parse出UserID所以要導到預設網頁
    FormsAuthentication.RedirectFromLoginPage(userId, false);
}

Web Service的Code如下,



  const string TokenQID = "token";
  const string UserQID = "userid";

  /// <summary>
  /// 產生代表該user的token
  /// </summary>
  /// <param name="userId"></param>
  /// <param name="extendQueryString">額外的QueryString</param>
  /// <returns></returns>
  [WebMethod]
  public string GenerateTokenByUserID(string userId, string extendQueryString)
  {
    //建立新的token
    string newToken = Guid.NewGuid().ToString();
    //將資料新增到OTP_LOG之中
    DBHelper.SaveTokenLog(newToken, userId);
    if (!string.IsNullOrEmpty(extendQueryString))
        extendQueryString = "&" + extendQueryString;
    //透過QueryString,所以要加密比較好
    string result = StringHelpers.EncryptQueryString("token=" + newToken + extendQueryString);
    return result;
  }

  /// <summary>
  /// 由QueryString取得UserID
  /// </summary>
  /// <param name="queryString"></param>
  /// <returns></returns>
  [WebMethod]
  public string ParseTokenQueryStringGetUserID(string queryString)
  {
    NameValueCollection paList = StringHelpers.DecryptQueryString(queryString);
    string result = string.Empty;
    if (paList != null && paList.Count > 0)
    {
      //取得token
      string token = paList[TokenQID];
      if (!string.IsNullOrEmpty(token))
      {
        //取出userid & set IS_ACTIVE = 0
        result = DBHelper.GetActiveUserIDByToken(token);
      }
    }
    return result;
  }

   
  /// <summary>
  /// 解析QueryString傳出解密後的QueryString Key Value
  /// </summary>
  /// <param name="queryString"></param>
  /// <returns></returns>
  [WebMethod]
  public NameValues[] ParseQueryString(string queryString)
  {
    NameValueCollection paList = StringHelpers.DecryptQueryString(queryString);
    NameValues[] result = null;
    if (paList.Count > 0)
    {
      result = new NameValues[paList.Count];
      for (int i = 0; i < paList.Count; i++)
      {
                result[i] = new NameValues(paList.GetKey(i), paList.Get(i));
      }
    }
    return result;
  }

  /// <summary>
  /// 解析QueryString傳出解密後的QueryString Key Value
  /// 同時解析token取出userid
  /// </summary>
  /// <param name="queryString"></param>
  /// <returns></returns>
  [WebMethod]
  public NameValues[] ParseQueryStringEx(string queryString)
  {
    NameValueCollection paList = StringHelpers.DecryptQueryString(queryString);
    NameValues[] result = null;
    if (paList.Count > 0)
    {
      result = new NameValues[paList.Count+1];
      for (int i = 0; i < paList.Count; i++)
      {
                result[i] = new NameValues(paList.GetKey(i), paList.Get(i));
      }

      string usrID = string.Empty;
      //取得token
      string token = paList[TokenQID];
      if (!string.IsNullOrEmpty(token))
      {
        //取出userid & set IS_ACTIVE = 0
        usrID = DBHelper.GetActiveUserIDByToken(token);
      }
      result[paList.Count] = new NameValues(UserQID, usrID);
    }
        
    return result;
  }
}

結論

將One Time Token抽成Web Service比較方便各專案來使用! 因為NameValueCollection無法透過Web Service傳遞,所以解Query String改用NameValues Array來傳遞!

範例程式

OTTService.rar

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^