I have a Keycloak server setup with a realm and a client. I have Authorization setup on the client and I'm able to evaluate the authentication within the admin interface.
When I click "Show authorization data", I can see in the response an authorization attribute with permissions.
I have a web client that uses a redirect via keycloak for oidc authentication. I would like to limit which keyclock users are able to login into the client, so I would like to authorise the login, but I'm unable to see the authorization attribute in the JWT.
Am I completely misunderstanding how this works, or is there something I can do to see that attribute?
OK, I've finally go my head around it. Short answer - I needed to RTFM.
Long answer - I needed to hit the token endpoint twice. The first time with grant_type = authorization_code to get the access token. Then again with grant_type = urn:ietf:params:oauth:grant-type:uma-ticket (and with the access token in the header) to get the keycloak client to authenticate.
If the second response comes back as 403 - access_denied, then I reject the login, otherwise, I allow the user to login into my system.
The specific bit I needed can be found in the docs is here: https://www.keycloak.org/docs/6.0/authorization_services/#_service_obtaining_permissions
Related
My simple application written in Javascript is using a service (which is written as a wrapper on Auth0) for authentication. On successful login, if I refresh the home page, application again goes to login page (even if I have stored the access token in cookies)
I also tried to store the access token in browser session storage.
As my index.html is launched, i am checking if my application url contains access token. If there is no access token, I redirect it to login page.
if (((window.location.hash).indexOf('access_token') < 0)) {
location.replace(redirectUrl);
}
On successful login, as url has access token in it, app works fine further.
But next time when I refresh the home page, it don't have access token in URL.
As per my understanding, as I have access token in cookies, it should not ask me for login again as long as token is valid.
It is still asking for login. What should be the strategy should I use to persist the token ?
On logout, I am setting the cookie to expire. Is there any ideal way to do log out other than this?
This can often be troubleshooted with a HAR file capture to follow the trail being left in the authentication flow. However since we don't have that option at this juncture here are a couple things to look at.
Are you using Dev keys in your auth scenario?
Expiry time
Where is the access token being stored?
https://auth0.com/docs/tokens/overview-access-tokens
Currently, you have a somewhat incomplete implementation.
As per my understanding, as I have access token in cookies, it should not ask me for login again as long as token is valid.
Saving token in the cookie storage and local storage does not have any relation with user authentication state. It is just a way of persisting the token and reading the data. In each navigation, you need to read the token and extract the information from the token to make sure user is authenticated.
The architecture you should follow:
Redirect the user to /authorize endpoint if there is no valid token in the application.
Once auth0 finish the user validation, the user will be redirected in the whitelisted callback URL. Make sure this URL is unique and save the token from URL fragments. It is very important to complete the token validation on the client side. Otherwise, it will be a major security issue. https://auth0.com/docs/tokens/guides/id-token/validate-id-token
Redirect the user to the secured URL.
I would highly recommend using auth0 SDK as it mitigates all the security issues including token signature validation using RS256 algorithm.
https://auth0.com/docs/quickstart/spa/vanillajs/01-login
You may find folloiwng thread useful
Why my auth0 token expires when refreshing page or clicking link in my Angular app?
Sign in intent doesn't work at the moment as clearly explained in the docs, it's just something you can use for test in the emulator, but it's not available in production.
My case is I'm using account linking and my token expires after one day, so if the user doesn't interact with the assistant, the token will no longer be valid. Then if the token is proved as invalid on the webhook I want to send back 'please link your account again' to the assistant from the webhook.
There is a method app.askForSignIn(); which seems similar to what I need but it looks like it is not available for Dialogflow and only available for the SDK.
So what I have done is:
Make an intent in Dialogflow with the name actions.intent.SIGN_IN and added actions_intent_SIGN_IN event to it
When any request comes to the webhook I check the token, then if I encounter an invalid token I call app.askForSignIn();
What is happening:
The app just left the conversation e.g: test app left the conversation
When I say again "talk to test app" it is behaving like the account is linked and does not ask for account linking until I manually reset the whole app using the reset button from test console
Update:
I tried to use the code snippet from the doc (https://developers.google.com/actions/reference/nodejs/AssistantApp#askForSignIn)
and it is not working as well, here is the response from the simulator when I call app.askForSignIn(); from the webhook
You can have 2 tokens, one being the access token, which is short-lived, and the other being the refresh token which is long-lived.
So, When Google needs to call one of your service's APIs, Google uses these endpoints together to get permission from your users to call these APIs on their behalf. A typical OAuth 2.0 session initiated by Google has the following flow:
First, Google opens your authorization endpoint in the user's browser. The user signs in if not signed in already, and grants Google permission to access their data with your API if they haven't already granted permission.
Then, your service creates an authorization code and returns it to Google by redirecting the user's browser back to Google with the authorization code attached to the request.
Next, Google sends the authorization code to your token exchange endpoint, which verifies the authenticity of the code and returns an access token and a refresh token. The access token is a short-lived token that your service accepts as credentials to access APIs. The refresh token is a long-lived token that Google can store and use to acquire new access tokens when they expire.
Finally, Google calls your service's APIs, attaching the access token with each request. Your service verifies that the access token grants Google authorization to access the API, then completes the API call.
I have a problem understanding the principle handling of oauth 2.0 tokens.
My scenario is, I have a web based frontend backend system with node.js and angular 2.
A user should be able upload a video on this site. Then some additional metadata is created (dosen't matter for this question). When that is done, the user could upload the video to youtube with the additional data by clicking on a button.
My question is how many tokens/credentials are there in this process. The youtube api needs an oauth token. Does the user also have its own token?
Here is the tutorial I used:
https://ionicabizau.net/blog/14-uploading-videos-to-youtube-using-nodejs
As you can see one token for the API is created for local testing. But is this token generated in a different way in a live version? And how is the user of my website recognized. Also via this token? Or do I have to generate a second token for him?
I am not sure what you mean by 'Token'.
In order to access any Google API you will first need to register your application on Google Developer console. You will then need to create Oauth2 credentials. Oauth2 credentials is were your application will request access from a user to access the data on their YouTube account.
On Google Developer console you will need to save the Client id, client secret and the redirect uri. All three will be needed by your code to authenticate the user.
When the user grants your application access to their YouTube data. You will get an access token and a refresh token back from the authentication server. Access tokens are short lived about an hour and are used to make requests (like upload) to the API. A refresh token can be used to request a new access token once the one you have currently has expired.
You will probably end up with the following:
client id, client secrete, redirect uri, and a refresh token.
If you are interested I have a tutorial that is part of my Google Development for beginners tutorial series that explains Oauth2 and how it works.
An access token is generated from the Server side and sent back to client from where the access request is generated. For all the subsequent requests you need to pass the access token which will be verified with the signature of the token saved on the server to check the authentication of valid requests. You will only get 1 access token which will be used.
You can also use "Refresh" tokens in case you need to keep your access tokens valid for longer duration.
I'm currently building a frontend client for my own Apigility API.
The API uses OAuth 2.0 Authentication which is working fine.
I want to create an AngularJS Landingpage to let the users authenticate by entering their credentials. Because the Client is created with JavaScript,
I shouldn't save the client_secret in the Client, correct?
I have read a lot of posts, but still haven't the right solution.
Is it correct to use the implicit grant type for this scenario?
This procedure is working, I'm being redirected to the authentication server,
after the client authorization and entering credentials, I get back to the client (authenticated).
But I don't want to get redirected to another authentication page.
Is it also possible to authenticate directly and secure on the angularJS frontend?
Thanks,
Simon
You should take a look at this post i made:
https://stackoverflow.com/a/42443878/2963703
It details how to do this using the Spotify API. Your page won't get redirected, instead a popup window will open in which the user authorizes themselves. Once they're authorized the window will close itself and in your main page you will have the access token you need.
I want to import contacts of a Gmail user through the Google API.
I have the following:
Use Client secret and key to obtain the authorized url. This is the url which the user visits to allow permission for my app.
The authorized url redirects to the redirect uri specified in the App settings.
I have a query parameter code in the url and I am guessing this is the Authorized code that the docs say here.
The problem:
I want to exchange this code to obtain the access token and the refresh token through javascript if possible. But I can't see any docs for this part in javascript.
In my server side I am doing this to obtain the authorized url:
token = gdata.gauth.OAuth2Token(client_id=settings.GMAIL_CLIENT_ID,
client_secret=settings.GMAIL_API_KEY,
scope=scope, user_agent=user_agent)
auth_url = token.generate_authorize_url(redirect_uri=redirect_uri)
and then redirecting the user to auth_url. Now once the user is allowing the requested permissions they are redirected back to my site with the query parameter code. I want to use javascript from here to get the access token.
The other option is to get the access token in the server side once the user is redirected to my site and return it to him along with the response but I dont really want to do this.
Short answer: if you want to use OAuth2 client-side authentication, you're using the wrong documentation.
Now the details.
OAuth2 has 4 grant types:
Authorization Code,
Implicit,
Resource Owner Password Credentials and
Client Credentials
If you want more details, you can read this nice post with explanation.
You've pointed the Google docs for OAuth2 for Web Servers, which fits Authorization Code type. It relies on Web Server data exchange over SSL, because it involves exchange the client_secret.
I.e, if you try do the POST request to get the access_token using JavaScript, you'll expose your client_secret, as it's a required parameter in the POST call.
If you want try request the access_token not using server side code, you need to use the Implicit grant type.
You can find Google documentation for Implicit grant type in Using OAuth 2.0 for Client-side Applications