dgn*_*dgn 6 asp.net oauth-2.0 owin owin.security
我正在尝试使用authorization_code授权流程设置我的身份验证.我以前曾经使用它grant_type=password,所以我知道这些东西应该如何工作.但是在使用时grant_type=authorization_code,我无法让它返回任何其他东西invalid_grant
这是我的设置:
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/auth/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),
Provider = new SampleAuthProvider()
});
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
AuthenticationType = "Bearer"
});
Run Code Online (Sandbox Code Playgroud)
SampleAuthProvider是以下类:https://gist.github.com/anonymous/8a0079b705423b406c00
基本上,它只是记录每一步并验证它.我试过了这个请求:
POST http://localhost:12345/auth/token
grant_type=authorization_code&code=xxxxxx&client_id=xxxxx&redirect_uri=https://xxxx.com/
Content-Type: application/x-www-form-urlencoded
Run Code Online (Sandbox Code Playgroud)
它正在经历:
OnMatchEndpointOnValidateClientAuthentication就这样.我希望它能打电话OnValidateTokenRequest,OnGrantAuthorizationCode接下来,但事实并非如此.我不知道为什么.
xxxx请求中的's不是占位符,我是这样尝试的.也许中间件会自行进行一些检查并因此拒绝请求?我尝试了redirect_uriwith的变种http,没有任何协议,没有尾随斜线...
它也适用于自定义grant_type.因此,如果我太绝望了,我想我可以用它来模拟authorization_code,但我宁愿不必那样做.
TL; DR
使用后我的OAuthAuthorizationServerProvider回报.{"error":"invalid_grant"}OnValidateClientAuthenticationgrant_type=authorization_code
谢谢你的帮助!
编辑
正如RajeshKannan所指出的,我在配置上犯了一个错误.我没有提供AuthorizationCodeProvider实例.但是,这并没有完全解决问题,因为在我的情况下,代码不是由代码发出的AuthorizationCodeProvider,我不能只是反序列化它.我接受了工作的解决方法.
dgn*_*dgn 10
这就是我的工作.我对这个解决方案并不完全满意,但它有效,应该帮助其他人解决问题.
所以,问题是我没有设置AuthorizationCodeProvider属性.grant_type=authorization_code收到请求后,代码必须由该代码提供程序验证.该框架假定代码是由该代码提供者发布的,但这不是我的情况.我从另一台服务器获取它,并且必须将代码发送回它以进行验证.
在标准情况下,您也是发布代码的人,RajeshKannan提供的链接描述了您必须做的一切.
您必须在此处设置属性:
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString(Paths.TokenPath),
Provider = new SampleAuthProvider(),
AuthorizationCodeProvider = new MyAuthorizationCodeProvider ()
}
Run Code Online (Sandbox Code Playgroud)
和MyAuthorizationCodeProvider班级的宣言:
internal class MyAuthorizationCodeProvider : AuthenticationTokenProvider
{
public override async Task ReceiveAsync(
AuthenticationTokenReceiveContext context)
{
object form;
// Definitely doesn't feel right
context.OwinContext.Environment.TryGetValue(
"Microsoft.Owin.Form#collection", out form);
var redirectUris = (form as FormCollection).GetValues("redirect_uri");
var clientIds = (form as FormCollection).GetValues("client_id");
if (redirectUris != null && clientIds != null)
{
// Queries the external server to validate the token
string username = await MySsoService.GetUserName(context.Token,
redirectUris[0]);
if (!string.IsNullOrEmpty(username))
{
var identity = new ClaimsIdentity(new List<Claim>()
{
// I need the username in GrantAuthorizationCode
new Claim(ClaimTypes.NameIdentifier, username)
}, DefaultAuthenticationTypes.ExternalBearer);
var authProps = new AuthenticationProperties();
// Required. The request is rejected if it's not provided
authProps.Dictionary.Add("client_id", clientIds[0]);
// Required, must be in the future
authProps.ExpiresUtc = DateTimeOffset.Now.AddMinutes(1);
var ticket = new AuthenticationTicket(identity, authProps);
context.SetTicket(ticket);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有同样的错误。我缺少的东西:
OAuthAuthorizationServerOptions.AuthorizationCodeProvider根据文档指定。client_id与 GET 参数相同的参数,就像您收到authorization_code.OAuthAuthorizationServerProvider.ValidateClientAuthentication并在此方法中调用context.TryGetFormCredentials。这会将属性设置为GET 参数context.ClientId中的值。必须设置client_id该属性,否则会出现错误。另外,打电话。invalid_grantcontext.Validated()完成上述所有操作后,我终于可以在令牌端点将 交换authorization_code为 an 。access_token