【发布时间】:2016-02-06 15:29:30
【问题描述】:
我有一个 web api 服务,我希望另一个 .Net 应用程序向它发出 web 请求,但是这样做时出现以下错误:
“远程服务器返回错误:(401) Unauthorized.”
澄清一下,这是 2 个独立的 .net 应用程序,它们试图进行通信。
这是客户端 .Net c# 应用程序尝试向其他 Web api 服务发出 Web 请求的代码:
public string MakeWebRequest()
{
var requestUrl = "http://localhost:8081/api/Tests/results";
var request = WebRequest.Create(requestUrl);
var username = "test";
var password = "test";
SetBasicAuthHeader(request, username, password);
var postData = "thing1=hello";
postData += "&thing2=world";
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = data.Length;
//request.Expect = "application/json";
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
string text;
var response = (HttpWebResponse)request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return null;
}
public static void SetBasicAuthHeader(WebRequest request, String userName, String userPassword)
{
string authInfo = userName + ":" + userPassword;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
request.Headers["Authorization"] = "Basic " + authInfo;
}
这是 .Net c# web api 服务的代码,它应该接收来自其他应用的 web 请求:
[RoutePrefix("api/Tests")]
public class TestsApiController : ApiController
{
[POST("results")]
[AcceptVerbs("POST")]
[HttpPost]
[BasicAuthAuthorize(Roles="Admin")]
public JObject resultsFinished()
{
//do something
}
}
这是我创建的基本身份验证属性,它甚至不会受到客户端服务的影响。
public class BasicAuthAuthorizeAttribute : AuthorizeAttribute
{
private const string BasicAuthResponseHeader = "WWW-Authenticate";
private const string BasicAuthResponseHeaderValue = "Basic";
public override void OnAuthorization(HttpActionContext actionContext)
{
try
{
AuthenticationHeaderValue authValue = actionContext.Request.Headers.Authorization;
if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter) && authValue.Scheme == BasicAuthResponseHeaderValue)
{
var parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
if (parsedCredentials != null)
{
if (parsedCredentials.Username == IoC.Username && parsedCredentials.Password == IoC.Password)
return;
}
}
}
catch (Exception)
{
//actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
return;
}
}
private Credentials ParseAuthorizationHeader(string authHeader)
{
string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(authHeader)).Split(new[] { ':' });
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[1]))
return null;
return new Credentials() { Username = credentials[0], Password = credentials[1], };
}
}
//Client credential
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
【问题讨论】:
-
是我还是你发送通过 HTTP 的原始纯文本密码?
-
抱歉,忘记包含更多编码密码的代码。注意上面的编辑。谢谢!
-
可以在 Web 服务中运行“HelloWorld”或“Test”方法吗?运行服务的应用程序池的 ID 可能有问题。
-
@Duston 抱歉,忘了说这是两个独立的应用程序。
标签: c# asp.net-web-api