asp.net – MVC 5 Web API与Facebook访问令牌到RegisterExternal而不需要Coo
|
建立:
通过传入UserName和Password,我可以从Token端点获取我的Web API的Token.然后使用该令牌进行进一步的呼叫. 但 我想在iOS应用程序的Facebook SDK的帮助下注册新用户. 接下来我知道的是通过将该令牌传递给具有承载[访问令牌]的授权头部,但是会导致500个服务器错误,从而调用api / Account / RegisterExternal端点. 我想我知道的原因,Cookie缺失.我用Fidler的一个cookie做了同样的电话,它的工作. (通过转到ExternalLogins端点提供的URL接收Cookie). // POST api/Account/RegisterExternal
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("RegisterExternal")]
public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var info = await Authentication.GetExternalLoginInfoAsync();
if (info == null)
{
return InternalServerError();
}
var user = new ApplicationUser() { UserName = model.Email,Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
result = await UserManager.AddLoginAsync(user.Id,info.Login);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
我不想对我的Web API进行3次调用,要求外部登录,然后转到该URL并在Web浏览器中进行身份验证,以访问Facebook访问令牌,然后使用我需要收集的访问令牌和Cookie调用RegisterExternal端点在这些电话之间. 正如我所说,除了Facebook Ids,我没有改变任何模板.仍然代码如下. public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication,please visit http://go.microsoft.com/fwlink/?LinkId=301864
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.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("/api/Account/ExternalLogin"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.USEOAuthBearerTokens(OAuthOptions);
app.UseFacebookAuthentication(
appId: "xxxxxxxxxxxxxxx",appSecret: "xxxxxxxxxxxxxxxxxxxxxxxx");
}
}
据我所知,Web API不需要Cookie,当我从令牌端点获得本地令牌,但为什么在执行ExternalRegister时首先需要Cookie public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional }
);
}
}
我不知道我是否在这里错过了这一点.我的意图是不需要在本机iOS应用程序中使用Web浏览器进行令牌.那就是Facebook SDK获取访问令牌,并使用该调用RegisterExternal获取本地令牌并创建该用户身份. 我做了我的功课,我坚持这个想法. 解决方法我误以为它接受了Cookie的社交令牌!它不直接接受任何外部令牌. 事情是.. MVC 5正在为我们照顾一切,即从社会媒体收集令牌并验证/处理它.之后,它生成一个本地令牌. RegisterExternal方法还需要维护Cookie,解决方案不会. 我写了一个blog post,这将详细解释.在下面添加了直接的答案.我的目标是使其融合并成为默认MVC Web API的登录/注册流程的组成部分,以确保其易于理解. 在下面的解决方案之后,授权属性必须如下才能工作,否则您将获得未经授权的响应. [Authorize] [HostAuthentication(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalBearer)] [HostAuthentication(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie)] 如果要仅允许令牌使用API,请使用ExternalBearer,如果要仅允许记录的Cookie使用API即从网站使用ApplicationCookie.如果您要允许两者的API,用户都可以. 将此操作添加到AccountController.cs // POST api/Account/RegisterExternalToken
[OverrideAuthentication]
[AllowAnonymous]
[Route("RegisterExternalToken")]
public async Task<IHttpActionResult> RegisterExternalToken(RegisterExternalTokenBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ExternalLoginData externalLogin = await ExternalLoginData.FromToken(model.Provider,model.Token);
if (externalLogin == null)
{
return InternalServerError();
}
if (externalLogin.LoginProvider != model.Provider)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
return InternalServerError();
}
ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,externalLogin.ProviderKey));
bool hasRegistered = user != null;
ClaimsIdentity identity = null;
IdentityResult result;
if (hasRegistered)
{
identity = await UserManager.CreateIdentityAsync(user,OAuthDefaults.AuthenticationType);
IEnumerable<Claim> claims = externalLogin.GetClaims();
identity.AddClaims(claims);
Authentication.SignIn(identity);
}
else
{
user = new ApplicationUser() { Id = Guid.NewGuid().ToString(),UserName = model.Email,Email = model.Email };
result = await UserManager.CreateAsync(user);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
var info = new ExternalLoginInfo()
{
DefaultUserName = model.Email,Login = new UserLoginInfo(model.Provider,externalLogin.ProviderKey)
};
result = await UserManager.AddLoginAsync(user.Id,info.Login);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
identity = await UserManager.CreateIdentityAsync(user,OAuthDefaults.AuthenticationType);
IEnumerable<Claim> claims = externalLogin.GetClaims();
identity.AddClaims(claims);
Authentication.SignIn(identity);
}
AuthenticationTicket ticket = new AuthenticationTicket(identity,new AuthenticationProperties());
var currentUtc = new Microsoft.Owin.Infrastructure.SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromDays(365));
var accessToken = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
Request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",accessToken);
// Create the response building a JSON object that mimics exactly the one issued by the default /Token endpoint
JObject token = new JObject(
new JProperty("userName",user.UserName),new JProperty("id",user.Id),new JProperty("access_token",accessToken),new JProperty("token_type","bearer"),new JProperty("expires_in",TimeSpan.FromDays(365).TotalSeconds.ToString()),new JProperty(".issued",currentUtc.ToString("ddd,dd MMM yyyy HH':'mm':'ss 'GMT'")),new JProperty(".expires",currentUtc.Add(TimeSpan.FromDays(365)).ToString("ddd,dd MMM yyyy HH:mm:ss 'GMT'"))
);
return Ok(token);
}
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – 如何使用存储库模式处理表关系?
- asp.net-mvc – 在控制器中创建操作链接
- asp.net-mvc-3 – 不支持使用相同的DbCompiledModel来针对不
- asp.net-web-api – 无法从’Microsoft.IdentityModel.Toke
- asp.net MVC – ValidationSummary不显示
- asp.net – 使PDF显示内联而不是单独的Acrobat Reader窗口
- asp.net-mvc – Sitecore和ASP.net MVC
- 在Asp.net中运行外部可执行文件的内存限制
- asp.net-mvc – ASP.Net MVC – 视图中的编译器错误
- 从Asp.Net MVC 6 API返回JSON错误
- asp.net-mvc – 如何将用户重定向到ASP.NET MVC中
- asp.net-mvc – Windows 8 VS2012 IISExpress Wi
- 单元测试 – 测试ASP.NET Web API多部分表单数据
- asp.net-mvc – 使用ASP.NET会员资格和配置文件与
- asp.net-mvc – EditorTemplates / Object.cshtm
- asp.net-mvc – 具有ASP.NET MVC的多语言网站
- asp.net-mvc-3 – ASP.Net Mvc 3 Url.Action方法
- asp.net-mvc – 自定义控制器工厂,依赖注入/结构
- 使用ASP.NET,JQuery和Suckerfish构建数据库驱动的
- asp.net-web-api – ASP.NET Web API:如何在Web
