Microsoft Graph Authentication - Delegated permission - java

I am able to access resources from Microsoft Graph using Get access without user. However, this method does not allow me to access resources which require delegated permissions.
I also tried to use the Get access on behalf of a user method, but it will require my user to sign in through a webpage, which is not desired in my scenario.
Is it possible to generate an authorization code with a long life time (possibly over a year) and use that code to request an access token, which can then be used to get resources that require delegated permissions?
Note: I know generating an authorization code with such a long life time is not a good idea, but this code will be used by the back-end program to access resources and not the user. So I do not want the user sign in page to pop up. Looking to implement this in Java.
Thanks!

In order to use delegated permission, the end user needs to sign in interactively through an OAuth2.0 flow.
Now, you can use a user's creds with the Resource Owner Credentials Flow which is simply posting the username/password to Azure AD and getting tokens back. This path is not recommended as it's brittle (For example, MFA will not work) and requires your app to manage the user's credentials.
Your best bet is to create some kind of sign in experience for your users that allows them to sign in and consent to your application. Refresh tokens in Azure AD have a lifetime of until-revoked meaning they can last as long as a year if not longer. The bottleneck you'll hit is the end user's password expiring which would lead them to need to sign in again.
For some help with this, Azure AD has an ADAL4j library you can use. I've also written a small Spring MVC Java code sample for the Azure AD v2.0 endpoint (Microsoft Accounts + Azure AD Accounts) that uses a 3rd party library.

Related

Which would be the right way to Sign-In on my own server from an native Android app?

I have a website and my own server and database, I also have an native Android app. I need to allow users to be able to sign-in with their account from the website inside the app in order to sync information and other things they need to use. I've been stuck for a couple of days trying to figure out how to do that. I've found a lot of content regarding OAuth and AppAuth but they are focused on using an OAuth API to the job. Back on my server, I use Hybridauth for social login, but users can also register directly on the site. How would be the proper way to allow my users to sign-in to their website account through the Android app?
You're overthinking it. OAuth isn't meant for users to log in, it's meant to enable external services to access data on behalf of a user.
To make a user log in? Create a POST endpoint on your webservice named login. It should take two parameters- username and password. The body of the login service should salt and hash the password, then check if the hash equals the hash stored in the db for the same user. If so, you're logged in and you return a success packet with a unique token to authenticate you for later requests. If not, you return a failure. The Android app would ask the user for their data, then send a request to the endpoint. On success it saves the token and sends it in all future requests to authenticate yourself, either as a parameter or as a header.
This is of course the simplest possible version. More advanced features would include expiring of login tokens, refresh tokens, possible lockout if you have too many bad requests, etc. But the above is the basic idea. Although really I'd look for an open source solution you can take, as there's quite a lot of complexity when you get into all the stuff mentioned above, and its a place where a mistake that leads to a vulnerability is probably the most dangerous.

Designing authentication in android app through JWT API

