How to do Application-only authentication in doorkeeper (oauth2) - ruby-on-rails

Twitter has application-only authentication for their api: https://dev.twitter.com/docs/auth/application-only-auth
Twitter offers applications the ability to issue authenticated requests on behalf of the application itself (as opposed to on behalf of a specific user)
I want to do the same with doorkeeper in Rails, but I'm not sure how to do that. It seems to be only possible to authenticate users via a callback url, but how can I access my API using the applications context (only by using the app ID and app secret)
My first idea was to do a password credentials login with the app's ID and secret to obtain an access token that belongs to the application. Is this a bad idea? Is it safe from a security point of view? I am wondering because the app's secret is saved as plain text in the db, which is a no go for user authentication.

It is something you can definitely do : you can see on the example here where it generate a token with client_credentials, but no username / password :
curl -i http://localhost:5100/oauth/token \
-F grant_type="client_credentials" \
-F client_id="your_application_id" \
-F client_secret="your_secret"
Up to you after to check if you have a resource_owner associated to your doorkeeper_token.

Related

Support for "Personal Access Tokens" or "API keys"

Does keycloak provide a way to support Personal Access Tokens, similar to Github, when I am using Keycloak to handle authentication and using the tokens it issues to secure my API? When my application is using a web browser then logging in via OIDC flow works fine, but how can I handle login from a CLI or a headless API script for my application?
I could support a password flow where I get back a JWT token after providing a username and password, but I assume once the user has configured 2FA or if they are using SAML on the backend then all bets are off as a username and password would not get you access. This is exactly why Github offers personal access tokens. Is there some way to implement something like this using Keycloak or do we have to build it in our own application and then accept those tokens in addition to the JWT.
What I would envision is Keycloak being able to generate and store personal access tokens in its user store that a user could generate and revoke via the UI that Keycloak provides to the user. My CLI could then use this token to obtain a JWT and then proceed with calling my API the same way a web browser or other client would.
Some support for utilizing OTP during CLI scripting was added in recent Keycloak releases. I've not played with it so far, so i can't present you any recipes. Try to start at Authentication -> HTTP challenge Flow settings.
Regarding to users token you can implement required functionality as an SPI extension to Keycloak (see Server Development section in docs). From my point of view there should be two components:
User token issuer
Custom authenticator that will be used in authentication flow for your client
Here is rough example:
Let User tokens be like UUID strings, so all user tokens could be stored in user attributes (Attributes tab in user's settings Admin UI).
Some of your APIs could introduce dedicated endpoint that will accept valid Access Token< generate new UUID User Token, store it in keycloak user attributes via Admin API and return this token to user.
Then we create custom Authenticator SPI implementation that will extract user token from direct grant auth request and validate it.
And last step is to properly configure direct grant authentication flow for corresponding OIDC client. This flow should work like default if no user token presented in auth request and should validate only user token and ignore other credentials if user token presents.
Keycloak "server development" docs and keycloak sources are very helpful with such king of tasks.

wso2 api manager revoke tokens for specific user or application

In wso2 api manager there is Token API that can be used to revoke specific tokens by clients. This is for applications to handle token revocations during logout etc.
But how to revoke all tokens for specific user when I do not want to let user use API anymore? For example when I removed user account from my service.
Is there ani API that can be called from third party application to api manager with information that the user is removed and therefore api manager should invalidate user’s tokens.
In WSO2 API manager, the access token is generated for an Application. When a user is going to use an API, he/she first needs to Subscribe to that API by create an application for that particular API.
So, if you need to revoke a particular token, you should do it for the application. The Token API of the WSO2 API Manager provides a method to revoke the token.
curl -k -v -d "token=<ACCESS_TOKEN_TO_BE_REVOKED>" -H "Authorization: Basic <base64 encoded (clientId:clientSecret of the application)>" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/revoke
AFAIK, there is no straight forward option to remove the keys for particular user, as users are subscribed to apis via Applications.
However you could do it by deleting the database entry for that particular user in IDN_OAUTH2_ACCESS_TOKEN table, where all the access token information are stored.
For more information for the Token api, please refer the following documentation.
https://docs.wso2.com/display/AM210/Token+API
On a related note: If you want to block a user from accessing APIs, you can use blacklisting feature.
See https://docs.wso2.com/display/AM210/Managing+Throttling#ManagingThrottling-Blacklistingrequests

Can I get Access token of any twitter accounter by just passing user name and password

I want to get twitter access token by just passing twitter user name and password.
Is there any way to get this?
Help me to solve this issue
Yes, you can. Twitter provides xAuth which allows you to submit a username and password, then get back your tokens.
Please note, there are two main restrictions.
You won't get DM access.
You need to specifically request xAuth access from Twitter
xAuth access is restricted to approved applications. If your application is a desktop or mobile application that has no other recourse but to utilize xAuth, send a detailed request to https://support.twitter.com/forms/platform.
I would strongly suggest that you find a way to incorporate the normal oAuth flow into your app.

Oauth2 flow to request a token using Facebook uid for credentials

I am building an iPhone client with a Rails backend. The client communicates with the server through an Oauth2 API. I've set this up using the oauth2 and doorkeeper gems.
Every API request must be sent with a token. I currently support two token "types":
Client: Using the Client Credentials grant type. This is for non-user-specific requests, like accessing app-wide assets, keys, etc.
User: Using the Password Credentials grant type. To get this token, the client must request it by passing a valid username/password combination. All user requests use this token.
This is all working fine but I'm hitting an issue now that I'm allowing a user to also log into the app using Facebook.
Upon the user logging into FB, my client responds by passing the Facebook UID to my server (using a Client token). I then do some checks on my server to match this UID to an existing user in my database.
Here's the issue: I want to respond to this request with a User Token. This token is needed as the user will now be logged into the app, and any subsequent requests will need this token. However, currently I feel like the only way for me to do this is:
Respond with the username and password. Then have the client make a request for a User Token following the Password Credentials flow. I don't like this because I'm passing a password, and it requires multiple trips.
I feel like I may be missing something basic. Is there another way I should be handling this flow?
I think I have a solution but it's definitely a hack.
Basically I'm hijacking the Password Credentials flow to also handle this Facebook scenario.
The client makes the call like so (formatting may be off as I tested in ruby):
curl -i http://www.example.com/oauth/token -F grant_type=password -F client_id=(client id)-F client_secret=(client secret) -F username=(email address) -F password=(password) -F provider="facebook" -F uid=(fb uid) -F token=(fb token)
On my server I check for the "provider" parameter. If found, instead of password authentication it uses the facebook uid to find a match in the user table. I also pass the FB token as a security measure (I verify that this token belongs to the uid before looking for a match). If a match is found, the user is set as the resource owner of the token, meaning I end up with a User Token.
This is the code block from my doorkeeper.rb:
resource_owner_from_credentials do |routes|
if params[:provider]
// FB uid authentication path code here
else
// password authentication
user = User.find_by_email(params[:username])
user if user && user.authenticate(params[:password])
end
end
The resource owner password credentials type defined by OAuth 2.0 doesn't really fit to external logins, e.g., Facebook, since the authentication is done through the external site and not from the username and password on your own authorization server.
One solution is to switch to the implicit grant type of OAuth 2.0 (https://www.rfc-editor.org/rfc/rfc6749#section-4.2). This type is supported by Doorkeeper too.
From your app you have to open a web view and redirect the user to the authorization endpoint of Doorkeeper (default: /oauth/authorize) with the parameters: client_id=..., redirect_uri=... and response_type=token. Additionally you have to tell Doorkeeper to redirect the user to FB login.
Therefore add this to doorkeeper.rb:
resource_owner_authenticator do
user_from_session || begin
session[:return_to] = request.fullpath
fb_login_url = "..." # add here your facebook login url
redirect_to(fb_login_url)
end
end
After the user logged in via FB and you authenticated the user on your server, you have to redirect the user back to session[:return_to] what points to /oauth/authorize and that redirects to the initially given redirect_uri including the access_token in the url.

Twitter authorization via oauth

Been following this tutorial.
Is there a way to "allow access" without having to browse to the url: http://api.twitter.com/oauth/authorize?oauth_token=your_request_token_from_above?
Is there a way I can authorize a user via the oauth gem in console?
The way oauth is implements demands that you send the user to twitter, so that the user could give the authentication details to twitter and then authorize your access request (for your application).
if you want to skip the callback url and all that. You should look at xAuth. With xAuth the you could provide the username and the password and get a token through the API, with no callback URLs or what so ever.
Here some example of how to use xAuth with ruby.

Resources