created an authenticator based on OAuthHandler. in order to make it work, I also needed to specialize a set of options derived from OAuthOptions.
public class MyHandler : OAuthHandler<MyOptions> {
public MyHandler(IOptionsMonitor<MyOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock) { }
protected async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) {
// accessing OAuthHandler.Options here and everything is initialized.
}
public async Task RevokeAuthorizationAsync(string token) {
// following line throws NullReferenceException on accessing OAuthHandler.Options
var request = new HttpRequestMessage(HttpMethod.Post, Options.RevocationEndpoint);
}
}
public class MyOptions : OAuthOptions {
public MyOptions() {
RevocationEndpoint=MyDefaults.RevocationEndpoint;
// other initialization required here...
}
public string RevocationEndpoint {get;set;}
}
the CreateTicketAsync
is a protected method that is overriden from the OAuthHandler
base class, whilst RevokeAuthorizationAsync
is a speciality of MyHandler
.
the login and logout features both work great. since the OAuthHandler doesn't provide any revocation capability, I need to create one to conform with the identity server of the resource being integrated, that is, a cloud-based accounting system.
that being said, I simply thought since the HttpContext
within a controller can challenge the authenticator, let's enable it to revoke tokens!
public static class MyHttpContextExtensions {
public static async Task RevokeAuthorizationAsync(this HttpContext context) {
var token = context.GetTokenAsync(MyDefaults.AuthenticationScheme, "refresh_token");
var handler = context.RequestServices.GetRequiredService<MyHandler>();
// below line calls upon MyHandler speciality method which is to revoke token.
// for some reason, when the handler is initialized, the Options property doesn't get assigned.
await handler.RevokeAuthorizationAsync(token);
}
}
I suspect that I might not initialize the MyHandler
the proper way, if it works with the AddMyHandler extension method.
public static class MyHandlerExtensions {
// many overloads here...
public static AuthenticationBuilder AddMyHandler(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<MyOptions> configureOptions)
=> builder.AddOauth<MyOptions, MyHandler>(authenticationScheme, displayName, configureOptions);
}
which in turn allows to
public class Program {
builder.Services
.AddAuthentication(o => {
// some config here...
})
.AddCookie()
.AddMyHandler(o => {
o.ClientId="my_client_id";
o.ClientSecret="my_client_secret";
});
}
so as stated already, login and logout both work fine. but revoke won't because OAuthHandler.Options
just won't get initialized/assigned!?
I feel like I must be close, but just can't see it.