我正在分两部分创建一个应用程序。在一台服务器上是使用Owin的.net Webapi2。在另一台服务器上是一个MVC5网站,目前没有登录,它将充当api的前端。这也是一个很好的卖点,表明应用程序本身就是客户可以开发的一个例子,因为它依赖于相同的api。我把用户身份验证的东西放在api中,因为我需要第三方才能使用api开发自己的前端应用程序。
我想要完成的事情(理论上) 我需要让用户在前端提交他们的登录信息,它将通过resourceownergrant类型对他们进行身份验证,并收到允许前端创建包含accesstoken和identityuser / roles的cookie的结果。只要这个cookie存在,mvc app就会使用accesstoken调用api。 MVC应用程序和API都可以使用[Authorize]属性。
到目前为止我有什么 我有api up and working,我可以发布“grant_type = password& username = testuser& password = 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"
}
web api的回复也有一个标题
set-cookie: -Long-assserializedcookiestuffhere-
我的问题是如何连接我的mvc应用。
在我的mvc5应用程序中,我在configureauth中使用此设置为owin创建了一个启动
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
CookieName = "MyCookie",
LoginPath = new PathString("/Account/Login")
});
我在测试页面上设置了[Authorize]属性,当我访问时,它正确地将我重定向到登录页面。我缺少的是如何制作它,以便点击登录使网站回复到api并创建一个Owin Cookie,网站将使用该Cookie允许用户通过[authorize] attibute。我还希望它包含identityuser,因此Web应用程序将自动拥有用户信息,而无需在每次调用时回发到api。我不知道我是否能以某种方式从返回结果中获取cookie。
如果他们有更好的方式,我愿意接受建议。
Heeelp!?
答案 0 :(得分:2)
我有完全相同的要求。我试图让MVC5 CookieAuthentication工作,但它不会让我使用自己的cookie值。但是,您的WebAPI不应返回set-cookie。 WebAPI应该是RESTful,并要求客户端在每个请求上传递一个持有者令牌。
所以,这是我的解决方案。用户名和密码将发送到外部API,后者返回JSON Web令牌。 API中的令牌存储在cookie中。您可以在JavaScript或MVC帐户控制器中执行此操作。该cookie由MVC应用程序检查,如果存在,则cookie表示用户也登录到MVC应用程序。
在JavaScript中,您从cookie中提取该令牌,并将其添加到Authorization标头中作为Bearer令牌的API的所有请求中。此外,MVC应用程序可以使用cookie(令牌)的值来访问所有用户的声明。要注销,只需使cookie过期。
首先,将应用程序连接到我们的自定义提供程序
以使用Bearer令牌// 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")
}
}
);
现在,我不得不使用自定义提供程序,因为Bearer令牌存储在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