BS客户端的单点登录
1、参数类似于“XXXXX://?userId=system&time=1696830378038&token=38a8ea526537766f01ded33a6cdfa5bd”
2、在config里加一个LoginSecret参数可随意指定一个字符串
3、BS登录代码里会对“LoginSecret的参数值+用户ID+时间戳”进行MD5加密形成token,与传过来的Token进行比对,一致才通过,同时对时间戳进行校验,时间的有效性为3分钟,也就是时间戳代表的时间+3分钟后,若大于当前时间则校验通过。通过后,直接以传过来的用户名登录BS,否则弹出提示信息。
以下为示例代码:
public static class TokenUtil
{
private static readonly string LIVE_SECRET = "6132E474arKk56ed3384310265O876ql";
public static string GenerateToken(string userId, long time)
{
string text = LIVE_SECRET + userId + time;
return GetMd5Hash(text);
}
public static bool ValidateToken(string userId, string time, string token)
{
if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(time) || string.IsNullOrEmpty(token))
{
return false;
}
if (TimestampToDateTime(time).AddMinutes(3) < DateTime.Now)
{
return false;
}
string text = LIVE_SECRET + userId + time;
string loginSecret =ConfigurationManager.AppSettings["LoginSecret"];
if (!string.IsNullOrEmpty(loginSecret))
text = loginSecret + userId + time;
string validateToken = GetMd5Hash(text);
return token.Equals(validateToken, StringComparison.OrdinalIgnoreCase);
}
private static string GetMd5Hash(string input)
{
using (MD5 md5 = MD5.Create())
{
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2"));
}
return sb.ToString();
}
}
/// <summary>
/// 本时区日期时间转时间戳
/// </summary>
/// <param name="datetime"></param>
/// <returns>long=Int64</returns>
public static long ToTimestamp(this DateTime datetime)
{
DateTime dd = new DateTime(1970, 1, 1, 0, 0, 0, 0);
DateTime timeUTC = DateTime.SpecifyKind(datetime, DateTimeKind.Utc);//本地时间转成UTC时间
TimeSpan ts = (timeUTC - dd);
return (Int64)(ts.TotalMilliseconds);//精确到毫秒
}
/// <summary>
/// 时间戳转本时区日期时间
/// </summary>
/// <param name="timeStamp"></param>
/// <returns></returns>
public static DateTime TimestampToDateTime(this string timeStamp)
{
DateTime dd = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0), DateTimeKind.Local);
long longTimeStamp = long.Parse(timeStamp + "0000");
TimeSpan ts = new TimeSpan(longTimeStamp);
return dd.Add(ts);
}
}
调用:
public partial class Login
{
private string strTempUser;
protected override void OnLoad( EventArgs e )
{
PageLoad("Login");
try
{
if (Request["userId"] != null && Request["time"] != null && Request["token"] != null)
{
if (TokenUtil.ValidateToken(Request["userId"].ToString(), Request["time"].ToString(), Request["token"].ToString()))
{
strTempUser = Request["userId"].ToString();
User u = UsersDirectory.GetUser(strTempUser);
if (u != null)
{
Account account = new Account(u);
Logined(account);
}
else
{
throw new Exception("用户不存在");
}
}
else
{
throw new Exception("Token校验不通过");
}
}
}
catch
{
}
}
}