如何实现OAuth2 Auth_Code流程?

时间:2017-11-16 12:21:15

标签: c# oauth oauth-2.0 asp.net-web-api2

目的: 我与已实施OAuth2授权代码流的第三方合作。我的目标是让我的应用中经过身份验证的用户能够访问此第三方应用的区域,而无需登录第三方。我已向第三方提供了我们的授权网址,clientId和回调网址(不确定如何使用)。

我正在尝试使用OAuth2连接基本授权代码流,但我遇到了invalid_grant错误,并且无法确定进程的工作方式。

以下是我迄今为止实施的内容:

在启动类中,我将OAuth服务器配置为包含AuthorizeEndpointPath和AuthorizationCodeProvider:

var allowInsecureHttp = bool.Parse(ConfigurationManager.AppSettings["AllowInsecureHttp"]);

var oAuthServerOptions = new OAuthAuthorizationServerOptions()
{
    AllowInsecureHttp = allowInsecureHttp,
    TokenEndpointPath = new PathString("/oauth2/token"),
    AuthorizeEndpointPath = new PathString("/oauth2/authorize"),
    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
    Provider = new CustomOAuthProvider(HlGlobals.Kernel),
    AccessTokenFormat = new CustomJwtFormat(_baseUrl, HlGlobals.Kernel),
    AuthorizationCodeProvider = new SimpleAuthenticationTokenProvider()
};

CustomOAuthProider包含以下替代:

public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
    //We validated that Client Id and redirect Uri are what we expect
    if (context.ClientId == "123456" && context.RedirectUri.Contains("localhost"))
    {
        context.Validated();
    }
    else
    {
        context.Rejected();
    } 

    return Task.FromResult<object>(null);
}

public override Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
    var ci = new ClaimsIdentity("Bearer");
    context.OwinContext.Authentication.SignIn(ci);
    context.RequestCompleted();

    return Task.FromResult<object>(null);
}

public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
    string clientId;
    string clientSecret;
    Guid clientIdGuid;    

    // Validate the context
    context.Validated();
    return Task.FromResult<object>(0);
}

最后,SimpleAuthenticationTokenProvider中的代码实现如下:

public SimpleAuthenticationTokenProvider() : base()
{
    this.OnCreate = CreateCode;
    this.OnReceive = ReceiveCode;
}

private readonly ConcurrentDictionary<string, string> _authenticationCodes = new ConcurrentDictionary<string, string>(StringComparer.Ordinal);

public void CreateCode(AuthenticationTokenCreateContext context)
{
    context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n"));
    _authenticationCodes[context.Token] = context.SerializeTicket();
}


public void ReceiveCode(AuthenticationTokenReceiveContext context)
{
    string value;
    _authenticationCodes.TryGetValue(context.Token, out value);
    context.DeserializeTicket(value);
}

我已经在Postman内部连接了一个示例请求。当我执行邮递员oauth2 Authroization Code授权类型时,上面按顺序触发以下方法:

  1. ValidateClientRedirectUri
  2. AuthorizeEndpoint
  3. ValidateClientAuthentication
  4. ReceiveCode
  5. 我从邮递员那里收到'invalid_grant'错误,并且没有返回任何授权码。

    有谁可以指出我在这里可能出错的地方?

    其次,如何使用callbackurl / redirect url?如果用户未经过身份验证,它是否是登录页面的后备?

    更新 我看到响应中redirectURL附带的查询字符串中出现了“代码”。 redirectURL应该是第三方网站上的页面吗?

    这段代码是如何交换令牌的?

    更新2 另一个问题:我在什么阶段读取/解析代码?我可以在GrantClientCredentials方法中查看请求查询字符串中的代码。我应该从查询字符串中解析并验证吗?应该在什么时候调用ReceiveCode?

0 个答案:

没有答案