Background
We've developed a CMS in ASP.Net Core 2.2 a few years ago for company internal day-to-day stuff. It holds several hundreds of users and I'm considering adding an android app to it. The android app should mainly serve as a front end to existing logic in the ASP.Net controllers. The benefits of the Android app I expect to have are:
Better UX
User not having to type the password for each session (the ASP.Net page logs them out after 20 or 30 minutes of inactivity)
Push notifications etc.
Existing infrastructure
The CMS has already an API (JWT) which is used by several backend services and could easily be expanded to be used by every user through the android app. Unfortunately I'm not a professional developer in general and are quite new to Java especially, so please bare some patience with me as I'm asking for a general advise of how to handle the authentication in the android app (Java).
I read about curity.id and stuff like this, but IMO this would be kind of overkill to the whole project and would also require major changes to the already working fine ASP.Net website.
Now my question is whether the following would be an acceptable practice to do:
When the user opens the app for the first time, I ask him for his username and password (and optionally 2nd factor).
I make an http request to the API of the CMS in order to authenticate the user and get back the JWT token on successful authentication.
The JWT token gets stored in some way (e.g. SQLite DB) and is being used for subsequent requests being made to the API.
Since the the lifetime of the JWT token is also limited to a few hours and the goal is to keep the app running without prompting the user for his credentials all the time, I need to store the password also in some way in the app or a DB on the android device. This is actually the part which confuses me the most and I have no clue how I would store the password in a safe way, so it may be used again for authentication requests down the road. (I'm aware that if the user uses 2nd factor there is no way around but to ask for the 2nd factor every time the token expires or to exclude the device or so, but this should not be within the scope of this question)
So I would be grateful to get some judgements about this approach, if it is acceptable in general and what would be the best way to do about point #4.
Thanks a lot
Do not store password
If store (and frequently send) passwords you defeat the entire purpose of a token. The token itself exists as a disposable means to substitute the primary authentication (yet is cryptographically sufficiently strong to replace it without reducing system security).
SIMPLE: Use a long token
Create a new authentication API (or add some parameters to the existing one) to enable the mobile APP to require a long-lasting token (for example 6 months). If you then store this token in the SecureStorage of the device you can be quite confident it can not be extracted from there.
Remember that with this solution, you lose control over the authentication. This is not the best practice but is the easiest solution to adopt in the case of existing JWT infrastructures that use only one token.
RECCOMENDED: Create a renew token system
Once you issued a token you cannot revoke it. Hence the main issue introduced by the 'long token' solution is that if a device gets lost it can not be de-authenticated. This can be solved by a renew token:
You create an authentication API that after the confirmed authentication it creates a unique sessionId, stores it in the DB, and issues a special token that contains the sessionId among other information. This is called the renew token. This special token can be used only for the exchange API
You then create an exchange API, that expects a renew token in exchange for a normal token (that can have the same properties your current token has). This API will always check if the sessionId present in the renew token is still marked as active in the DB otherwise will not issue the normal token.
This approach allows you to have very long expiring tokens but still have control to remotely log out the app (by masking the sessionId as deactivated in the DB) and even monitor how frequently the app is used.

How to authenticate a regular Yammer user automatically from a Java program in a SSO enabled network?

I am trying to write an external Java application that collects posts from Yammer using its REST API and I am experiencing issues with the authentication part.
To extract the data I want a regular yammer user (I do not have admin permissions) to be authenticated automatically from the Java application without any prompts. Does anyone know whether this is feasible and moreover - whether it is feasible in a SSO-enabled network? If yes, what kind of authentication libraries should I use? Is there some documentation/sample code snippet describing how to log in to Yammer via Java and not via a Yammer app?
I've seen that there are similar questions here, but are still unanswered.
I will appreciate any know-how on the topic!
Thanks!
The only way to authenticate to yammer without any prompt is to pass a persistent oauth token as an authorization bearer token in your request header. The caveat is, users cannot be dynamic.
It is pretty simple to generate the access token. For that you need client Id and client Secret.Steps are available in https://developer.yammer.com/v1.0/docs/test-token.
But if you don't have that information, go to https://developer.yammer.com and log on with the credentials and try some Rest API(Try It Out section) in the developer site. Copy the Authorization code from the Request Headers and you can use it in your application.
Note: Access Tokens for users are long lived, expiring when users are suspended, change their Yammer password (non-SSO networks only), or users manually revoke them

How to secure Android App that pulls data from OAuth protected resource

My company is building a RESTful API that will return moderately sensitive information (i.e. financial information, but not account numbers). I have control over the RESTful API code/server and also am building the Android app. I've setup the API to use OAuth 2 with authorization code grant flow (with client ID and secret), and I auto-approve users without them having to approve the client since we own both client and provider. We use CAS for SSO and I am using this for the Authorization server as part of the OAuth 2 process when the user logs in to retrieve the token.
I am contemplating various ways to secure the data on the Android app. I've concluded that storing the client id and secret on the device is definitely not going to happen, but am thinking that storing the auth token might work, since it is only risk to the individual user (and really only if they happen to have a rooted phone).
Here are two options I have thought of. They both require me to have a sort of proxy server that is CAS protected, does the dance with the API server, and returns the auth token. This gets rid of the need for storing the client id and secret in the app code.
Here are what I've come up with:
1) Require the user to enter their password to access data each time they startup the App. This is definitely the most foolproof method. If this were done, I'd probably want to save the userID for convenience, but in that case couldn't use the CAS login (since it's web-based). I might be able to use a headless browser on the backend to log the user into CAS and retrieve the token based on what they enter in the Android form, but this seems hacky. Saving the userID is similar to what the Chase app does (if you happen to use this one) - it saves the userID but not your password between sessions.
2) Store the auth token on the Android device. This is a little less secure, but almost foolproof. When the user starts the app for the first time, open the webpage to the CAS login of the proxy server that returns the token (similar to https://developers.google.com/accounts/docs/MobileApps). After the user logs in and the token is returned to the app, encrypt it and store it private to the application. Also, use ProGuard to obfuscate the code, making the encryption algorithm more difficult to reverse engineer. I could also work in a token refresh, but I think this would be more of a false sense of security.
3) Don't use CAS but come up with another way to get an auth token for the service.
Any advice of how others have implemented similar scenarios (if it's been done)?
Thanks.
Well the reason why standards like OAuth are developed is that not everyone has to rethink the same attack vectors again and again. So most often it is your best choice to stick to something already available instead of baking your own thing.
The first problem with clients that are not capable of secretly storing data is that the user's data could be accessed by some attacker. As it is technically not possible to prevent this (code obfuscation won't help you against an expert attacker), the access token in OAuth 2 typically expires after short time and doesn't give an attacker full access (bounded by scope). Certainly you shouldn't store any refresh token on such a device.
The second problem is client impersonation. An attacker could steal your client secret and access your API in his own (maybe malicious) app. The user would still have to login there himself. The OAuth draft there requires the server to do everything it can to prevent this, but it is really hard.
The authorization server MUST authenticate the client whenever possible. If the authorization server cannot authenticate the client due to the client's nature, the authorization server MUST require the registration of any redirection URI used for receiving authorization responses, and SHOULD utilize other means to protect resource owners from such potentially malicious clients. For example, the authorization server can engage the resource owner to assist in identifying the client and its origin.
I think Google are the first to try another approach to authenticate a client on such devices, by checking the signature of the application, but they are not yet ready for prime time. If you want more insight into that approach, see my answer here.
For now, your best bet is to stay on the OAuth way, i.e. having the access token, client ID and client secrect (when using the authorization code grant flow) on the device, and configure your server to do additional checks. If you feel more secure obfuscating these, just do it, but always think of it as if these values were publicly available.

