Doorkeeper and OAuth2 - ruby-on-rails-3

I always have this error when I follow ryan's tutorial to how to use Doorkeeper to protect rest API:
OAuth2::Error: invalid_grant: The provided authorization grant is
invalid, expired, revoked, does not match the redirection URI used in
the authorization request, or was issued to another client.
{"error":"invalid_grant","error_description":"The provided
authorization grant is invalid, expired, revoked, does not match the
redirection URI used in the authorization request, or was issued to
another client."}
when I'm in the phase of parsing token. What is the problem and how I can fix this ?

I have an habit of adjusting my time 20 minutes ahead and it's the source of this problem. Change back the time by synchronizing, now everything works :)

Related

What is the appropriate status code for NotBeforeError JWT Error?

When I googled NotBeforeError JWT Error, it says that it is an error that occurs when you try to use the issued token while it has not yet been activated.
When you have an inactive token, you do not have permission to access a specific resource, so I thought it might be 403.
If the issued token has not been activated yet, it will not pass authentication, so I think that 400 or other codes may be more suitable than 403.
I would say it is a 401 error. I use 401 for situations where the request does not have a valid credential. In your case, there is no valid token. I reserve 403 for situations where there is a valid token in the request, but it doesn't have the required permissions.
The difference is in how the client should react to these errors:
When you get a 401 it is information to the client that the user needs to authenticate. The reason why is not relevant — maybe the token has expired, maybe there's no token, or maybe it violates nbf.
When you get a 403 it is information that the user needs to present stronger credentials. Usually in this case, reauthenticating won't help and the user needs other ways of fixing the problem.

.net core 2.0 & Identityserver4 : Cookie Not getting expired after logout

I am using identityserver4 for all configured clients with "AccesssTokenType=1" i.e. reference type.
I have one web app hosted for server, and other one for clients.
I used default identityserver settings, which generated two cookie, one for session Id "idsrv.session", and other one for authentication "idsrv".
In logout I do signout
await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
however it gives error when I call with "idsrv.session"
await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCheckSessionCookieName);
Issue / Steps to reproduce the problem
1st Iteration : Login on my client website which redirects to my identityserver application. I now interceprt the request and response using "Burp Suite". I copy the complete response which has redirect URL's and cookie details.
I signout/logout from client website.
2nd Iteration : I tried login again, and intercepted the request and response using Burp Suite, by passing wrong credential. While Intercepting the response I just copied the cookies from previous request (which was successful in my first iteration), and observe that identityserver has successfully validated the user using the cookie value, ignoring the wrong credentials in this iteration.
Even I tried invalidating and deleting cookies in my signout/logout method, but looks like identityserver still recognises it as the valid ones.
Brock Allen directed me to the corrrect solution. According to him :
This is the real issue you're asking about -- when you signout, you want the cookie to no longer be valid, even in the scenario when it's stolen and replayed. This is not something IdentityServer can address, because we use Microsoft's cookie authentication to achieve signin. You would have to fix this by changing the default usage of their component. You can do it by implementing "server-side cookie" (a term that I dislike) by implementing an ITicketStore: https://github.com/aspnet/Security/blob/master/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs#L136
Details Here
https://github.com/IdentityServer/IdentityServer4/issues/2565

Social tables authorization and authentication flow

As per the documents received writing down the flow of authorization for version 4.0:
1. call authorize service to get the authorization code back.
2. read the 'code' value for the authorization_code.
3. use this authorization_code to get 'access_token' using '4.0/oauth/token'.
4. for the subsequent calls use 'access_token'.
Please confirm if my understanding above is correct.
My question:
- What will happen when access_token expires? Do we need to go to above flow again?
- the URLs are https does it need certificates?
- what will be the redirect_uri if i want to test in my dev?
I suggest reading a bit about OAuth 2.0 flow. Here's a decent article/example that I would start with from Digital Ocean: https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
But to answer your specific questions:
when the access_token expires you need to make an additional request to Social Tables with the refresh_token -- here's an example: click here. In short, yes you need to use the refresh token to get a new access token which you'll use for subsequent requests
No, you do not need to configure any certificates on your end. These are done via SSL+HTTPS and are ready to go.
The redirect_url for local development can be set to your local running server. You can set it to http://localhost:<port> and that will work just fine.

OAuth v2 (Google API) expiry Access Token

