在我的MVC应用程序中,我使用HMAC身份验证滤波器向Web API服务发出调用。我的Get(GetMultipleItemsRequest)有效,但我的Post没有。如果我关闭HMAC认证过滤,所有这些过滤器都可以工作。我不确定为什么POSTS不起作用,但GETs可以。
我做的GET电话从我这样的代码(这一个工程):
var productsClient = new RestClient(System.Configuration.ConfigurationManager.AppSettings["WebApiUrl"],
"xxxxxxxxxxxxxxx", true);
var getManyResult = productsClient.GetMultipleItemsRequest("api/Role").Result;
我做出POST调用从我这样的代码(这个只有当我关掉HMAC作品):
private RestClient profileClient = new RestClient(System.Configuration.ConfigurationManager.AppSettings["WebApiUrl"],
"xxxxxxxxxxxxxxx", true);
[HttpPost]
public ActionResult ProfileImport(IEnumerable files)
//...
var postResult = profileClient.PostRequest("api/Profile", newProfile).Result;
我RESTClient实现建立这样的:
public class RestClient where T : class
//...
private void SetupClient(HttpClient client, string methodName, string apiUrl, T content = null)
const string secretTokenName = "SecretToken";
client.BaseAddress = new Uri(_baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (_hmacSecret)
client.DefaultRequestHeaders.Date = DateTime.UtcNow;
var datePart = client.DefaultRequestHeaders.Date.Value.UtcDateTime.ToString(CultureInfo.InvariantCulture);
var fullUri = _baseAddress + apiUrl;
var contentMD5 = "";
if (content != null)
var json = new JavaScriptSerializer().Serialize(content);
contentMD5 = Hashing.GetHashMD5OfString(json); //
var messageRepresentation =
methodName + "\n" +
contentMD5 + "\n" +
datePart + "\n" +
fullUri;
var sharedSecretValue = ConfigurationManager.AppSettings[_sharedSecretName];
var hmac = Hashing.GetHashHMACSHA256OfString(messageRepresentation, sharedSecretValue);
client.DefaultRequestHeaders.Add(secretTokenName, hmac);
else if (!string.IsNullOrWhiteSpace(_sharedSecretName))
var sharedSecretValue = ConfigurationManager.AppSettings[_sharedSecretName];
client.DefaultRequestHeaders.Add(secretTokenName, sharedSecretValue);
public async Task GetMultipleItemsRequest(string apiUrl)
T[] result = null;
using (var client = new HttpClient())
SetupClient(client, "GET", apiUrl);
var response = await client.GetAsync(apiUrl).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
await response.Content.ReadAsStringAsync().ContinueWith((Task x) =>
if (x.IsFaulted)
throw x.Exception;
result = JsonConvert.DeserializeObject(x.Result);
catch (HttpRequestException exception)
if (exception.Message.Contains("401 (Unauthorized)"))
else if (exception.Message.Contains("403 (Forbidden)"))
catch (Exception)
return result;
public async Task PostRequest(string apiUrl, T postObject)
T result = null;
using (var client = new HttpClient())
SetupClient(client, "POST", apiUrl, postObject);
var response = await client.PostAsync(apiUrl, postObject, new JsonMediaTypeFormatter()).ConfigureAwait(false); //
response.EnsureSuccessStatusCode();
await response.Content.ReadAsStringAsync().ContinueWith((Task x) =>
if (x.IsFaulted)
throw x.Exception;
result = JsonConvert.DeserializeObject(x.Result);
catch (HttpRequestException exception)
if (exception.Message.Contains("401 (Unauthorized)"))
else if (exception.Message.Contains("403 (Forbidden)"))
catch (Exception)
return result;
//...
我的Web API控制器的定义是这样的:
[SecretAuthenticationFilter(SharedSecretName = "xxxxxxxxxxxxxxx", HmacSecret = true)]
public class ProfileController : ApiController
[HttpPost]
[ResponseType(typeof(Profile))]
public IHttpActionResult PostProfile(Profile Profile)
if (!ModelState.IsValid)
return BadRequest(ModelState);
GuidValue = Guid.NewGuid();
Resource res = new Resource();
res.ResourceId = GuidValue;
var data23 = Resourceservices.Insert(res);
Profile.ProfileId = data23.ResourceId;
_profileservices.Insert(Profile);
return CreatedAtRoute("DefaultApi", new { id = Profile.ProfileId }, Profile);
这里是一些什么SecretAuthenticationFilter做:
//now try to read the content as string
string content = actionContext.Request.Content.ReadAsStringAsync().Result;
var contentMD5 = content == "" ? "" : Hashing.GetHashMD5OfString(content); //
var datePart = "";
var requestDate = DateTime.Now.AddDays(-2);
if (actionContext.Request.Headers.Date != null)
requestDate = actionContext.Request.Headers.Date.Value.UtcDateTime;
datePart = requestDate.ToString(CultureInfo.InvariantCulture);
var methodName = actionContext.Request.Method.Method;
var fullUri = actionContext.Request.RequestUri.ToString();
var messageRepresentation =
methodName + "\n" +
contentMD5 + "\n" +
datePart + "\n" +
fullUri;
var expectedValue = Hashing.GetHashHMACSHA256OfString(messageRepresentation, sharedSecretValue);
// Are the hmacs the same, and have we received it within +/- 5 mins (sending and
// receiving servers may not have exactly the same time)
if (messageSecretValue == expectedValue
&& requestDate > DateTime.UtcNow.AddMinutes(-5)
&& requestDate < DateTime.UtcNow.AddMinutes(5))
goodRequest = true;
任何想法,为什么HMAC不为岗位工作?
当SecretAuthenticationFilter尝试比较发送的HMAC与它认为HMAC应该是他们不匹配。原因是内容的MD5Hash与接收内容的MD5Hash不匹配。 RestClient使用JavaScriptSerializer.Serialized内容版本对内容进行散列处理,但是PostRequest将对象作为JsonMediaTypeFormatted传递。
这两种类型的格式不一样。例如,JavaScriptSerializer给在美国的历史可以是这样的: \ “EnteredDate \”:\ “\ /日期(1434642998639)\/\”
所传递的内容有日期如下: \ “EnteredDate \”:\ “2015-06-18T11:56:38.6390407-04:00 \”
我想我需要哈希使用传递的相同数据,因此另一端的过滤器可以正确地确认它。思考?
编辑: 找到答案,我需要使用此线改变SetupClient代码:
var json = new JavaScriptSerializer().Serialize(content);
contentMD5 = Hashing.GetHashMD5OfString(json);
要使用这样的:
var json = JsonConvert.SerializeObject(content);
contentMD5 = Hashing.GetHashMD5OfString(json);
现在发送的内容(通过JSON格式)将匹配散列的内容。
我原来并不是这位代码的人。:)
检查WebDav模块是否已安装。如果是,请卸载并重试。 –
在我的MVC应用程序中,我使用HMAC身份验证滤波器向Web API服务发出调用。我的Get(GetMultipleItemsRequest)有效,但我的Post没有。如果我关闭HMAC认证过滤,所有这些过滤器都可以工作。我不确定为什么POSTS不起作用,但GETs可以。我做的GET电话从我这样的代码(这一个工程):var productsClient = new RestClient(Syste...
前言:上篇
C#
进阶系列——
Web
Api
接口传参不再困惑:传参详解介绍了
Web
Api
参数的传递,这篇来看看
Web
Api
里面异常的处理。关于异常处理,作为程序员的我们肯定不陌生,记得在介绍 AOP 的时候,我们讲过通过AOP可以统一截获异常。那么在我们的
Web
Api
里面一般是怎么处理异常的呢,今天这一篇,博主带着大家一起来实践下
Web
Api
的异常处理。
Web
Api
系列文章
C#
进阶系列——W...
无法在
web
服务器上启用调试,远程服务器
返回
错误:(
403
)已禁止
情况说明:从别人那拷贝了一份程序,该程序是从TFS上拉下来的,我在本地生成和部署后都没问题,但当我调试的时候碰到如题问题,现场车祸如下图:
在经过百度一系列乱七八糟的指引后,我的问题最终没有得到解决,但头脑里总算有了一点想法,于是将目标放在了程序的sln文件上。
我做的项目是ASP.NET MVC相关的,打开sln文件后大致内容...
使用Http
web
request采集百度图片,经常会出现
403
for
bidden
采用以下解决办法:
1:增加refer,写https://www.baidu.com 就行了
2:在获得列表时,将cookie保存,
static CookieContainer cookie = new CookieContainer();
http
Web
Request.CookieCont
在一次爬虫下载图片的过程中,遇到服务器
返回
403
,然后寻找解决办法,解决办法如下:
1.一般造成
403
的原因是权限设置问题,也就是没有权限造成的,因此这里直接添加信任权限即可:
web
client.Credentials = CredentialCache.DefaultCredentials; // 添加授权证书
2.分析Reques tHeaders
可以看到在requet中,有...
2.
C#
Web
Api
404及Post取不到参数
原文地址:https://blog.csdn.net/PLA12147111/article/details/89666797
如果是HttpPost,一定记得参数要写[FromBody],否则就是404