Is it compulsory to register our web application on Google Apps before implementing OAuth?

I am developing a Java application that needs to access personal account Google Data of a user. The development is currently in netbeans on my localhost. I am implementing 3-legged OAuth. And while sending Grant request, it sends me Unauthorized Request Token and then redirects to Callback URL.
While trying to access Access Token, it gives me Error "Error Getting HTTP Response". Now, as per it given in Google Documentation, it is given that "If the application is not registered, Google uses the oauth_callback URL, if set; if it is not set, Google uses the string "anonymous"." Does it mean that I must register my application on Google Apps Engine before granting authorization & accessing request ? Please Help.
For reference : OAuth for Web Applications, OAuth in the Google Data Protocol Client Libraries
Based on your question, it's probably not the registration piece that's causing you trouble. It sounds like you just haven't implemented OAuth correctly — not that doing so is easy. The OAuth process is roughly as follows:
Get a request token. You must pass in a bunch of stuff that declares what kind of stuff you want access to and where you want Google to send the user when they're done granting you access to that data. This is where you pass in your consumer key, which you get by registering. The consumer key will be the string anonymous if you are developing an installed application (i.e., mobile app, desktop app, etc). This is a work-around; the alternative would be to embed your client secret or RSA private key within the application itself, which is a very, very bad idea. If you use 'anonymous', you should absolutely be setting the xoauth_displayname parameter. (Actually, everyone should set this parameter, but it's especially important if you're using anonymous.)
Once you have a request token, you then redirect the user to the special authorization endpoint, passing along the request token key in the query string. Assuming the user grants access, Google will redirect the user back to the callback URL that you associated with your request token. The request token is now authorized, but it can't be used directly just yet.
Once the request token is authorized, you can exchange it for an access token key/secret pair. The access token key/secret can then be used to sign requests for protected resources, such as the private data in the API you're trying to access.
For web applications, registering is almost always a good idea. It makes it much easier for users to manage their access tokens and revoke them if your application misbehaves or if they don't want you to have access anymore. If you don't register, your application will probably show up as a fairly scary-looking 'anonymous' in that list. It's really only installed applications that you wouldn't want to register for. You probably also want to register for an API key. An API key will dramatically increase your rate limit and it will also allow Google to get in touch with you if your application starts to malfunction.
I'd link to the OAuth docs, but you've already found them. Hope my explanation helps!
If you're developing on your local machine, you'll continue to get the same result as above.
For more interesting tests, then yes, you'll have to register your app and push it to the app engine.
Google will check if the domainname of the return-url is registered. You could also modify your dns/host-file to point the domain-name you're using to localhost.

Categories