ASP.net Web API RESTful web service + Basic authen

2019-01-16 16:25发布

I'm implementing a RESTful web service using ASP.Net Web Api. I have concluded to use Basic authentication + SSL to do the authentication part. What is the best/correct way to implement that?

My first attempt was to do it manually, parsing the Authorization header, decoding and verifying the user against my database. It works, but I wonder if I am missing something.

I've seen some solutions using user roles and principals. While I'm not sure what these actually do, I'm almost sure I will not be needing these, since in my database I define my own users and their roles.

Also what I haven't yet completely understand, is if the consumers of the service must sent the credentials with each request or they are somehow cached. Should my service do something in order for this to happen, or it's completely up to the consumer to handle this?

And a last question about clients making requests with javascript. Would there be any "cross domain request" problems if they try to use the service?

3条回答
淡お忘
2楼-- · 2019-01-16 16:36

Use basic authentication for the initial (sign in) request by adding a [BasicHttpAuthorize] attribute to the appropriate controllers/methods. Specify the Users and Roles with the attribute if desired. Define BasicHttpAuthorizeAttribute as a specialized AuthorizeAttribute like this:

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (Thread.CurrentPrincipal.Identity.Name.Length == 0) { // If an identity has not already been established by other means:
            AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization;
            if (string.Compare(auth.Scheme, "Basic", StringComparison.OrdinalIgnoreCase) == 0) {
                string credentials = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(auth.Parameter));
                int separatorIndex = credentials.IndexOf(':');
                if (separatorIndex >= 0) {
                    string userName = credentials.Substring(0, separatorIndex);
                    string password = credentials.Substring(separatorIndex + 1);
                    if (Membership.ValidateUser(userName, password))
                        Thread.CurrentPrincipal = actionContext.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity(userName, "Basic"), System.Web.Security.Roles.Provider.GetRolesForUser(userName));
                }
            }
        }
        return base.IsAuthorized(actionContext);
    }
}

Have the initial response include an API key for the user. Use the API key for subsequent calls. That way, the client's authentication remains valid even if the user changes username or password. However, when changing password, give the user an option to "disconnect clients", which you implement by deleting the API key on the server.

查看更多
相关推荐>>
3楼-- · 2019-01-16 16:40

Jamie Kurtze provides a good explanation of using Basic Authentication here ASP.NET Web API REST Security Basics

From my understanding, if you want your requests to be stateless then each request will require the Authentication field to be set

Jamie Kurtze wraps the necessary code in a class derived from DelegateHandler, while Rick Strahl checks if the call is valid using a Filter. You can read more at his blog post on this topic at A WebAPI Basic Authentication Authorization Filter

查看更多
登录 后发表回答