2014-04-09 33 views
1

我在2部分中创建应用程序。在一台服务器上是一个使用Owin的.net Webapi2。在另一台服务器上是一个MVC5网站,目前没有登录,将作为api的前端。这也是一个很好的卖点,表明应用程序本身就是客户可以开发的一个例子,因为它依赖于相同的api。我把用户认证的东西放在api中,因为我需要第三方能够使用api开发自己的前端应用程序。如何让MVC5客户端通过远程WebApi2应用登录?

我正在试图完成的(理论上) 我需要有一个用户提交前端他们的登录信息将通过resourceownergrant型验证他们的身份,并收到效果,使前端创建一个包含accesstoken和identityuser /角色的cookie。只要这个cookie存在,mvc应用程序就会使用accesstoken调用api。 MVC应用程序和API都将能够使用[授权]属性。

我有什么到目前为止 我有API起来和工作,我可以张贴“grant_type =密码&用户名= testuser的&密码= password123”我收到这样的事情在JSON

{ 
    "access_token":"-longasstokenhere-", 
    "token_type":"bearer", 
    "expires_in":1209599, 
    "userName":"testuser", 
    ".issued":"Thu, 03 Apr 2014 16:21:06 GMT", 
    ".expires":"Thu, 17 Apr 2014 16:21:06 GMT" 
} 

网络API的回应也有

set-cookie: -Long-assserializedcookiestuffhere- 

头我的问题是如何连接我的MVC应用程序。

在我mvc5应用

我有一个启动的owin这一套在configureauth

app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
       CookieName = "MyCookie", 
       LoginPath = new PathString("/Account/Login") 
      }); 

我见[授权]属性的测试页,当我参观,它正确地重定向设置上我到登录页面。我缺少的是如何做到这一点,使点击登录使网站发回api并创建一个Owin Cookie,网站将使用该cookie允许用户通过[授权] attibute。我也希望它包含identityuser,所以web应用程序将自动获得用户信息,而不必在每次调用时都回发到api。我不知道我能否以某种方式或返回的结果抓取cookie。

此外,如果他们有更好的方式,我愿意接受建议。

Heeelp!?

回答

2

我有完全相同的要求。我试图让MVC5 CookieAuthentication正常工作,但它不会让我使用我自己的cookie值。但是,您的WebAPI不应该返回一个set-cookie。 WebAPI应该是RESTful的,并且要求客户端在每个请求上传递一个不记名令牌。

所以,这是我的解决方案。用户名和密码被发送到外部API,它返回一个JSON Web令牌。来自API的令牌存储在cookie中。你可以用JavaScript或者MVC账户控制器来做到这一点。该cookie由MVC应用程序检查,如果存在,该cookie指示用户也登录到MVC应用程序的证据。

在JavaScript中,您从Cookie中取出该令牌,并将其添加到作为承载令牌的授权标头中的API的所有请求中。另外,MVC应用程序可以使用cookie(令牌)的值来访问所有用户的声明。要注销,只需过期cookie。

首先,线了该应用使用承载的道理,我们的自定义提供

// Api controllers with an [Authorize] attribute will be validated with JWT 
app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions 
    { 
     AllowedAudiences = audienceId.ToArray(), 
     IssuerSecurityTokenProviders = providers.ToArray(), 
     Provider = new CookieOAuthBearerProvider("MyCookieName") 
     { 
      LoginPath = new PathString("/Account/Login") 
     } 
    } 
); 

现在,我不得不使用定制的提供者,因为承载令牌被存储在cookie中,而不是在标准头。我还需要重定向到登录页面,而不是简单地发出401

public class CookieOAuthBearerProvider : IOAuthBearerAuthenticationProvider 
{ 
    public PathString LoginPath {get; set;} 

    public string CookieName { get; set; } 

    public CookieOAuthBearerProvider(string cookieName) 
    { 
     if(string.IsNullOrWhiteSpace(cookieName)) { 
      throw new ArgumentNullException("cookieName"); 
     } 
     else { 
      this.CookieName = cookieName; 
     }; 
    } 

    public Task ApplyChallenge(OAuthChallengeContext context) 
    { 
     if (this.LoginPath.HasValue) 
     { 
      context.Response.Redirect(this.LoginPath.Value); 
     } 
     return Task.FromResult<object>(null); 
    } 

    public Task RequestToken(OAuthRequestTokenContext context) 
    { 
     string token = context.Request.Cookies[this.CookieName]; 
     if (!string.IsNullOrEmpty(token)) 
     { 
      context.Token = token; 
     } 
     return Task.FromResult<object>(null); 
    } 

    public Task ValidateIdentity(OAuthValidateIdentityContext context) 
    { 
     // prove that the cookie token matches this site using context.Ticket.Identity 
     return Task.FromResult<object>(null); 
    } 
} 

然后,其他地方在你的MVC应用程序,你可以通过简单地说得到理赔:

ClaimsPrincipal.Current 
+0

嘿,我试图使用你的实现原因即时通讯使用JWT令牌,它的工作很好,当我在角度使用它,并在标题中发送令牌...但我需要我的MVC有时切换视图,所以我需要一个cookie让我登录mvc ...但即使使用您的代码,我仍然不会通过控制器中的授权...我在哪里可以调试JWT中的授权属性中发生了什么? – Shakawkaw

相关问题