/// <summary> /// 对给定的数据和内部附加的时间戳进行签名,传入的签名数据可以为null,此时相当于只签名内部附加的时间戳。 /// </summary> /// <param name="data"></param> /// <returns></returns> public Dictionary <string, string> GetSignData(ISignableData data = null) { var timestamp = Timestamp.GetTimestamp(DateTime.Now); return(new Dictionary <string, string> { { "loginName", this.LoginName }, { "sign", CalcSign(this.LoginName, this.Password, timestamp, data) }, { "timestamp", timestamp.ToString() } }); }
public static TResponse SignPost <TResponse>( string host, int port, string controller, string action, ISignableData data, int?timeountMilliseconds = null) { return(Post <TResponse>(host, port, controller, action, query: RpcUser.GetSignData(data), data, timeountMilliseconds)); }
/// <summary> /// /// </summary> /// <typeparam name="TResponse"></typeparam> /// <param name="host">用于组装Url</param> /// <param name="port">用于组装Url</param> /// <param name="controller">用于组装Url</param> /// <param name="action">用于组装Url</param> /// <param name="signData">用于组装url查询字符串</param> /// <param name="data">post的数据</param> /// <param name="callback"></param> /// <param name="timeountMilliseconds"></param> public static void SignPostAsync <TResponse>( string host, int port, string controller, string action, ISignableData data, Action <TResponse, Exception> callback, int timeountMilliseconds = 0) { PostAsync(host, port, controller, action, query: RpcUser.GetSignData(data), data, callback, timeountMilliseconds); }
protected bool IsValidAdmin <TResponse>(ISignableData data, out TResponse response, out UserData user) where TResponse : ResponseBase, new() { user = null; if (!WebApiRoot.UserSet.IsReadied) { string message = "服务器用户集启动中,请稍后"; response = ResponseBase.NotExist <TResponse>(message); return(false); } ClientSignData query = ClientSign; if (!Timestamp.IsInTime(query.Timestamp)) { response = ResponseBase.Expired <TResponse>(); return(false); } if (!string.IsNullOrEmpty(query.LoginName)) { user = WebApiRoot.UserSet.GetUser(query.UserId); } if (user == null && !string.IsNullOrEmpty(query.LoginName)) { user = WebApiRoot.UserSet.GetUser(query.UserId); } if (user == null) { string message = "用户不存在"; response = ResponseBase.NotExist <TResponse>(message); return(false); } else if (!user.IsAdmin()) { string message = "对不起,您不是超管"; response = ResponseBase.NotExist <TResponse>(message); return(false); } string mySign = RpcUser.CalcSign(user.LoginName, user.Password, query.Timestamp, data); if (query.Sign != mySign) { string message = "登录名或密码错误"; response = ResponseBase.Forbidden <TResponse>(message); Write.DevDebug(() => $"{message} sign:{query.Sign} mySign:{mySign}"); return(false); } response = null; return(true); }
private static bool IsValidUser( ClientSignData clientSign, ISignableData data, bool isLoginAction, out ResponseBase response, out UserData user) { user = null; if (!AppRoot.UserSet.IsReadied) { string message = "服务器用户集启动中,请稍后"; response = ResponseBase.NotExist(message); return(false); } if (!Timestamp.IsInTime(clientSign.Timestamp)) { response = ResponseBase.Expired(); return(false); } if (!string.IsNullOrEmpty(clientSign.LoginName)) { user = AppRoot.UserSet.GetUser(clientSign.UserId); } if (user == null) { string message = "用户不存在"; response = ResponseBase.NotExist(message); return(false); } if (isLoginAction) { if (!AppRoot.UserSet.CheckLoginTimes(clientSign.LoginName)) { response = ResponseBase.Forbidden("对不起,您的尝试太过频繁"); return(false); } } string mySign = HashUtil.CalcSign(user.LoginName, user.Password, clientSign.Timestamp, data); if (clientSign.Sign != mySign) { string message = "签名错误:1. 可能因为登录名或密码错误;2. 可能因为软件版本过期需要升级软件。"; response = ResponseBase.Forbidden(message); return(false); } response = null; return(true); }
protected bool IsValidUser <TResponse>(ISignableData data, out TResponse response, out UserData user) where TResponse : ResponseBase, new() { user = null; if (!WebApiRoot.UserSet.IsReadied) { string message = "服务器用户集启动中,请稍后"; response = ResponseBase.NotExist <TResponse>(message); return(false); } ClientSignData query = ClientSign; if (!Timestamp.IsInTime(query.Timestamp)) { response = ResponseBase.Expired <TResponse>(); return(false); } // 对于User来说LoginName可以是LoginName、Email、Mobile if (!string.IsNullOrEmpty(query.LoginName)) { user = WebApiRoot.UserSet.GetUser(UserId.Create(query.LoginName)); } if (user == null) { string message = "用户不存在"; response = ResponseBase.NotExist <TResponse>(message); return(false); } if (user.IsAdmin()) { response = null; return(true); } string mySign = RpcUser.CalcSign(user.LoginName, user.Password, query.Timestamp, data); if (query.Sign != mySign) { string message = "签名错误:1. 可能因为登录名或密码错误;2. 可能因为软件版本过期需要升级软件,请将软件升级到最新版本再试。"; response = ResponseBase.Forbidden <TResponse>(message); return(false); } response = null; return(true); }
public override void OnActionExecuting(HttpActionContext actionContext) { base.OnActionExecuting(actionContext); var queryString = new NameValueCollection(); string query = actionContext.Request.RequestUri.Query; if (!string.IsNullOrEmpty(query)) { query = query.Substring(1); string[] parts = query.Split('&'); foreach (var item in parts) { string[] pair = item.Split('='); if (pair.Length == 2) { queryString.Add(pair[0], pair[1]); } } } long timestamp = 0; string t = queryString["timestamp"]; if (!string.IsNullOrEmpty(t)) { long.TryParse(t, out timestamp); } string loginName = queryString["loginName"]; if (!string.IsNullOrEmpty(loginName)) { loginName = HttpUtility.UrlDecode(loginName); } ClientSignData clientSign = new ClientSignData(loginName, queryString["sign"], timestamp); ISignableData data = null; var actionDescripter = actionContext.ActionDescriptor; var actionParameters = actionDescripter.GetParameters(); bool isLoginAction = actionDescripter.ActionName == nameof(UserController.Login) && actionDescripter.ControllerDescriptor.ControllerName == RpcRoot.GetControllerName <UserController>(); if (actionParameters.Count == 1 && typeof(ISignableData).IsAssignableFrom(actionParameters[0].ParameterType)) { data = (ISignableData)actionContext.ActionArguments.First().Value; } string message = null; bool isValid = IsValidUser(clientSign, data, isLoginAction, out ResponseBase response, out UserData user); if (isValid) { isValid = OnAuthorization(user, out message); } if (!isValid) { if (response != null && !string.IsNullOrEmpty(message)) { response.Description = message; } Type returnType = actionContext.ActionDescriptor.ReturnType; var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK); if (returnType == typeof(HttpResponseMessage)) { httpResponseMessage.Content = new ByteArrayContent(VirtualRoot.BinarySerializer.Serialize(response)); httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg"); } else { httpResponseMessage.Content = new StringContent(VirtualRoot.JsonSerializer.Serialize(response), Encoding.UTF8, "application/json"); } actionContext.Response = httpResponseMessage; } else { actionContext.ControllerContext.RouteData.Values["_user"] = user; } }
protected bool IsValidAdmin <TResponse>(ISignableData data, out TResponse response) where TResponse : ResponseBase, new() { return(IsValidAdmin(data, out response, out _)); }
public static string CalcSign(string loginName, string passwordSha1, long timestamp, ISignableData data = null) { StringBuilder sb; if (data == null) { sb = new StringBuilder(); } else { sb = data.GetSignData(); } sb.Append("LoginName").Append(loginName).Append("Password").Append(passwordSha1).Append("Timestamp").Append(timestamp); return(HashUtil.Sha1(sb.ToString())); }
public static Dictionary <string, string> GetSignData(string loginName, string passwordSha1, ISignableData data = null) { var timestamp = Timestamp.GetTimestamp(DateTime.Now); return(new Dictionary <string, string> { { "loginName", loginName }, { "sign", CalcSign(loginName, passwordSha1, timestamp, data) }, { "timestamp", timestamp.ToString() } }); }