- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这个问题是我上一个问题的延续:ASP.Net Identity 2 login using password from SMS - not using two-factor authentication
我构建了自定义 OAuthAuthorizationServerProvider 以支持自定义 grant_type。
我的想法是创建 sms
的 grant_type,这将允许用户生成一次性访问代码,该代码将发送到他的手机,然后在使用 grant_type 密码发送请求时作为密码用户。
现在,在生成、存储并通过 SMS 发送该密码后,我想返回自定义响应,而不是来 self 的 GrantCustomExtension 的 token 。
public override async Task GrantCustomExtension(OAuthGrantCustomExtensionContext context)
{
const string allowedOrigin = "*";
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {allowedOrigin});
if (context.GrantType != "sms")
{
context.SetError("invalid_grant", "unsupported grant_type");
return;
}
var userName = context.Parameters.Get("username");
if (userName == null)
{
context.SetError("invalid_grant", "username is required");
return;
}
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindByNameAsync(userName);
if (user == null)
{
context.SetError("invalid_grant", "user not found");
return;
}
var generator = new TotpSecurityStampBasedTokenProvider<ApplicationUser, string>();
await userManager.UpdateSecurityStampAsync(user.Id);
var accessCode = await generator.GenerateAsync("SMS", userManager, user);
var accessCodeExpirationTime = TimeSpan.FromMinutes(5);
var result = await userManager.AddAccessCode(user, accessCode, accessCodeExpirationTime);
if(result.Succeeded)
{
Debug.WriteLine("Login code:"+accessCode);
//here I'll send login code to user phone via SMS
}
//return 200 (OK)
//with content type="application/json; charset=utf-8"
//and custom json content {"message":"code send","expires_in":300}
//skip part below
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "SMS");
var ticket = new AuthenticationTicket(oAuthIdentity, null);
context.Validated(ticket);
}
如何停止生成 token 并从 OAuthAuthorizationServerProvider 返回自定义响应?
我知道两种方法:TokenEndpoint
、TokenEndpointResponse
,但我想覆盖整个响应,而不仅仅是 token 。
编辑:
现在,我正在使用以下代码在 GrantCustomExtension
中创建临时 ClaimsIdentity:
var ci = new ClaimsIdentity();
ci.AddClaim(new Claim("message","send"));
ci.AddClaim(new Claim("expires_in", accessCodeExpirationTime.TotalSeconds.ToString(CultureInfo.InvariantCulture)));
context.Validated(ci);
我正在覆盖 TokenEndpointResponse
:
public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
{
if (context.TokenEndpointRequest.GrantType != "sms") return base.TokenEndpointResponse(context);
//clear response containing temporary token.
HttpContext.Current.Response.SuppressContent = true;
return Task.FromResult<object>(null);
}
这有两个问题:当调用 context.Validated(ci);
时,我说这是一个有效的用户,但我想响应我已发送访问代码的信息通过短信。HttpContext.Current.Response.SuppressContent = true;
清除响应,但我想返回一些内容而不是空响应。
最佳答案
这更像是一种解决方法,而不是最终解决方案,但我相信这是解决问题的最可靠方法,无需重写默认 OAuthAuthorizationServerProvider
实现中的大量代码。
方法很简单:使用 Owin 中间件捕获 token 请求,并在发送 SMS 时覆盖响应。
[评论后编辑] 修复了代码以允许根据此答案缓冲和更改响应主体 https://stackoverflow.com/a/36414238/965722
在您的 Startup.cs
文件中:
public void Configuration(IAppBuilder app)
{
var tokenPath = new PathString("/Token"); //the same path defined in OAuthOptions.TokenEndpointPath
app.Use(async (c, n) =>
{
//check if the request was for the token endpoint
if (c.Request.Path == tokenPath)
{
var buffer = new MemoryStream();
var body = c.Response.Body;
c.Response.Body = buffer; // we'll buffer the response, so we may change it if needed
await n.Invoke(); //invoke next middleware (auth)
//check if we sent a SMS
if (c.Get<bool>("sms_grant:sent"))
{
var json = JsonConvert.SerializeObject(
new
{
message = "code send",
expires_in = 300
});
var bytes = Encoding.UTF8.GetBytes(json);
buffer.SetLength(0); //change the buffer
buffer.Write(bytes, 0, bytes.Length);
//override the response headers
c.Response.StatusCode = 200;
c.Response.ContentType = "application/json";
c.Response.ContentLength = bytes.Length;
}
buffer.Position = 0; //reset position
await buffer.CopyToAsync(body); //copy to real response stream
c.Response.Body = body; //set again real stream to response body
}
else
{
await n.Invoke(); //normal behavior
}
});
//other owin middlewares in the pipeline
//ConfigureAuth(app);
//app.UseWebApi( .. );
}
在您的自定义授权方法中:
// ...
var result = await userManager.AddAccessCode(user, accessCode, accessCodeExpirationTime);
if(result.Succeeded)
{
Debug.WriteLine("Login code:"+accessCode);
//here I'll send login code to user phone via SMS
}
context.OwinContext.Set("sms_grant:sent", true);
//you may validate the user or set an error, doesn't matter anymore
//it will be overwritten
//...
关于c# - ASP.Net Identity 2 - 来自 OAuthAuthorizationServerProvider 的自定义响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36647419/
创建使用.NET框架的asp.net页面时,访问该页面的客户端是否需要在其计算机上安装.NET框架? IE。用户访问www.fakesite.com/default.aspx,如果他们没有安装框架,他
我阅读了很多不同的博客和 StackOverflow 问题,试图找到我的问题的答案,但最后我找不到任何东西,所以我想自己问这个问题。 我正在构建一个应用程序,其中有一个长时间运行的工作线程,它执行一些
已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我一直想知道为什么微软为这样一个伟大的平台选择了一个如此奇怪的、对搜索引擎不友好的名称。他们就
.Net Framework .Net .NET Standard的区别 1、.NET Framework 在未来.NET Framework或许成为过去时,目前还是有很多地方在使用的。这一套
如果有选择的话,您会走哪条路? ASP.NET Webforms + ASP.NET AJAX 或 ASP.NET MVC + JavaScript Framework of your Choice
我有一个 Web 服务,它通过专用连接通过 https 使用第三方 Web 服务,我应用了 ServicePointManager.ServerCertificateValidationCallbac
为什么我应该选择ASP.NET Web Application (.NET Framework)而不是ASP.NET Core Web Application (.NET Framework)? 我在
我在网络上没有找到任何关于包含 .NET Standard、.NET Core 和 .NET Framework 项目的 .NET 解决方案的公认命名约定。 就我而言,我们在 .NET 框架项目中有以
.NET Compact 是 .NET 的完美子集吗? 假设我考虑了屏幕大小和其他限制并避免了 .NET Compact 不支持的类和方法,或者 .NET Compact 是一个不同且不兼容的 GUI
我已经阅读了所有我能找到的关于 connectionManagement 中的 maxconnection 设置的文章:即 http://support.microsoft.com/kb/821268
我现在正在使用asp.net mvc,想知道使用内置的Json或 Json.Net哪个是更好的选择,但我不确定一个人是否比另一个人有优势。 另外,如果我确实选择沿用Json.Net的路线,那么我应该选
在 Visual Studio 中,您至少可以创建三种不同类型的类库: 类库(.NET Framework) 类库(.NET 标准) 类库(.NET Core) 虽然第一个是我们多年来一直使用的,但我
.NET 和 ASP.NET 之间有什么区别?它们有什么关系? 最佳答案 ASP.Net 基于 .Net 框架构建,提供有关 Web 开发的附加功能。 你可以去看看wikipedia article
在安装更高版本(3.0)之前,我需要安装.net框架1.1和2.0吗?或者单独安装 3.0 框架就足够了,并为在早期框架版本上编写的软件提供支持?谢谢 ,丽然 最佳答案 不,您不必安装以前的框架。 我
我正在开发一个项目,人们可以“更新”类别,例如更改类别的名称。我收到以下消息 This is called after clicking update 按钮 with the SQL statemen
.NET 类 System.Net.CookieContainer 线程安全吗? --更新:交 key 答复-- 是否有任何方法可以确保异步请求期间修改的变量(即 HttpWebRequest.Coo
我正在使用 JScript.NET 在我编写的 C# WinForms 应用程序中编写脚本。它工作得很好,但我只是尝试在脚本中放置一些异常处理,但我无法弄清楚如何判断我的 C# 代码抛出了哪种类型的异
我需要你的帮助, 比如我有一个小数类型的变量,我想这样取整。 例如 3.0 = 3 3.1 = 4 3.2 = 4 3.3 = 4 3.4 = 4 3.5 = 4 3.6 = 4 3.7 = 4 3.
我使用过这样的代码:http://msdn.microsoft.com/en-us/library/dw70f090.aspx在 ASP.NET 中工作之前访问数据库(2-3 年前)。我没有意识到我正
自 ConfigurationManager .NET Standard 中不存在,检索正在执行的程序集的应用程序设置的最佳方法是什么,无论是 web.config或 appSettings.{env
我是一名优秀的程序员,十分优秀!