简体   繁体   中英

How to include a basic http authentication in MVC4

I am using the new oAuthWebSecurity functionality in MVC4 to do Facebook authentication for users of the site and it works great.

However, what I would like to do is that for a specific controller only, enable basic HTTP authentication.

I have tried implementing a custom action filter (authenticationFilter) to intercept the call and do the basic authentication with custom code but the code never hits the overloads of the AuthorizationFilter .

Is there an easier way to implement this rather than creating a custom SimpleMembershipProvider ?

You can use [Authorize] filter is as below.

public class BooksController : ApiController
{
    [Authorize]
    public IEnumerable<Book> Get()
    {
        var result = new List<Book>()
        {
            new Book()
            {
                Author = "John Fowles",
                Title = "The Magus",
                Description = "A major work of mounting tensions " +
                                "in which the human mind is the guinea-pig."
            },
            new Book()
            {
                Author = "Stanislaw Ulam",
                Title = "Adventures of a Mathematician",
                Description = "The autobiography of mathematician Stanislaw Ulam, " +
                                "one of the great scientific minds of the twentieth century."
            }
        };
        return result;
    }
}

For more information check Basic HTTP authentication

I hope this will help to you.

You can create custom AuthorizeAttribute to handle both authentication and authorization using basic authentication. This attribute works as a filter and will process the request before it gets to your controller action or Web API method. In the overridden OnAuthorize method you can grab the header information to perform authentication.

If you are using ajax to make request to a controller or Web API method use basic authentication to pass the credentials for authorization. This puts the credentials in the header. To do this is pretty straight forward by using the beforeSend event handler of the JQuery ajax function. Use jquery.base64.js to encode the information being sent over. Here is an example of how to do this.

    getAuthorizationHeader = function (username, password) {
      var authType;
      var up = $.base64.encode(username + ":" + password);
      authType = "Basic " + up;
    };
    return authType;
 };

    $.ajax({
        url: _url,
        data: _data,
        type: _type,
        beforeSend: function (xhr) {
            xhr.setRequestHeader("Authorization", getAuthorizationHeader(username, password));
        },
        success: ajaxSuccessHandler,
        error: ajaxErrHandler
    });

This encodes the username/password that is sent in the header. Note that this is not enough security to rely on just the encoding as it is easy to decode. You still want to use HTTPS/SSL to make sure the information sent over the wire is secure.

On the server side you can make a custom AuthorizeAttribute that gets the credentials from the header, decodes them, and performs your authentication/authorization process. Note that there is aaa separate AuthorizeAttribute used by the Web API as opposed to the controller. Be sure to use System.Web.Http.AuthorizeAttribute as your base class when creating your custom AuthorizeAttribute if you are using Web API. They have different behaviors. The one for the controller will want to redirect to the logon page whereas the one for the Web API returns an HTTP code indicating success or failure. I return an HTTP code of Forbidden if authorization fails to distinguish a failure due to authorization as opposed to authentication so the client can react accordingly.

Here is an example method for getting the credentials from the header that can be used in the custom AuthorizeAttribute .

    private bool GetUserNameAndPassword(HttpActionContext actionContext, out string username, out string password)
    {
        bool gotIt = false;
        username = string.Empty;
        password = string.Empty;
        IEnumerable<string> headerVals;
        if (actionContext.Request.Headers.TryGetValues("Authorization", out headerVals))
        {
            try
            {
                string authHeader = headerVals.FirstOrDefault();
                char[] delims = { ' ' };
                string[] authHeaderTokens = authHeader.Split(new char[] { ' ' });
                if (authHeaderTokens[0].Contains("Basic"))
                {
                    string decodedStr = SecurityHelper.DecodeFrom64(authHeaderTokens[1]);
                    string[] unpw = decodedStr.Split(new char[] { ':' });
                    username = unpw[0];
                    password = unpw[1];
                }
                gotIt = true;
            }
            catch { gotIt = false; }
        }

        return gotIt;
    }

And here is the code for decoding the header data that is used in this method.

    public static string DecodeFrom64(string encodedData)
    {

        byte[] encodedDataAsBytes

            = System.Convert.FromBase64String(encodedData);

        string returnValue =

           System.Text.Encoding.ASCII.GetString(encodedDataAsBytes);

        return returnValue;

    }

Once you have the username and password you can perform your authentication and authorization using the SimpleMembership provider.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM