保护返回JSON的ASP.NET MVC控制器操作

Bil*_*lga 8 asp.net authentication json asp.net-mvc-3

我有一个MVC3应用程序,我的控制器操作使用[Authorize]属性进行保护.到目前为止,这么好,表格auth工作得很好.现在我想向我的应用程序添加一个JSON API,以便非浏览器客户端可以访问某些操作.

我无法搞清楚'正确'的设计.

1)每个用户都有秘密的API密钥.

2)用户ID 5调用http://myapp.com/foocontroller/baraction/5?param1=value1m2=value2&secure_hash=someValue.这里,secure_hash只是param1的SHA1哈希值,而param2的值附加了用户的秘密API密钥

2)/ foocontroller/baraction将使用[CustomAuthorize]进行修饰.这将是AuthorizeAttribute的一个实现,它将检查请求是否以JSON形式进入.如果是,它将检查散列并查看它是否匹配.否则,如果请求是HTML,那么我调用现有授权.

我不确定这是否有效.在查询字符串中传递安全哈希是否正常,或者我应该将其作为HTTP头传递?使用HTTP基本身份验证而不是使用秘密API密钥创建的哈希是否更好?

任何使用ASP.NET MVC制作Web API的人都会受到欢迎!

Jas*_*tts 11

我在请求正文中传递了秘密API密钥以及用户名和密码.授权后,将生成令牌,客户端必须在Authorization标头中传递该令牌.这将在每个请求的基本控制器中进行检查.

  1. 客户端调用myapp.com/authorize,返回auth令牌.
  2. 客户端在本地存储身份验证令牌
  3. 客户端使用Authorization标头中的authtoken调用myapp.com/anycontroller.

AuthorizeController继承自控制器.Anycontroller继承自执行授权代码的自定义基本控制器.

我的示例需要以下路由,将POST请求定向到任何控制器中名为post的ActionResult.我正在手动输入这个,以尽可能地简化它,为您提供一般的想法.不要指望剪切和粘贴,让它工作:)

routes.MapRoute(
    "post-object",
    "{controller}",
    new { controller = "Home", action = "post" {,
    new { httpMethod = new HttpMethodConstraint("POST")}
);
Run Code Online (Sandbox Code Playgroud)

您的auth控制器可以使用它

public class AuthorizationController : Controller
{
    public ActionResult Post()
    {
        string authBody;
        var request = ControllerContext.HttpContext.Request;
        var response = ControllerContext.HttpContext.Response;

        using(var reader = new StreamReader(request.InputStream))
            authBody = reader.ReadToEnd();

        // authorize based on credentials passed in request body
        var authToken = {result of your auth method}

        response.Write(authToken);

    }
}
Run Code Online (Sandbox Code Playgroud)

您的其他控制器继承自基本控制器

public class BaseController : Controller
{
    protected override void Execute(RequestContext requestContext)
    {
        var request = requestContext.HttpContext.Request;
        var response = requestContext.HttpContext.Response;

        var authToken = Request.Headers["Authorization"];

        // use token to authorize in your own method
        var authorized = AmIAuthorized();

        if(authorized = false) { 
            response.StatusCode = 401; 
            response.Write("Invalid token");
            return;            
        }

        response.StatusCode = 200; // OK

        base.Execute(requestContext);  // allow inheriting controller to continue

    }
}
Run Code Online (Sandbox Code Playgroud)

调用api的示例代码

 public static void ExecutePostRequest(string contentType)
        {
            request = (HttpWebRequest)WebRequest.Create(Uri + Querystring);
            request.Method = "POST";
            request.ContentType = contentType;  // application/json usually
            request.Headers["Authorization"] = token;

            using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                writer.Write(postRequestData);

            // GetResponse reaises an exception on http status code 400
            // We can pull response out of the exception and continue on our way            
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }
            finally
            {
                using (StreamReader reader =
                    new StreamReader(response.GetResponseStream()))
                    responseText = reader.ReadToEnd();
                httpcontext = HttpContext.Current;
            }
        }
Run Code Online (Sandbox Code Playgroud)