- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 OWIN 中间件开发 OAuth v2 授权服务器,我正在尝试实现 OAuth2 Authorization Code Grant Flow但是我遇到了一个问题,如果 redirect_uri 包含查询字符串参数并且资源所有者必须进行身份验证,我的客户端会收到错误。
客户端能够请求身份验证代码,但是当它尝试将代码交换为访问 token 时,授权服务器会以“400 错误请求”的 HTTP 状态和以下响应正文进行响应。
{"error":"invalid_grant"}
如果 redirect_uri 不包含查询字符串参数,或者如果客户端在请求授权码之前删除了它们,那么它将完美地工作。如果资源所有者已经通过授权服务器进行身份验证,那么它也可以正常工作。
我的客户端正在使用 DotNetOpenAuth 并使用 Glimpse 我可以看到 redirect_uri 在授权码请求和访问 token 请求之间是一致的。
Glimpse 日志中的故障如下所示:
Prepared outgoing EndUserAuthorizationRequestC (2.0) message for http://localhost:61814/authorize:
client_id: localhost36618
redirect_uri: http://localhost:36618/login?redirectURL=%2FProfile
state: <state token>
scope: authentication
response_type: code
Processing incoming EndUserAuthorizationSuccessAuthCodeResponse (2.0) message:
code: <authorization code>
state: <state token>
redirectURL: /Profile
Prepared outgoing AccessTokenAuthorizationCodeRequestC (2.0) message for http://localhost:61814/token:
code: <authorization code>
redirect_uri: http://localhost:36618/login?redirectURL=%2FProfile
grant_type: authorization_code
http://localhost:61814/token returned 400 BadRequest: Bad Request
WebException from http://localhost:61814/token: {"error":"invalid_grant"}
但是,如果我从 redirect_uri 中省略查询字符串参数,它会起作用:
Prepared outgoing EndUserAuthorizationRequestC (2.0) message for http://localhost:61814/authorize:
client_id: localhost36618
redirect_uri: http://localhost:36618/Login
state: <state token>
scope: authentication
response_type: code
Processing incoming EndUserAuthorizationSuccessAuthCodeResponse (2.0) message:
code: <authorization code>
state: <state token>
Prepared outgoing AccessTokenAuthorizationCodeRequestC (2.0) message for http://localhost:61814/token:
code: <authorization code>
redirect_uri: http://localhost:36618/Login
grant_type: authorization_code
Processing incoming AccessTokenSuccessResponse (2.0) message:
access_token: <access token>
token_type: bearer
expires_in: 3599
refresh_token: <refresh token>
同样,如果我在使用客户端之前登录到授权服务器,它会起作用:
Prepared outgoing EndUserAuthorizationRequestC (2.0) message for http://localhost:61814/authorize:
client_id: localhost36618
redirect_uri: http://localhost:36618/login?redirectURL=%2FProfile
state: <state token>
scope: authentication
response_type: code
Processing incoming EndUserAuthorizationSuccessAuthCodeResponse (2.0) message:
code: <authorization code>
state: <state token>
redirectURL: /Profile
Prepared outgoing AccessTokenAuthorizationCodeRequestC (2.0) message for http://localhost:61814/token:
code: <authorization code>
redirect_uri: http://localhost:36618/login?redirectURL=%2FProfile
grant_type: authorization_code
Processing incoming AccessTokenSuccessResponse (2.0) message:
access_token: <access token>
token_type: bearer
expires_in: 3599
refresh_token: <refresh token>
OWIN 授权服务器的 OAuthAuthorizationServerProvider 在成功访问 token 授权代码请求时执行以下方法:
然而,不成功的访问 token 授权代码请求仅涉及以下方法:
AuthorizationCodeProvider.OnReceive 具有以下实现:
private void ReceiveAuthenticationCode(AuthenticationTokenReceiveContext context)
{
try
{
string ticket = _repo.RemoveTicket(context.Token);
if (!string.IsNullOrEmpty(ticket))
{
context.DeserializeTicket(ticket);
}
}
catch (Exception ex)
{
var wrapper = new Exception("Receive Authentication Code Error", ex);
Logger.Error(wrapper);
}
}
在调试器中,我可以看到一个有效的 token ,从 _repo 成功检索到序列化票证,以及在方法完成之前上下文对象中的反序列化票证。不会抛出异常。成功请求和失败请求之间的流程看起来完全相同,所以我不清楚是什么失败了,并且诊断工具事件日志在请求处理期间没有显示任何异常,只是在 ReceiveAuthenticationCode 完成后退出的线程。
看起来问题出在我的测试客户端上,因为我能够使用 Brent Shaffer's OAuth2 Demo PHP live demo 重现完全相同的问题.
测试客户端基于 DotNetOpenAuth:
private static class Client
{
public const string Id = "username";
public const string Secret = "password";
}
private static class Paths
{
public const string AuthorizationServerBaseAddress = "http://localhost:61814";
public const string ResourceServerBaseAddress = "http://localhost:61814";
public const string AuthorizePath = "/authorize";
public const string TokenPath = "/token";
public const string ResourceServerApiMethodPath = "/getaccount";
}
public ActionResult Login(string code = "", string redirectURL = "/profile")
{
var authorizationServerUri = new Uri(Paths.AuthorizationServerBaseAddress);
var authorizationServer = new AuthorizationServerDescription
{
AuthorizationEndpoint = new Uri(authorizationServerUri, Paths.AuthorizePath),
TokenEndpoint = new Uri(authorizationServerUri, Paths.TokenPath)
};
var client = new WebServerClient(authorizationServer, Client.Id, Client.Secret);
if (!string.IsNullOrEmpty(code))
{
var apiResponse = null;
var authorizationState = client.ProcessUserAuthorization();
if (!string.IsNullOrEmpty(authorizationState?.AccessToken))
apiResponse = GetApiResponse(authorizationState, Paths.ResourceServerApiMethodPath);
if (apiResponse != null)
{
var identity = new ClaimsIdentity(new[] { new Claim("test", apiResponse),
new Claim(ClaimTypes.Role, "ResourceOwner")
}, "ApplicationCookie");
AuthMgr.SignIn(new AuthenticationProperties { IsPersistent = true }, identity);
return Redirect(redirectURL);
}
}
else
{
client.RequestUserAuthorization();
}
return View();
}
知道我使用 DotNetOpenAuth 可能做错了什么吗?为什么我在服务器端看不到无效请求?
最佳答案
我解决了。获取access_token不要使用webclient.ProcessUserAuthorization(Request)方法。
using (var client = new HttpClient())
{
var uri = new Uri($"http://localhost:24728/ClientAuthorization?tourl={tourl}");
var httpContent = new FormUrlEncodedContent(new Dictionary<string, string>()
{
{"code", code},
{"redirect_uri", uri.AbsoluteUri},
{"grant_type","authorization_code"},
{"client_id", ClientStartupProfile.Client.ClientId},
{"client_secret", ClientStartupProfile.Client.Secret}
});
var response = await client.PostAsync(ClientStartupProfile.AuthorizationServer.TokenUri, httpContent);
var authorizationState = await response.Content.ReadAsAsync<AuthorizationState>();
//判断access_token 是否获取成功
if (!string.IsNullOrWhiteSpace(authorizationState.AccessToken))
Response.Cookies.Add(new System.Web.HttpCookie("access_token", authorizationState.AccessToken));
return Redirect(tourl);
}
关于c# - 当 redirect_uri 包含查询字符串参数时,DotNetOpenAuth 拒绝访问 token 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37329637/
我正在开发一个应用程序,它使用 OAuth - 基于 token 的身份验证。 考虑到我们拥有访问和刷新 token ,这就是流程的样子。 Api call -> intercepter append
如何取消标记此代码的输出? 类(class)核心: def __init__(self, user_input): pos = pop(user_input) subject = ""
当我使用命令 kubectl 时与 --token标记并指定 token ,它仍然使用 kubeconfig 中的管理员凭据文件。 这是我做的: NAMESPACE="default" SERVICE
我正在制作 SPA,并决定使用 JWT 进行身份验证/授权,并且我已经阅读了一些关于 Tokens 与 Cookies 的博客。我了解 cookie 授权的工作原理,并了解基本 token 授权的工作
我正在尝试从应用服务获取 Google 的刷新 token ,但无法。 日志说 2016-11-04T00:04:25 PID[500] Verbose Received request: GET h
我正在开发一个项目,只是为了为 java 开发人员测试 eclipse IDE。我是java新手,所以我想知道为什么它不起作用,因为我已经知道该怎么做了。这是代码: public class ecli
我正在尝试使用 JwtSecurityTokenHandler 将 token 字符串转换为 jwt token 。但它出现错误说 IDX12709: CanReadToken() returned
我已阅读文档 Authentication (来自 Facebook 的官方)。我仍然不明白 Facebook 提供的这三种访问 token 之间的区别。网站上给出了一些例子,但我还是不太明白。 每个
我的部署服务器有时有这个问题,这让我抓狂,因为我无法在本地主机中重现,我已经尝试在我的 web.config 中添加机器 key ,但没有成功远。 它只发生在登录页面。 我的布局:
我已经设法获得了一个简单的示例代码,它可以创建一个不记名 token ,还可以通过阅读 stackoverflow 上的其他论坛来通过刷新 token 请求新的不记名 token 。 启动类是这样的
如果我有以前的刷新 token 和使用纯 php 的访问 token ,没有 Google Api 库,是否可以刷新 Google Api token ?我在数据库中存储了许多用户刷新和访问 toke
我通过 Java 应用程序使用 Google 电子表格时遇到了问题。我创建了应用程序,该应用程序运行了 1 年多,没有任何问题,我什至在 Create Spreadsheet using Google
当我有一个有效的刷新 token 时,我正在尝试使用 Keycloak admin REST API 重新创建访问 token 。 我已经通过调用 POST/auth/realms/{realm}/p
我正在尝试让第三方 Java 客户端与我编写的 WCF 服务进行通信。 收到消息时出现如下异常: Cannot find a token authenticator for the 'System.I
在尝试将数据插入到我的 SQl 数据库时,我收到以下错误 System.Data.SqlServerCe.SqlCeException: There was an error parsing the
使用数据库 session token 系统,我可以让用户使用用户名/密码登录,服务器可以生成 token (例如 uuid)并将其存储在数据库中并将该 token 返回给客户端。其上的每个请求都将包
我最近注册了 Microsoft Azure 并设置了认知服务帐户。使用 Text Translation API Documentation 中的说明我能够使用 interactive online
我使用 IAntiforgery API 创建了一个 ASP.Net Core 2 应用程序。 这提供了一种返回 cookie 的方法。 客户端获取该 cookie,并在后续 POST 请求中将该值放
我正在使用 spacy 来匹配某些文本(意大利语)中的特定表达式。我的文本可以多种形式出现,我正在尝试学习编写一般规则的最佳方式。我有如下 4 个案例,我想写一个适用于所有案例的通用模式。像这样的东西
我无法理解 oauth 2.0 token 的原则处理。 我的场景是,我有一个基于 web 的前端后端系统,带有 node.js 和 angular 2。用户应该能够在此站点上上传视频。然后创建一些额
我是一名优秀的程序员,十分优秀!