Mvc Api从请求中获取凭据 [英] Mvc Api get credentials from request

查看:92
本文介绍了Mvc Api从请求中获取凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使想很简单,我也很想找到任何有关此的东西

I'm having a heck of a time finding anything on this, even though I would think it's pretty straight forward...

我正在使用.NET MVC 4.5开发API.我希望最终用户能够发送类似(PowerShell)的请求:

I'm developing an API using .NET MVC 4.5. I want the end user to be able to send a request like (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")

但是我不知道如何从我的应用程序中的请求中提取凭据.

But I don't know how to pull the Credentials from the request in my application.

我的控制器如下:

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中获取凭据.

So far, everything works if I hard-code the credentials, all I need to figure out is how to get the credentials from the end-user's $webclient.Credentials.

我确定以前已经讨论过了,但是我已经搜索了几个小时,找不到答案.

I'm sure this has been discussed before, but I've been searching for hours and can't find the answer.

我要离开吗?

这不是验证API请求的好方法吗?我知道有一个[Authorize]属性可以使用内置的身份验证系统,但是我的应用程序使用自定义登录验证,因此我认为这不起作用.是否有理由以我想要的方式验证Controller方法中的凭据是一个坏主意?

Is this not a good way to go about authenticating API requests? I know that there is an [Authorize] attribute that can use the built-in authentication system, but my app uses custom login verification, so I don't think that will work. Is there a reason verifying credentials within the Controller method in the manner that I want is a bad idea?

推荐答案

MVC通常不用于API工作.尽管MVC可以处理服务于API的调用,但Microsoft具有类似于MVC的产品称为WebApi,该产品更适合于服务API,例如返回JSON或XML而不是视图.

Typically MVC is not used for API work. While MVC can handle serving API calls, Microsoft has an MVC like product called WebApi that is more geared to serving an API, such as returning JSON or XML instead of a view.

MVCWebApi中,均不建议在方法内处理身份验证和授权.当它起作用时,它使您容易忘记保护API调用.因此,Microsoft设置了AuthenticationFilterAuthorizationFilter属性.这些使您可以按方法,类或应用程序标记要保护的API或视图.

In both MVC and WebApi, handling authentication and authorization within methods is not advised. While it works, it opens you up to forgetting to secure an API call. Therefore Microsoft made the AuthenticationFilter and AuthorizationFilter attributes. These allow you to mark which APIs or Views to secure by Method, Class, or Application.

要从MVC中的请求访问基本凭据,请访问Authorization标头.这将是Basic [Base64Encoded, colon delimited strings]形式的字符串.

To access basic credentials from a request in MVC, you would access the Authorization header. This will be a string in the form of Basic [Base64Encoded, colon delimited strings].

以下代码显示了如何读取凭据的粗略示例:

The following code shows a rough example of how to read the credentials:

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中.这使您能够按方法,类或应用程序打开/关闭授权.

It would be best to insert this code into an AuthenticationFilter however. This grants you the ability to turn authorization on/off by method, class, or application.

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;
        }
    }
}

然后被

[CustomAuthFilter] //Secure all methods in the class
public class SecureApiController
{

    public ActionResult SecuredApiCall()
    {
        return Foo();
    }

    public ActionResult AnotherSecuredCall()
    {
        return Bar();
    }

    [AllowAnonymous]
    public ActionResult UnsecuredApiCall()
    {
        return UnsecureFoo();
    }
}

请注意,以典型的Microsoft方式, Authentication Authorization 是两件事.如果您要通过此用户拥有一个帐户"以上的方式来保护API,则需要设置一个授权过滤器.

Note that in typical Microsoft fashion, Authentication and Authorization are two different things. You will need to setup an Authorization filter if you want to secure an API by more than "this user has an account".

这篇关于Mvc Api从请求中获取凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