我想制作一个安全的asp.net web api。对于我跟随下面的链接如何为asp.net mvc 4 web api执行基于角色的授权
所以现在每个API请求需要我在例如下面
public class TestController : Controller
{
public string GetProducts()
{
Uri myUri = new Uri("http://localhost:420420/api/products");
WebRequest myWebRequest = WebRequest.Create(myUri);
myWebRequest.Method = "GET";
myWebRequest.ContentType = "application/json";
myWebRequest.Headers.Add("Authorization-Token", RSAClass.accessToken);
using (WebResponse response = myWebRequest.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return reader.ReadToEnd();
}
}
}
}
所以我现在的请求头我提供一个令牌能够做出每一个API请求,检查标题中的令牌。但我该如何完成授权,我的意思是我怎么能不让这个令牌不能访问同一个控制器中的某些动作。我只需要一个想法。希望我解释得很好。
编辑:
public class TestController : Controller
{
public string GetProducts()
{
Uri myUri = new Uri("http://localhost:420420/api/products");
WebRequest myWebRequest = WebRequest.Create(myUri);
myWebRequest.Method = "GET";
myWebRequest.ContentType = "application/json";
myWebRequest.Headers.Add("Authorization-Token", RSAClass.accessToken);
**using (WebResponse response = myWebRequest.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return reader.ReadToEnd();
}
}**
}
我正在向 “API” 控制器的请求,上述内部控制器使用的WebRequest(I稍后将改变它的HttpClient)。在这两者之间**上面我收到404页未找到myWebRequest.GetResponse()
下面是我的API控制器
public class ProductsController : ApiController
{
TestModelContainer testModel = new TestModelContainer();
[Authorize(Roles="Users")]
public IEnumerable<Products> GetProducts()
{
IEnumerable<Products> products = (from prods in testModel.Products
select prods);
return products;
}
}
}
现在在委托处理我有代码以下代码
public class TokenValidationHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
TestModelContainer testModel = new TestModelContainer();
var token = "";
try
{
if (request.Headers.Contains("Authorization-Token"))
{
token = request.Headers.GetValues("Authorization-Token").FirstOrDefault();
if (String.IsNullOrEmpty(token))
{
return Task<HttpResponseMessage>.Factory.StartNew(() =>
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("Missing Authorization-Token")
};
});
}
}
else
{
return Task<HttpResponseMessage>.Factory.StartNew(() =>
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("You need to include Authorization-Token " +
"header in your request")
};
});
}
var decryptedToken = RSAClass.Decrypt(token);
var foundUser = (from user in testModel.Users
where user.Name == decryptedToken
select user).Any();
if (!foundUser)
return Task<HttpResponseMessage>.Factory.StartNew(() =>
{
return new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("Unauthorized User")
};
});
var identity = new GenericIdentity(decryptedToken);
string[] roles = new string[] { "Users", "Testers" };
var principal = new GenericPrincipal(identity, roles);
Thread.CurrentPrincipal = principal;
}
catch (Exception ex)
{
return Task<HttpResponseMessage>.Factory.StartNew(() =>
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent("Error encountered while attempting to process authorization token")
};
});
}
return base.SendAsync(request, cancellationToken);
}
如果我从api控制器中删除授权属性,然后我能够访问它,404错误不会增加。
更新(我相信解决方案太):
这是问题是怎么通过达林季米特洛夫
public class TestsController : Controller
{
public ActionResult GetProducts()
{
var productsUrl = Url.RouteUrl("DefaultApi", new { httproute = "", controller = "products" }, "http");
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization-Token", RSAClass.accessToken);
var products = client
.GetAsync(productsUrl)
.Result;
if (products.StatusCode == HttpStatusCode.Unauthorized)
{
return Content("Sorry you are not authorized to perform this operation");
}
var prods = products.Content
.ReadAsAsync<IEnumerable<Products>>()
.Result;
return Json(prods, JsonRequestBehavior.AllowGet);
}
}
解决
我已经改变了的TestController方法如下建议问题是我不知道如何打电话给api,感谢达林他的大力支持(他也很快)。
感谢
我已经注册了TokenValidation在global.asax.cs中,但我的问题如何使一个经过身份验证的令牌不能访问同一控制器中的其他一些操作...?我的意思是我怎么做到[授权(角色=“管理员”)与在“API控制器”将产生的令牌 – CrazyNooB 2012-08-16 12:35:58
你必须写一个不同的'TokenValidationHandler'。本文中介绍的仅在令牌内存储用户名,根本没有角色。您可以在结帐我出一个自定义的委托处理程序使用基本身份验证方案,并依靠内置的成员资格和角色提供以下答案:http://stackoverflow.com/a/11536349/29407 – 2012-08-16 12:37:45
没错,这就是我问。你能给出一小段代码如何使用令牌进行基于角色的授权..? – CrazyNooB 2012-08-16 12:40:59