Asp.net mvc 手动授予访问令牌MVC Web API
我允许用户从应用程序注册到MVC Web API。该应用程序传递电子邮件,但没有密码。我添加用户并分配一个随机密码,然后将其发送给用户 我不希望应用程序两次调用api来获取令牌。 因此,对于这个请求,我想返回一个oauth令牌,Asp.net mvc 手动授予访问令牌MVC Web API,asp.net-mvc,model-view-controller,asp.net-web-api,Asp.net Mvc,Model View Controller,Asp.net Web Api,我允许用户从应用程序注册到MVC Web API。该应用程序传递电子邮件,但没有密码。我添加用户并分配一个随机密码,然后将其发送给用户 我不希望应用程序两次调用api来获取令牌。 因此,对于这个请求,我想返回一个oauth令牌,/token端点返回 我正在尝试此操作,但来自此请求的令牌访问被拒绝。 我错过了什么?如果有更好的方法,我们将不胜感激 Web API具有与Web API模板类似的默认配置。没有什么习俗。我想保持这样 ClaimsIdentity identity = n
/token
端点返回
我正在尝试此操作,但来自此请求的令牌访问被拒绝。
我错过了什么?如果有更好的方法,我们将不胜感激
Web API具有与Web API模板类似的默认配置。没有什么习俗。我想保持这样
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
Claim providerKeyClaim = new Claim(ClaimTypes.Email, model.Email, ClaimValueTypes.String, "DrySignup", "DrySignup");
ExternalLoginData externalLogin = new ExternalLoginData
{
LoginProvider = providerKeyClaim.Issuer,
ProviderKey = providerKeyClaim.Value,
UserName = identity.FindFirstValue(ClaimTypes.Email)
};
var info = new ExternalLoginInfo()
{
DefaultUserName = model.Email,
Login = new UserLoginInfo(providerKeyClaim.Issuer, 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("userId", user.Id),
new JProperty("access_token", accessToken),
new JProperty("token_type", "bearer"),
new JProperty("expires_in", TimeSpan.FromDays(9999).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);
ClaimsIdentity identity=newclaimsidentity(OAuthDefaults.AuthenticationType);
Claim providerKeyClaim=新索赔(ClaimTypes.Email、model.Email、ClaimValueTypes.String、“干注册”、“干注册”);
ExternalLoginData externalLogin=新的ExternalLoginData
{
LoginProvider=providerKeyClaim.Issuer,
ProviderKey=providerKeyClaim.Value,
用户名=identity.FindFirstValue(ClaimTypes.Email)
};
var info=new ExternalLoginInfo()
{
DefaultUserName=model.Email,
Login=new UserLoginInfo(providerKeyClaim.Issuer,externalLogin.ProviderKey)
};
结果=wait UserManager.AddLoginAsync(user.Id,info.Login);
如果(!result.successed)
{
返回GetErrorResult(结果);
}
identity=await UserManager.CreateIdentityAsync(用户,OAuthDefaults.AuthenticationType);
IEnumerable claims=externalLogin.GetClaims();
身份。添加索赔(索赔);
身份验证。签名(身份);
AuthenticationTicket票证=新的AuthenticationTicket(标识,新的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(票证);
Request.Headers.Authorization=new System.Net.Http.Headers.AuthenticationHeaderValue(“Bearer”,accessToken);
//创建响应,构建一个JSON对象,该对象完全模仿默认/令牌端点发出的JSON对象
JObject令牌=新JObject(
新的JProperty(“用户名”,user.userName),
新的JProperty(“userId”,user.Id),
新的JProperty(“访问令牌”,accessToken),
新产权(“令牌类型”、“持有人”),
新的JProperty(“expires_in”,TimeSpan.FromDays(9999.TotalSeconds.ToString()),
新的JProperty(“已发布”,当前UTC.ToString(“ddd,dd-MMM-yyy-HH':'mm':'ss'GMT')),
新的JProperty(“expires”,currentUtc.Add(TimeSpan.FromDays(365)).ToString(“ddd,dd-MMM-yyyy-HH:mm:ss'GMT'))
);
返回Ok(令牌);
您的问题的简短答案是,您不能以这种方式颁发令牌并使用内置的OAuthProvider
通过在OAuthServerOptions
中将此函数设置为AuthorizeEndpointPath
,您仍然可以实现所需的功能
如果您这样做,您将不得不发送response\u type=token&client\u id=something&redirect\u uri=/index.html
query参数作为请求的一部分,然后您将得到一个302,其中访问令牌作为url的一部分。比如:
http://example.com/index.html/#access_token={long token string here}&token_type=bearer&expires_in=1209600
然后在你的控制器函数中,你的代码看起来像这样
ApplicationUser user = await UserManager.FindByEmailAsync("email@example.com");
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
Authentication.SignIn(properties, oAuthIdentity);
return Ok();
你的第二个选择是实现一个自定义的授权类型。这将允许您调用/token服务并创建帐户。在OAuthProvider类上,您希望覆盖GranCustomExtension
函数
public override async Task GrantCustomExtension(OAuthGrantCustomExtensionContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var email = context.Parameters["Email"];
var createUser = new ApplicationUser() { UserName = email, Email = email };
IdentityResult result = await userManager.CreateAsync(createUser, "Som3R@ndomPassword");
if (!result.Succeeded)
{
return;
}
ApplicationUser user = await userManager.FindByEmailAsync(email);
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
}
公共重写异步任务GrantCustomExtension(OAuthGrantCustomExtensionContext)
{
var userManager=context.OwinContext.GetUserManager();
var email=context.Parameters[“email”];
var createUser=newapplicationuser(){UserName=email,email=email};
IdentityResult result=await userManager.CreateAsync(createUser,“Som3R@ndomPassword");
如果(!result.successed)
{
返回;
}
ApplicationUser user=await userManager.findbyemailsync(电子邮件);
ClaimsIdentity oAuthIdentity=等待用户.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
AuthenticationProperties=ApplicationAuthProvider.CreateProperties(user.UserName);
AuthenticationTicket=新的AuthenticationTicket(OAuthidentitity,属性);
上下文。已验证(票证);
}
然后,您可以使用URL编码的请求表单向/token发送如下内容的请求grant\u type=create&Email=test3%40example.com
,您的响应将与使用password
grant\u type
一样有效
ClaimsIdentity oAuthIdentity = new ClaimsIdentity(Startup.OAuthOptions.AuthenticationType);
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
oAuthIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
DateTime currentUtc = DateTime.UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromDays(365));
string 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("userId", 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);
谢谢,你救了我一天。最后我做了这件事,这也是我用于外部登录的,我尝试使用OWIN TestServer,正如一些人建议的那样调用令牌端点,但没有用,在一些项目中,它在我的系统中起作用