在web api中进行身份验证,而不仅仅是普通的Web应用程序

时间:2013-04-10 19:34:20

标签: c# asp.net asp.net-mvc asp.net-web-api

我创建了两个非常简单的方法:

[Authorize]
[HttpGet]
public string getUser()
{
   return User.Identity.Name;
}

[HttpPost]
public bool SignIn(Credentials cred)
{
   var user = userRepository.ValidateUser(cred);
   if (user != null)
   {
      if (user.IsActive)
      {
         FormsAuthentication.SetAuthCookie(userRepository.GetUserIdByEmail(cred.Email).ToString(), cred.RememberMe);
         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
         user.UserId.ToString(),
         DateTime.UtcNow,
                  DateTime.UtcNow.AddDays(Convert.ToInt32(ConfigurationManager.AppSettings["CookieTimeoutInDays"])),
         true,
         "MyTicket",
         FormsAuthentication.FormsCookiePath);

         //Encrypt the ticket.
         string encTicket = FormsAuthentication.Encrypt(ticket);

         //Create the cookie.
         HttpCookie mycookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);

         // Set the cookie's expiration time to the tickets expiration time
         if (ticket.IsPersistent)
            mycookie.Expires = ticket.Expiration;

         Response.AddHeader(FormsAuthentication.FormsCookieName, encTicket);
         return true;
       }
       else
       return false;
     }
     else
     {
        return false;
     }
  }

我将这些函数放在API控制器和普通控制器中(当它在api控制器中时,唯一不同的行是HttpContext.Current.Response.AddHeader(FormsAuthentication.FormsCookieName, encTicket);)。当我使用普通控制器进行身份验证并将相同的cookie传回调用getUser()时,它可以工作,但是当我对API控制器执行它时它不起作用。我正在使用移动设备来调用这两个控制器,不是浏览器。现在我理解API控制器通常通过在每个调用的头文件中传入用户名和密码来使用基本身份验证,但是从普通控制器执行它有什么问题吗?使用asp.net Web API比普通控制器有什么好处?

1 个答案:

答案 0 :(得分:0)

  
    

当我使用普通控制器进行身份验证并将相同的cookie传递回调用getUser()时,它可以工作,但是当我对API控制器执行它时它不起作用

  

我不确定为什么会这样。如果您使用的是普通模板,请注意您的ApiController将位于/ api路径下,并注意该操作名称不会是URL的一部分。如果您的WebApiConfig说:

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

并且您的控制器类名为FooController,那么您的ApiController URL将类似于: HTTP://:33504 / API /富

(对于GET和POST)。

将Cookie与Web API一起使用通常不是最好的方法,但如果您有特殊需要,可以使用它。

还有其他几个地方可能会被绊倒:

  1. 您正在生成两次表单身份验证Cookie。 SetAuthCookie行正在执行一次,并将其放在cookie头中。然后,Response.AddHeader再次执行此操作,将其放在自定义标头(不是cookie标头)中。

  2. 当你说Response.AddHeader(FormsCookieName)时,我认为你的意思是:Response.SetCookie(myCookie)。您当前的代码是添加名为FormsCookieName的自定义标头;它没有使用该cookie名称添加cookie(在Set-Cookie标头中)。

  3. 使用Web API时,通常不建议使用HttpContext.Current.Response。相反,请考虑返回HttpResponseMessage并在该对象上设置标题属性。

  4.   
        

    现在我理解API控制器通常通过在每次调用的头文件中传入用户名和密码来使用基本身份验证,但是从普通控制器执行它有什么问题吗?

      

    当您使用Web API时,您通常会使用REST并且cookie与那里的超媒体创意不太匹配。如果你没有做超媒体/ REST,那么我想你可以使用cookies,但它通常不是最合适的。

      
        

    使用asp.net Web API比使用普通控制器有什么好处?

      

    Web API为您提供了自我主持人的故事以及进行内容协商和良好的HTTP编程模型的能力。 MVC更专门针对HTML而设计(不是其他内容类型)。如果你要返回HTML,MVC可能有意义。如果您的应用中没有任何内容返回HTML,那么Web API可能更适合。

    对于这个控制器,我会在你的应用程序的其余部分做任何事情。 (我不会为这一个控制器选择不同的框架。)