Reputation: 20224
I have a WebAPI with OAuth login configured like this:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = "https://www.microsoft.com/",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + context.Exception.Message);
return Task.FromResult(0);
}
}
});
and Login enforced for all Controllers using
config.Filters.Add(new System.Web.Http.AuthorizeAttribute());
I now want to add an ApiController called LogoutController (guess what it does).
I have found that I can logout from MVC using
System.Web.Security.FormsAuthentication.SignOut();
but I am not logged out from WebAPI that way. I have not found any information how to logout from WebAPI. But I have found that there may be a bug in logout procedure, the cookie is kept and has to be removed manually, but then, the code is MVC again, and it seems as if I can't get a HttpCookie
into my HttpResponseMessage
object:
[HttpGet]
public HttpResponseMessage Logout()
{
FormsAuthentication.SignOut();
// clear authentication cookie
HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, "");
cookie1.Expires = DateTime.Now.AddYears(-1);
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent("<html><title>Logout successful</title><body style=\"font-family:sans-serif\"><div style=\"display:table; width:100%; height:100%; margin:0; padding:0; \"><div style=\"display:table-cell; vertical-align:middle; text-align:center;\">You have been successfully logged out.<br>You can close this window/tab now.</div></div></body></html>");
response.Headers.AddCookies(cookie1); // Types don't match
return response;
}
How can I achieve that my WebAPI is logged out and does require OAuth to be done again before I am logged in?
Upvotes: 1
Views: 6626
Reputation: 4467
You can't logout of the API because you're not logged in to it!
For example, say your API uses Facebook as its OpenID authentication provider. Your user will have to log into facebook to use your API. Your API will redirect them to facebook auth server and if they are not logged in - facebook will ask them to log in.
If the user decides to stay logged into facebook, then each time they use your API, they will not be required to login to facebook again and your middleware code will obtain a valid token for them to access your API.
Your API can't remove the browser cookie between facebook and your user's browser so you can't log them out of facebook, so you can't stop them getting new tokens when they want.
I don't know what OpenID provider you use but I would think the above applies for any.
You can log out of MVC app as it would have created a cookie between you (user agent) and the MVC app when you logged in. It can delete its own cookie!
Upvotes: 4
Reputation: 563
The easiest way is for the client itself to just "forget" the token - no need to tell server about it (this is what clearing the auth cookie really is doing - making the browser remove the cookie).
If you want the token itself to be no longer valid, than you would need to maintain a list of revoked tokens. For various reasons you may want your access tokens to be always valid but short lived and revoke refresh tokens instead.
Upvotes: 5