Asp.net

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

  • July 4, 2012

我有一個 MVC3 應用程序,並且我的控制器操作使用

$$ Authorize $$屬性。到目前為止,一切都很好,表單身份驗證效果很好。現在我想向我的應用程序添加一個 JSON API,以便非瀏覽器客戶端可以訪問一些操作。 我很難找出“正確”的設計。

  1. 每個使用者都有秘密的 API 密鑰。

  2. 使用者 ID 5 呼叫http://myapp.com/foocontroller/baraction/5?param1=value1¶m2=value2&secure_hash=someValue。在這裡,secure_hash 只是 param1 和 param2 的值的 SHA1 雜湊,附加了使用者的 API 密鑰

  3. /foocontroller/baraction 將被裝飾

$$ CustomAuthorize $$. 這將是 AuthorizeAttribute 的一個實現,它將檢查請求是否以 JSON 形式傳入。如果是,它將檢查雜湊並查看是否匹配。否則,如果請求是 HTML,那麼我呼叫現有授權。 我完全不確定這是否可行。在查詢字元串中傳遞安全雜湊是否正常,還是應該將其作為 HTTP 標頭傳遞?使用 HTTP 基本身份驗證而不是使用 API 密鑰生成的雜湊會更好嗎?

歡迎任何使用 ASP.NET MVC 製作 Web API 的人提供提示!

我在請求正文中傳遞秘密 API 密鑰以及使用者名和密碼。一旦獲得授權,就會生成一個令牌,客戶端必須在 Authorization 標頭中傳遞它。這會在每次請求時在基本控制器中進行檢查。

  1. 客戶端呼叫返回身份驗證令牌的 myapp.com/authorize。
  2. 客戶端在本地儲存身份驗證令牌。
  3. 客戶端呼叫 myapp.com/anycontroller,並在 Authorization 標頭中使用 authtoken。

AuthorizeController 繼承自控制器。Anycontroller 繼承自執行授權程式碼的自定義基本控制器。

我的範例需要以下路由,它將 POST 請求定向到任何控制器中名為 post 的 ActionResult。我是手動輸入的,以盡可能簡化它,以便為您提供總體構想。不要指望剪切和粘貼並讓它工作:)

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

您的身份驗證控制器可以使用它

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

   }
}

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

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

   }
}

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

引用自:https://stackoverflow.com/questions/5851900