I'm using keycloak to let my users authenticate with my application. And i am trying to migrate some functionality to a few plugins, e.g. a wordpress plugin. For these plugins i want to use a generic solution so I found the following authentication process from Microsoft (https://learn.microsoft.com/en-us/office/dev/add-ins/develop/auth-external-add-ins#middleman-services) and Adobe ( https://adobexdplatform.com/plugin-docs/tutorials/how-to-integrate-with-OAuth/).
I managed to hack my way around the process to get this working with keycloak. But at this moment I'm a bit concerned about the security risk that go with this process.
The process in steps
the (plugin) client asks to backend server to generate a code to identify the user.
the (plugin) client start polling the backend for an authentication code (no response yet, since the user is not logged in yet).
the plugin opens a browser window or tab with the keycloak loginpage. Everything is the same as the normal process, but this time we add an redirect uri with the code generated in step one, which identifies the user.
once the user is logged in the user gets redirected in the browser to an endpoint where the code from step one is linked to the access token retrieved in this step.
the polling from step 2 now returns the access token to the (plugin) client.
The reason I need to poll for the access token is because I want to make a generic login process for all client.
In short, I want to know what the security risks are, given the steps above. Also I can not seem to find any information of keycloak that they want to implement such feature. Does anyone know if they want to implement this, since many other plugins do offer tis feature to authenticate outside the plugin with a popup window and retrieving the accesstoken by "polling" the server.
Thanks for the help.
Related
I am building a website using .net. The plan is to use the strava api to get activity data of the user.
Currently the user will need to accept this strava prompt every time he reloads my site:
I got the auth flow working but my question is how to keep the user logged in. If I only store the tokens on my server I won't recognize the user on reload (or I have to use separate authentication). However if I store the tokens on the client the user will be able to make requests to the strava api on behalf on my application.
I tried to add custom jwt authentication to my server but don't like the complexity this is adding. I want to avoid it if possible.
Which of these is the standard way of doing it? Or is there a different strategy I am not seeing?
I have a progressive web application that needs write-access to the Google Drive API for uploading data (media files) the user is creating (either online or offline) in the background while online. It does not really need a server (except for serving the required files, so a static server is sufficient), all of the work could be done on the web application client side.
Since uploading needs to happen on the background, whenever the user is online again (using a service worker and the background sync one-shot API), an access token is not enough for my need (the user can be offline/not use the web application for days) and a refresh token is not supposed to be stored on the web application client side, as far as I understand. Even if it were, I would still need the client secret, which means I have to use a server (or keep the secret within the web application client side, which is a no-no) in order to refresh the token.
It seems like the current ways of using the OAuth2 scheme are at odds with server-less progressive web applications, or I might be missing something. Progressive web applications are more like Chrome applications in this regard, I guess, but I have to supply a Chrome application ID in the Google API console for my application, which I do not (and do not intend to) have and Chrome applications use the Chrome identity API for getting the tokens, which I do not intend to use (and cannot).
I am currently using an actual Node.js server which takes care of the authorization step, keeps the access token and refresh token in a database and returns the existing or new access token to the client, whenever asked. The server is redundant here (and requires a privacy policy for this data which I really do not need to store), I want to do everything using client code, without continuously asking for authorization whenever I upload in the background.
Keeping the refresh token on the web application client side and just reaching out to the server for actually refreshing the access token (nothing must be stored in the server side except the client secret, which is fine), but like I mentioned, I understand the refresh token is not supposed to be kept on the web application side.
Is there a safe and secure way to implement this without a server (or with a server that only gets the refresh token and returns it to the client and refreshes the access token by getting the refresh token from the client)?
It's actually fairly simple, depending on the fine details of your use case.
An important factoid is that once a user has granted permission to your app, he will not have to re-grant it. So you don't need to "continuously asking for authorization whenever I upload in the background". However, the only constraint is that the user must be logged in to Google in order to obtain an Access Token. Normally this isn't an issue, but your app needs to deal with the scenario that a user has logged off from Google, and prompt for login.
All the details are here https://developers.google.com/identity/protocols/OAuth2UserAgent
I suggest avoid the Google JS library because (a) it has its own opinions about the UX, (b) wasn't written with PWAs in mind, (c) has issues on mobile, and (d) is closed source so when it breaks (as it does occasionally), your users are dead in the water until Google fixes it. The page above details the OAuth endpoints so you can easily use them directly. This has the side benefit that adding other cloud storage accounts (AWS, Azure, Drop, etc) is just a case of changing the endpoint URL.
The architecture I use in my PWA is to have my PWA prompt once (and once only) for authorization and then store the user's Gmail address in localStorage. I then have a
hidden iframe which polls once per hour for an Access Token, using the gmail address in a login_hint. This means the iframe is never required to present any UX. The only time UX is required is for the initial auth, which is of course unavoidable, and once per session if the user has logged out of Google.
The only other edge-case you might want to deal with is allowing the user to select between multiple Google accounts, say a personal account and a work domain account.
On a broader point, remember that Google didn't create the OAuth spec so there is little they can do to provide an alternative solution. At an abstract level, auth requires one of the user being present, or secure storage for a permanent token (eg on a server or within a secure store such as Android). Even if we invent OAuth 3, that will still be the case.
Is there way to let the user who installs a GitHub App generate a permanent installation access token which can be used by the app to authenticate and perform actions as that app?
I am wanting to create a simple GitHub App that will run on a CI server and comment on PRs with data from one of the tests.
As this app is being run by the user on their CI server there is no place to store the private key for the GitHub App that would usually be used to generate the access token as described here.
Ideally if the user could generate a permanent installation access token for the app they could securely provide that key to the app when it runs on the CI server so the app can communicate with the GitHub API and authenticate as the app.
I realize that the user could provide a user access token and the app could authenticate that way - but when the app comments it needs to show up as originating from the app, not the user (and I don't believe that would happen if the app authenticates with a user access token).
I think you might be confusing "GitHub Apps" with the more generic idea of tools that access the GitHub API. The Apps system a specific way to build hosted services for GitHub that has its own authentication model. Users can't run an App themselves as it is only designed around hosted/SaaS tooling. For things that someone would run themselves, you would need the end user to create a new user account on GitHub for the bot and then authenticate as it (either OAuth or personal access token, doesn't matter).
This is an old question, but in the interest of having the correct info here...
#osowskit's answer is correct in terms of mentioning you need to use JWT but not in terms of that has to be done using webhooks. There are indeed advantages of using Apps for access control - the GitHub App can be given specific access for only some repos. Now at least some CI systems (well at least Jenkins) support GitHub App access natively for some uses.
The basic flaw in the original request was the request of a permanent PAT associated with the App. This is not how they work. Instead you generate a Private Key for the App and it is this that should be stored in the CI secrets system. Now you do indeed need some sort of PAT to actually do the action - here to add the PR comment - it is just that you don't have a permanent one. Instead you generate temporary PATs each time you need to run - IIRC these PATs last for about an hour, so are useful for most single jobs but are to be generated each time and not stored as such.
Once you get the code, it is no big deal using the jwt tokens - it just involves a couple of extra REST calls.
Is there way to let the user who installs a GitHub App generate a permanent installation access token which can be used by the app to authenticate and perform actions as that app?
Maybe but it shouldn't be necessary. A GitHub App will only perform actions on data a user grants it access to. Any data modified on GitHub by the App will appear as an action 'performed' by the App.
Ideally if the user could generate a permanent installation access token for the app they could securely provide that key to the app when it runs on the CI server so the app can communicate with the GitHub API and authenticate as the app.
This shouldn't be necessary based on the information you've provided. Users grant access to a GitHub App to access specific resources and listen for specific events; a GitHub App needs a installation ID (or multiple installation IDs) to interact with GitHub data.
The good news is that for the CI workflow you outlined, GitHub would send the installation ID in the webhook payload - likely a push event.
I realize that the user could provide a user access token and the app could authenticate that way - but when the app comments it needs to show up as originating from the app, not the user (and I don't believe that would happen if the app authenticates with a user access token).
Generating a personal access token (PAT) isn't required and GitHub Apps were created to avoid creating service accounts or adding credentials to your CI environment.
Author your GitHub App to listen for webhook events.
On receiving an event, parse the payload for the installation id
Generate an installation access token by authenticating as an application after creating a JWT.
Use the installation access token generated above to modify data. Note that this token expires in an hour.
Profit!
Everything I'm reading shows that in order for an application to use onedrive, it has to do the oauth2 thing to get credentials. But what if you're a batch process and don't have a web interface for your users.
Google's API has a special type of account called a service account where once you set it up, you can control access to everything from that one account, no need to interact with users. Does such a thing exist for onedrive?
App-only authentication doesn't require the user be prompted for credentials but it also isn't supported in 100% of scenarios. For example, the APIs need a user principle for creating special folders and resolving a user's personal site. Also, it is only supported for OneDrive for Business, not Consumer. Consumer always requires the user be prompted for initial authentication.
Another option would be to spin up a web service of some sort that handles initial user authentication, ie. a sign up page. With that, you can retrieve a refresh token for offline authentication and store it for the user. Every authentication from then on can be done using the refresh tokens, which doesn't require a user prompt.
I finally found this. It's the same basic idea as google's service account, but I think it's harder to use. But at least the concept is supported.
http://blogs.msdn.com/b/exchangedev/archive/2015/01/21/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx
Basically, I have the following scenario and information:
We're using HTTPS.
We want to authenticate a user by user/pass when they first log in.
After they are authenticated, I want any future calls to OTHER services (not the login service) to use the username and some sort of session (in case the password changes in the middle of a session).
I want to make sure my sessions can timeout and control them in a way that if a user tries to call a service and they don't have a session they get an error (cause they haven't logged in). Not sure if there's a WCF built-in way to do sessions this way or if I'll have to do something customized with a database.
I think we want to use WSHttpBinding (not BasicHttpBinding), 90% sure on this.
I just can't seem to figure out how to do this. Often time's I'll find information on the client code doing client.ClientCredentials.UserName.UserName = username and client.ClientCredentials.UserName.Password = password. But, that just doesn't work because what is my server checking against? I'm trying to grab that info and validate it against a database of user/passes. I'm not looking to use Windows Authentication or that sort (because I don't care who is logged into the computer, just who is logging into the app).
You want to use a Secure Token Service (STS) to authenticate and get a Security Token (maybe SAML) back that identifies the user which can then be passed to your other services and they can just use the identity information to identify and authorize because they trust the STS has verified the user's identity up front.
This is a large subject to discuss, so I suggest searching for WCF STS and doing some more research, but that's definitely the direction I'd recommend going. If you're going to build your own STS implementation, I also recommend looking into using the Windows Identity Foundation (WIF) components to ease your development efforts.
Here's the download link for WIF v1.0 which is the latest version at the time of this answer.