2014-04-09 62 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

相關問題