I have a Java web application that uses Google OAuth for authentication (with this API : http://goo.gl/6wWyT3) and it works fine. However, I need a way to allow only users from a certain Google Apps for Education domain e.g mike#wdu.edu.ng to be able to gain access to the app using Google's OAuth. How do I go about this ??
send users off to Google with a parameter hd=<domain.com> in the authorization request (by modifying buildLoginUrl) to skip the account chooser screen and upon return, check that the claims returned from Google contain the hd claim with a value <domain.com> in getUserInfoJson to enforce the access requirement
Related
I would like to authenticate against KeyCloak using "Direct Access Grant": https://www.keycloak.org/docs/latest/server_admin/index.html#resource-owner-password-credentials-grant-direct-access-grants
I works like a charm when keycloak manages users and passwords on its own.
But, my scenario is different:
I would like keycloak to act a Broker to some external IDP. KeyCloak has identity brokering feature - but in only works in "Authorization Code flow" - redirecting user to external IDP login form.
I have mobile app and would like ot use "direct access grant" - so that app comunicates with keycloak to authenticate user - and keycloak, as a broker, authenticates this user (using openid-connect) in external IDP
How to achieve such scenario ? I know that it is not possible out of the box - but maybe somebody could advice how write an extension to keycloak do make this scenario possible ?
Whatever it is you are trying to achieve this way, it goes directly against what OAuth and OpenID Connect were designed for. The whole idea of using access tokens is to allow some relying party (such as a mobile app) to interact with a service on behalf of the user without ever getting to see the user's credentials (like a password).
Think of it like this. Let's say you have some app on your mobile phone. It can make use of certain services by Google. In order to do so it offers you to log in with Google and grant the app access. Now, would you want to do so by putting your Google email and password directly into the app? Of course not. That could give it complete control over your Google account, other apps and sites using your Google identity, possibly services that allow you to pay through your Google wallet... It would be insane to simply hand some phone app your Google login.
So instead with OAuth2 or OpenID Connect you can use the authorization code flow or implicit flow to have the user redirected to the identity provider (Google in our example) where they will complete their login process, and then the identity provider redirects back to the app or a site with an authorization code that can be exchanged for tokens or, for the implicit flow, the tokens themselves.
Now, when it's your own app and your own identity provider (like Keycloak) which are under your control it doesn't really matter. You can use a direct grant to simply have the user input their username and password into the app because you know it's not trying to steal user credentials to maliciously use your service. They're both under your control. In that case OAuth or OIDC are a bit overkill, but you could have separate clients for direct grants (your own app) and authorization code flows (third-party apps using your service). When you want to use Keycloak identity brokering, however, an external identity provider like Google or Facebook is not going to offer a direct grant and invite apps to steal their user's credentials. So you won't be able to interact with them this way.
Depending on what you're trying to achieve you may find some use in the token exchange process. If however the idea is that you want your user to log in with their external identity provider credentials, in your app, without a redirect... Don't.
This is a real use case, unfortunately Keycloak doesn't have a direct way of solving this issue. AWS's "IAM Roles for Service Account" feature works based on token exchange with direct access grant using external IDP. I found this discussion on how to workaround this lack of support in Keycloak but not sure if it solves all the usecases - https://lists.jboss.org/pipermail/keycloak-user/2017-January/009272.html
Do you stick with Direct Access Grant as a method of user authentication in your mobile app? In my opinion, you need to use Authorization Code Flow when the IDP is a third party service as it won't provide an API to authenticate users, and even with your own (first party) IDP, it'd be better to use Authorization Code Flow as stated in OAuth 2.0 Security Best Current Practice section 2.4.
To implement Authorization Code Flow in mobile apps, you will need to use in-app browser tab to show login screen provided by the IDP. Please refer to RFC 8252: OAuth 2.0 for Mobile and Native Apps for details.
I am looking for a Java API to query Instagram images based on a given coordinate or bounding box. I will appreciate if someone can tell me if there is any such JAVA API exists?
TIA
You could do this by first searching for Instagram locations by geo coordinates using their /locations/search endpoint, and then pull the medias for each searched location using endpoint /locations/{location-id}/media/recent.
All Instagram APIs require authentication which means you would have to go through the process of creating an Instagram App and authorizing the app to access your account to get an Auth token. More details are available at https://www.instagram.com/developer/
The Java API 'jInstagram' mentioned by #Thanos is decent one to start with but it is not actively maintained and you still need all the App creation and authentication processes anyway. If you are doing serious development, it worth to write your Java program to access the Instagram endpoints directly. You can use Scrible to negotiate the OAuth process.
Background
I believe the recommended way to access Google services from Android is to use the Google APIs Client Library for Java (for some services play services is recommeneded too).
If you want to access your user's account, you use oauth2 to authenticate the user, but things seem less clear if you want to access your own services (eg. I want to access Google Cloud Storage belonging to my app engine project).
The problem with service accounts
What I see a lot of here is using service accounts, and I've used them server-side and found them to be a comparatively simple solution, but this requires you to deploy your private key so I don't think this could be right for public Android apps.
The solution: Public API access
If you go to the 'credentials' page of the cloud console:
https://console.developers.google.com/project/[your_project]/apiui/credential
it seems pretty clear that they expect you to use a 'public API access key' for the situation I'm describing. It appears that this is not OAUTH based.
I assume that I will still use the type 'GoogleCredential' for this, but in the documentation for the credential builder I don't see how to do this. The set client functions appear to relate to the oauth2 access (which uses client ID/secret).
The Question
How do I use the 'public API access' key to access Google services from an Android app.
Or, if I'm wrong about service accounts - and they really are the recommended solution, then please show me some evidence of this because it certainly apppears to me that they are not the right solution for publicly distributed apps.
The good news is that it's very much easier. You can either use a Service Account (ie. a brand new account dedicated to your app) or a regular account.
For a service account you embed the key in your app, for a regular account you embed a refresh token in your app. In both cases, be aware of the security risk and use the minimal scope necessary.
You can get a refresh token without writing any code by following the steps in How do I authorise an app (web or installed) without user intervention? (canonical ?)
Am I correct in thinking that the goodness of Cloud Endpoints comes with the following limitations:
The REST Api cannot be deployed to a custom domain (it'll remain on appspot.com).
The only authentication supported is OAuth against Google accounts.
Corollary: it isn't currently possible to create a user login/session-tracking mechanism that is Google-accounts-agnostic (e.g., with email as username and a password).
Is there any plan to do away with these limitations and if so, what is the ETA?
Taking these item by item:
Currently, yes this is still the case. Keep in mind, our initial release is targeted at a same-party use-case, where the domain you're serving from basically doesn't matter (it's not user/developer-facing). If you want to use your API to drive a website, you can use your custom domain to have your user-facing content, and still make requests to your appspot domain using CORS. If you're building a mobile app, no one sees the domain at all.
Built-in support (i.e. using the User object) is limited to Google accounts, but you're free to build your own authentication scheme by checking the OAuth headers (or email/password if you must...)
(From the comments, regarding GA status). Endpoints is now GA.
(From the comments, regarding public APIs). Your APIs must be public, but you can limit the clients that can make requests. If you want to make a secret API, i.e. the existence of the API must itself be protected, that's not currently supported. I'd be curious to hear how popular a request this is, but I suspect it's not a blocker for most people.
I want to know if he given user is admin of google apps domain or not. getting a list of domain admins will also do.
userService.isUserAdmin() gives user admin of google app engine which I don't want.I want to check if user is admin of google Apps domain.
I found that we can use read only access to provisioning api for this,but I could not get any detailed tutorial or code.I also need the authentication for read only access using oAuth 2 only.
Read-only Provisioning API access is only available to Google Apps Marketplace applications using two-legged OAuth 1.0. If you're not developing a Marketplace App, you'll need to get the full read-write users scope.
A java example is available at:
https://developers.google.com/google-apps/provisioning/#retrieving_user_accounts