如何为Web API请求设置oauth令牌安全性?

时间:2013-11-28 22:39:23

标签: asp.net-mvc-4 angularjs asp.net-web-api

在以下this教程中(将其修改为使用基于应用程序的身份验证字符串而不是其用户模型),请定义以下TokenValidationAttribute并在WebAPI控制器上设置此属性以验证API请求来自我的Web应用程序:

public class TokenValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        string token;

        try
        {
            token = actionContext.Request.Headers.GetValues("Authorization-Token").First();
        }
        catch (Exception)
        {
            actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
            {
                Content = new StringContent("Missing Authorization-Token")
            };
            return;
        }

        try
        {
            var crypto = new SimpleCrypto.PBKDF2(); // type of encryption
            var authPart = ConfigurationManager.AppSettings["AuthorizationTokenPart"];
            var authSalt = GlobalVariables.AuthorizationSalt;
            var authToken = GlobalVariables.AuthorizationToken;

            if (authToken == crypto.Compute(authPart, authSalt))
            {
                // valid auth token
            }
            else
            {
                // invalid auth token
            }

            //AuthorizedUserRepository.GetUsers().First(x => x.Name == RSAClass.Decrypt(token));
            base.OnActionExecuting(actionContext);
        }
        catch (Exception ex)
        {
            actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
            {
                Content = new StringContent("Unauthorized User")
            };
            return;
        }
    }
}

在我的登录类中,我定义了以下方法,如果有效,则返回User对象:

    private User IsValid(string username, string password)
    {
        var crypto = new SimpleCrypto.PBKDF2(); // type of encryption
        using (var db = new DAL.DbContext())
        {
            var user = db.Users
                .Include("MembershipType")
                .FirstOrDefault(u => u.UserName == username);
            if (user != null && user.Password == crypto.Compute(password, user.PasswordSalt))
            {
                return user;
            }
        }

        return null;
    }

正如您所看到的,用户登录验证方法不会对~/api/User进行WebAPI调用(该部分有效)。

1)如何使用auth令牌生成请求(只有站点生成的API请求有效)?这些可能是来自代码隐藏或基于JavaScript(AngularJS)请求的直接API调用,以便对某些对象进行水合。

2)我对base.OnActionExecuting(actionContext);的内容并不完全清楚。如果令牌有效/无效,该怎么办?

2 个答案:

答案 0 :(得分:0)

我认为发送授权标头的最佳做法是将其添加到请求标头

request.Headers.Add("Authorization-Token",bla bla bla);

您可以创建webrequest或httprequest 也许你应该从http://rest.elkstein.org/2008/02/using-rest-in-c-sharp.html开始 或http://msdn.microsoft.com/en-us/library/debx8sh9%28v=vs.110%29.aspx

在我看来为了创建正确的登录安全性并请求你应该应用一个标准,比如openid或oauth

欢呼声

答案 1 :(得分:0)

我做了类似这样的事情,LoginSession包含我的令牌并且是静态的(在我的情况下是一个共享服务(不是静态的))

        public HttpClient GetClient()
    {
        var client = new HttpClient
        {
            Timeout = new TimeSpan(0, 0, 2, 0),
            BaseAddress = new Uri(GetServiceAddress())
        };
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        if (LoginSession.Token != null)
        {
            client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", String.Format("Bearer {0}", LoginSession.Token.AccessToken));
        }
        return client;
    }

注意这一行:

client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", String.Format("Bearer {0}", LoginSession.Token.AccessToken));