我正在使用.NET MVC 4.5开发API。我希望最终用户能够发送类似(PowerShell)的请求:
$webclient = new-object System.Net.WebClient
$webclient.Credentials = new-object System.Net.NetworkCredential($username,
$securePassword)
$doc = $webclient.DownloadString("http://localhost:60023/api/getData?id=200")
但我不知道如何从我的申请中的请求中提取凭证。
我的控制器如下:
namespace App.Controllers
{
public IEnumerable<MyStruct> Get(int id)
{
// TODO: get credentials from request
// validate credentials
// code to create IEnumerable<MyStruct>
return DataList;
}
}
到目前为止,如果我对凭据进行硬编码,一切正常,我需要弄清楚的是如何从最终用户$webclient.Credentials
获取凭据。
我确定之前已经讨论过,但我一直在搜索几个小时但找不到答案。
我离开了吗?
这不是验证API请求的好方法吗?我知道有一个[Authorize]属性可以使用内置的身份验证系统,但我的应用程序使用自定义登录验证,因此我认为这不会起作用。是否有理由以我想要的方式验证Controller方法中的凭证是个坏主意?
答案 0 :(得分:3)
通常MVC
不用于API工作。虽然MVC
可以处理服务API调用,但Microsoft有一个名为MVC
的{{1}}类产品更适合提供API,例如返回JSON或XML而不是视图。
在WebApi
和MVC
中,不建议在方法中处理身份验证和授权。虽然它有效,但它会让您忘记保护API调用。因此,Microsoft制定了WebApi
和AuthenticationFilter
属性。这些允许您通过Method,Class或Application标记要保护的API或视图。
要从AuthorizationFilter
中的请求访问基本凭据,您将访问Authorization标头。这将是MVC
。
以下代码显示了如何阅读凭据的粗略示例:
Basic [Base64Encoded, colon delimited strings]
最好将此代码插入public ActionResult TestView()
{
bool isAuthenticated;
var base64Header = Request.Headers["Authorization"];
//The header is a string in the form of "Basic [base64 encoded username:password]"
if (base64Header != null)
{
var authHeader = AuthenticationHeaderValue.Parse(base64Header);
if (authHeader != null
&& authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase)
&& authHeader.Parameter != null)
{
//Decode the username:password pair
var credentialPair = Encoding.ASCII.GetString(Convert.FromBase64string(authHeader.Parameter));
//Split into pieces
var credentials = credentialPair.Split(new [] {":"}, StringSplitOptions.None);
var userName = credentials[0];
var plainTextPassword = credentials[1];
isAuthenticated = SomeAuthenticator.Authenticate(userName, password);
}
}
if (isAuthenticated)
return Foo();
else
RedirectResult("your login view");
}
。这使您能够通过方法,类或应用程序打开/关闭授权。
AuthenticationFilter
然后被
消耗public class CustomAuthFilter : IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
var header = filterContext.RequestContext.HttpContext.Request.Headers["Authorization"];
if (!Authenticate(header))
filterContext.Result = new HttpUnauthorizedResult();
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
filterContext.Result = new RedirectResult(@"https:\\foo\YourLoginPage");
}
private bool Authenticate(string rawAuthorizationHeader)
{
try
{
if (rawAuthorizationHeader != null)
{
var authHeader = AuthenticationHeaderValue.Parse(rawAuthorizationHeader);
if (authHeader != null
&& authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase)
&& authHeader.Parameter != null)
{
var credentialPair = Encoding.ASCII.GetString(Convert.FromBase64String(authHeader.Parameter));
var credentials = credentialPair.Split(new[] { ":" }, StringSplitOptions.None);
var userName = credentials[0];
var plainTextPassword = credentials[1];
return SomeAuthenticator.Authenticate(userName, plainTextPassword);
}
}
return false;
}
catch (Exception)
{
return false;
}
}
}
请注意,在典型的Microsoft方式中,身份验证和授权是两回事。如果您希望通过超过&#34来保护API,则需要设置授权过滤器;此用户拥有帐户&#34;。