Situation: 我有一个Web API 2项目,它充当授权服务器(/ token endpoint)和资源服务器 . 我正在使用ASP.Net Web API开箱即用的模板减去任何MVC参考 . Start.Auth配置如下:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
AppId = ConfigurationManager.AppSettings["Test_Facebook_AppId"],
AppSecret = ConfigurationManager.AppSettings["Test_Facebook_AppSecret"],
//SendAppSecretProof = true,
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
return Task.FromResult(0);
}
}
};
facebookAuthenticationOptions.Scope.Add("email user_about_me user_location");
app.UseFacebookAuthentication(facebookAuthenticationOptions);
}
MVC 5客户端(不同的项目)使用Web API应用程序进行授权和数据 . 以下是在用户名/密码存储的情况下检索Bearer令牌的代码:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
model.ExternalProviders = await GetExternalLogins(returnUrl);
return View(model);
}
var client = Client.GetClient();
var response = await client.PostAsync("Token",
new StringContent(string.Format("grant_type=password&username={0}&password={1}", model.Email, model.Password), Encoding.UTF8));
if (response.IsSuccessStatusCode)
{
return RedirectToLocal(returnUrl);
}
return View();
}
Problem
我可以检索Bearer令牌,然后将其添加到Authorization Header以进行后续调用 . 我认为如果是Angular App或SPA,那就没关系了 . 但我认为MVC中应该有一些东西可以为我处理它,比如自动将它存储在cookie中并在后续请求中发送cookie . 我已经搜索了很多,并且有一些帖子暗示了这个(Registering Web API 2 external logins from multiple API clients with OWIN Identity),但是我得到一个令牌后我无法弄清楚要做什么 .
我需要在MVC应用程序Startup.Auth中添加一些东西吗?
理想情况下,我需要ASP.Net模板(MVC Web API)中的AccountController提供的功能(登录,注册,外部登录,忘记密码等等),但在不同的项目中使用MVC和Web API .
是否有模板或git仓库有这个锅炉板代码?
提前致谢!
Update 合并@FrancisDucharme建议,下面是GrantResourceOwnerCredentials()的代码 .
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
//Add a response cookie...
context.Response.Cookies.Append("Token", context.Options.AccessTokenFormat.Protect(ticket));
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
但我似乎还不能得到那个Cookie或弄清楚下一步该做什么 .
Restating Questions:
-
从MVC客户端验证,授权和调用Web API方法(Auth和资源服务器)的正确方法是什么?
-
是否有AccountController的样板代码或模板进行基本的管道工作(登录,注册 - 内部/外部,忘记密码等)?
1 回答
你可以让你的Startup类返回一个响应cookie,然后客户端将在所有后续请求中返回,这是一个例子 . 我会在
GrantResourceOwnerCredentials
做 .Startup类:
这假设客户端已启用cookie,当然 .
然后,modify your MVC headers将Authorization标头添加到所有请求中 .
在
ActionFilterAttribute
中,获取您的cookie值(Token
)并添加 Headers .