试图弄清楚OAuth的工作原理,我做了一些沙盒测试,但是当我尝试请求refresh_token时,我得到的是错误请求,而不是OK响应。请在代码中告诉我如何在第二个请求或新请求中返回刷新令牌,以及为什么我不使用OnGrantRefreshToken方法。
public static class Constants
{
public const string BaseAddress = "http://localhost:8181";
public const string TokenAddress = "/token";
}
public class OAuthStartup
{
public void Configuration(IAppBuilder app)
{
var provider = new OAuthAuthorizationServerProvider()
{
OnValidateClientAuthentication = (ctx) =>
{
if (ctx.TryGetBasicCredentials(out var clientId, out var clientSecret) || ctx.TryGetFormCredentials(out clientId, out clientSecret))
{
if (clientId.Equals("client_id") && clientSecret.Equals("client_secret"))
{
ctx.Validated(clientId);
}
}
else
{
ctx.Rejected();
}
return Task.FromResult<object>(null);
},
OnGrantResourceOwnerCredentials = (ctx) =>
{
if (!ctx.UserName.Equals("username") || !ctx.Password.Equals("password"))
{
ctx.SetError("Invalid username or password");
return Task.FromResult<object>(null); }
var identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
ctx.Validated(ticket);
return Task.FromResult<object>(null);
},
OnGrantRefreshToken = (ctx) =>
{
ctx.Validated();
return Task.FromResult<object>(null);
}
};
var option = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString(Constants.TokenAddress),
Provider = provider,
RefreshTokenProvider = new AuthenticationTokenProvider() {
OnCreate = (ctx) =>
{
var expire = 5 * 60;
ctx.Ticket.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddSeconds(expire));
ctx.SetToken("client_refresh_token");
}, OnReceive = (ctx) =>
{
ctx.DeserializeTicket(ctx.Token);
}
}
};
app.UseOAuthAuthorizationServer(option);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active
});
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
}
}
[TestFixture]
public class OAuthTest
{
private TestServer _server;
private HttpClient _client => _server.HttpClient;
[SetUp]
public void SetUp()
{
_server = TestServer.Create<OAuthStartup>();
_server.BaseAddress = new Uri(Constants.BaseAddress);
}
[Test]
public async Task HttpClient_GrandType_RefreshToken_Ok()
{
var request = new HttpRequestMessage(HttpMethod.Post, Constants.TokenAddress);
var properties = new Dictionary<string, string>
{
["client_id"] = "client_id",
["client_secret"] = "client_secret",
["grant_type"] = "password",
["username"] = "username",
["password"] = "password"
};
request.Content = new FormUrlEncodedContent(properties);
try
{
var response = await _client.SendAsync(request);
request = new HttpRequestMessage(HttpMethod.Post, Constants.TokenAddress);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
properties = new Dictionary<string, string>
{
["client_id"] = "client_id",
["client_secret"] = "client_secret",
["grant_type"] = "refresh_token",
["refresh_token"] = "client_refresh_token"
}; request.Content = new FormUrlEncodedContent(properties);
response = await _client.SendAsync(request);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
catch (Exception ex) { Assert.Fail(ex.Message); }
}
}
此外,我想知道我是在正确的方法中获取代码中的刷新令牌,还是需要更改某些内容