我想製作一個安全的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