I am building an integration component using a graphical framework who has a pre-build OAuth2 connector.
This framework required following fields for OAuth v2:
Grant type
Scope
Auth Server URL
Client Id
Client Secret
Access Token
Refresh token
I need to get data from Google Analytics API, so I went to Google Dev Console
(https://console.developers.google.com/project/927890000889/apiui/credential). I generated a 'Client ID for web application'. From the parameter of this object I was able to fill some of the parameters above
Grant type : 'authorisation_code'
Client Id : 'RANDOMCHARSam5o37nsiu730d.apps.googleusercontent.com'
Client Secret : 'RANDOMCHARSiSwBA5OH5qYLUa'
Then using Google Oauth Playground (https://developers.google.com/oauthplayground) I was able to fill the missing bits
Scope : 'https://www.googleapis.com/oauth/analytics'
Auth Server URL : 'https://accounts.google.com/o/oauth2/auth'
Access Token : 'RANDOMCHARSQAQv4HRF5-JsQEzUS61lj2YremyCocv0PQ4-agpzJe'
Refresh token : 'RANDOMCHARSLPJnL4FPaDc2KP6V8kCzjjHO2Kj4Np_3X0'
Everything works fine, I am authorised to access and I get data from Google Analytics, but just for a while, after few minutes if I retry I receive an authorisation failure error.
I believe that the problem is related to the expiration of the Access Token, but I don't know how to solve that.
Worth to mention that this activity it's batch (no human interaction), so nobody can request a new access token.
The integration framework is not extensible (I cannot write code to renew the code) so I believe there's a way to get a access token that never expire or some other mechanism to achieve the same result.
Bottom line, I am not sure if I approached the requirement correctly since the beginning (Client ID for web application).
Any help is much appreciated,
Giovanni
Access tokens typically expire after 60 minutes. If you have a refresh token you can use the refresh token to get a new (valid) access token.
This doc explains how to do that:
https://developers.google.com/accounts/docs/OAuth2WebServer#refresh
To answer your overarching question, yes, you are approaching everything correctly. All you need to do is handle the case where the access token has expired by refreshing it. Also, when you originally requested the access token the response should tell you how long it's valid for, so you should only refresh that token if it's expired.
You can use Refresh tokens to make it more long used.
The Google Auth server issued Refresh tokens never expire,
A token might stop working for one of these reasons:
The user has revoked access.
The token has not been used for six months.
The user changed passwords and the token contains Gmail scopes.
The user account has exceeded a certain number of token requests. There is currently a limit of 50 refresh tokens per user account
per client.If the limit is reached, creating a new token automatically invalidates the oldest token without warning.
This limit does not apply to service accounts.
from: https://developers.google.com/identity/protocols/OAuth2

Web API 2, OWIN Authentication, SignOut doesn't logout

I'm doing some research for work with a view to using Bearer tokens as an authentication mechanism (i.e. AngularJS UI, authenticates via OWIN in a Web API [2] project).
I have the login working fine, role information and all that is fine, but I cannot get the token to logout.
My startup configuration is this:
OAuthOptions = new OAuthAuthorizationServerOptions() {
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = SESSION_TIMEOUT,
AllowInsecureHttp = true
};
And my logout action is simply this:
public HttpResponseMessage Logout() {
var authentication = HttpContext.Current.GetOwinContext().Authentication;
authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);
return new HttpResponseMessage(HttpStatusCode.OK);
}
I've left all the authentication stuff out for brevity, but to confirm I am using ExternalBearer when setting up the token.
In my UI I'm storing the token in local storage (no cookies are involved here, which is a deliberate design decision). So I have a logout button on my UI, the Logout action is hit and the code runs fine.
However if I subsequently hit the an action on the API which requires authorisation, the request still goes through (i.e. the user is still authenticated even though they should have been signed out.
Either I'm missing something really obvious (wouldn't be the first time ;-) or there's something more fundamental going on here - finally I'm pinging #leastprivilege as I know this is their area.
Any help or insight would be gratefully received.
Only thing I can think of is that the token is stateless on the server/API side and hence can't be expired or signed out.
If that is the case I guess I could either:
a) Add a refresh token which creates a new token that expires in the past - would this even work? - actually cancel that, it would issue a new token ... the old one would still be valid
b) Store the bearer token in the database and check each time, removing the token on logout (naturally salted, hashed, etc). However this is just bringing us back to having a stateful server.
c) I can (and will) be removing the token from local storage when someone explicitly logs out, however the token is still technically valid if a baddy can intercept the token. Naturally all the above will be over SSL anyway, which should inhibit the bad guys/girls.
d) Perhaps this is why lots of people are storing the Bearer token in a cookie (as a storage mechanism) so once you logout as least the cookie will be removed on the next refresh.
Sorry the above is a bit of a brain dump, just wanting to pre-empt any questions
Since OAuth is not an authentication protocol, there is no notion of signout. Delete the access token on the client - that's all you can do.
If you want to invalidate the token on the server side, add a unique id to it and keep track in your service - you would need to manually build something like that.
I have a beautiful solution here: http://www.nakov.com/blog/2014/12/22/webapi-owin-identity-custom-login-service/. It is custom user session implementation for Web API OAuth bearer token authorization based on OWIN and the standard ASP.NET Identity (Microsoft.AspNet.Identity.EntityFramework). It works as most people may expect:
Web API sessions die after 30 minutes of inactivity.
Session’s life is extended at each authorized HTTP request with additional 30 minutes.
Logout works correctly: after logout the bearer access_token becomes invalid (its is revoked).
Full working source code is available at GitHub: https://github.com/SoftUni/SPA-with-AngularJS/tree/master/Ads-REST-Services
This question has been here for ages (and answered too), but I only wanted to chime in my thoughts.
I would do similar to your (C) option, but use a shorter expiry on the bearer access token something like 10 or 20 minutes, so that when you have logged out and deleted the token on the client, although technically the token is still valid, the bad man will have only the remainder of the expiry time to play with your valid token.
In practice, I would use this together with a long-lived refresh token, so that I can get a new bearer token if it expires and want to continue interacting with the API resources, without having to authenticate again.
As long as I know the bearer token lives in the client side so I don't think that you need a server side "logout" function. Just remove the token from the client local storage should log you out.