Graph REST API -- Reading Email (Java) -- NoPermissionsInAccessToken - java

The objective that I am after is that I would like to obtain an email from Outlook 365 without any human interaction.
So I am trying to use MS Graph REST API and Java.
To obtain the access token, I use:
resource=https://graph.microsoft.com
response = Unirest.post(
String.format("https://login.microsoftonline.com/%s/oauth2/token",
auth.getProperty("tenant_id")))
.header("Content-Type", "application/x-www-form-urlencoded")
.field("grant_type", "client_credentials")
.field("resource", auth.getProperty("resource"))
.field("client_id", auth.getProperty("app_id"))
.field("client_secret", auth.getProperty("app_secret"))
.asString();
which returns a string, which is parsed into a JSON, and passed into:
jsonNode = Unirest.get(
String.format("https://graph.microsoft.com/v1.0/users/%s/mailFolders",
prop.getProperty("user_email")))
.header("Accept", "application/json")
.header("Authorization", json.get("token_type") + " " + json.get("access_token"))
.asString();
I am getting the error with the message, "The token contains no permissions, or permissions can not be understood."
I do not have admin access to Azure AD, but I do have access to the user_mail inbox, which I can access through https://outlook.office365.com/mail/inbox.
I feel like I went off on a tangent, but not sure what else I can do.
Does anyone know what needs to be done to allow me to receive emails thru MS-Graph API? Or a better way of doing this?
Appreciate all the help I can get.

You would need to register an application in Azure AD in your tenant and provide the permissions that a user would require access to.
As you are trying to access
v1.0/users/%s/mailFolders
Looks like you want to use applicatoin permissions (not delegated permissions). So you would need to use Mail.ReadWrite application permissions which would require admin consent too.
You can use this tutorial to get an idea of how to connect Microsoft Graph using JAVA too https://learn.microsoft.com/en-us/graph/tutorials/java

Related

How does one get the id_token using Google's OAuth2 Java Api?

I'm trying to get my head around the OAuth2 Java library that Google provides.
I have everything I need to make the request to Google's token endpoint manually using Springs built-in WebClient. However, this is very verbose and feels like re-inventing the wheel. It got me thinking that there must be a way to get this data using the classes provided by the library. Right?
Currently I am using the com.google.auth.oauth2.UserAuthorizer class to build up a request for the exchange of information.
val userCredentials: UserCredentials = UserAuthorizer.newBuilder()
.setClientId(googleOauthConfig.clientId)
.setTokenStore(tokenStore)
.setScopes(googleOauthConfig.scopes)
.setTokenServerUri(URI.create("https://oauth2.googleapis.com/token"))
.setCallbackUri(redirectUri)
.build()
.getCredentialsFromCode(authorizationCode, redirectUri)
The internals of getCredentialsFromCode() parses the response and it contains all the tokens. Including the id_token but, it gets discarded when constructing the UserCredentials object further down.
return UserCredentials.newBuilder()
.setClientId(clientId.getClientId())
.setClientSecret(clientId.getClientSecret())
.setRefreshToken(refreshToken)
.setAccessToken(accessToken)
.setHttpTransportFactory(transportFactory)
.setTokenServerUri(tokenServerUri)
.build(); // no mention of id_token
Regardless, I want to get this value so I can know basic information about the user such as their name, birthday and email address from a single request.
There does exist a method called idTokenWithAudience() which returns a Google ID Token from the refresh token response. If I call this, I get a token back that doesn't contain all the data that was available in the identically named id_token mentioned earlier making it a no-go either.
You can use IdTokenCredentials to access the ID token like so:
var credentials = UserCredentials.newBuilder()
.setClientId("...")
.setClientSecret("...")
.setRefreshToken("...")
.build()
.createScoped("openid email");
var idToken = IdTokenCredentials
.newBuilder()
.setIdTokenProvider((IdTokenProvider)credentials)
.build();
idToken.refresh();
System.out.println(idToken.getIdToken().getTokenValue());

Graph request as User from backend Azure Ad

I've recently faced a problem.
My frontend use Oauth2 to authenticate my user on Azure (Organization). This giives me multiple information containing idToken and accessToken.
My Backend uses AADResourceServerWebSecurityConfigurerAdapter to authenticate the user thanks to the idToken put in the Authorization Bearer header from the frontend.
Unitil here everything works well. I can get the connected user with this:
public static String getConnectedUserEmail() {
return (String) ((AADOAuth2AuthenticatedPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getAttributes().get("preferred_username");
}
I use my backend app credentials to contact the graph api on behalf of the API itself.
Though, following Azure Ad documentation, I cannot query group/calendar on behalf of the API, I have to do it on behalf of the user.
To respect SOLID principles, I want to make the request from the backend, but on behalf of the user.
I cannot find any information about that.
So here is my final question: How can I make a graph API request in my backend on the behalf of the user?
Knowing that trying to use the tokenValue (idToken) of the user or the accessToken value returns invalid credentials from Microsoft.
You requested GET /groups/{id}/calendar to get group calendar as you said.
You can call Graph API with the access token using on-behalf-of flow, see here.
There is a sample using the On-Behalf-Of flow: https://github.com/Azure-Samples/ms-identity-java-webapi
Note: Make sure the following delegated permission is added.

AccessTokens returned for Active Directory are different between sample projects

I've been experimenting with Azure Active Directory access for Java using two sample projects:
1) https://github.com/AzureAD/azure-activedirectory-library-for-java which builds a stand-alone war using OAuth tokens for security, and
2) https://github.com/Microsoft/azure-spring-boot/tree/master/azure-spring-boot-samples/azure-active-directory-spring-boot-backend-sample for spring-boot embeded containers
I've come across quite a difference in the way the APIs can be used, that I can't understand.
In both cases, I get an OAuth token for AD by logging in with my Azure credentials.
In the Http response, I get an authorizationCode of the form:
AQABAAIAAAD.....
Then using the following URL as an authContext:
https://login.microsoftonline.com/{tenantId}
I get a AuthenticationResult by making the following call:
Future<AuthenticationResult> future = authContext.acquireTokenByAuthorizationCode(authorizationCode, redirectUri, credential, null);
in the Adal4j project (1), the AuthenticationResult's AccessToken is of the form:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6I...
Which I can use as a Bearer token in an HTTP call to retrieve the user's profile picture via https://graph.windows.net/myorganization/me/thumbnailPhoto?api-version=1.6
whereas in the SpringBoot AD example, the AccessToken returned from exactly the same call is of the form:
AQABAAAAAADXzZ3ifr-GRbDT....
and If I use that in exactly the same way to try to retrieve the user's profile pic, I get a 401 Unauthorized response
What's the reason for the difference in the form and use of these AccessTokens?
What's the reason for the difference in the form and use of these AccessTokens?
I assume that you got the access token is authorization_code not the bearer token.
As Rohit Saigal mentioned that you could use JWT.IO or JWT.MS to check that.
If we want to get the access token for Azure AD graph we could use the follow code to do that.
public String index(Model model, OAuth2AuthenticationToken authentication) {
...
DefaultOidcUser user = (DefaultOidcUser)authentication.getPrincipal();
String accessToken = user.getIdToken().getTokenValue();
...
}
Then we could use the access token to access the Azure AD graph api if you have assiged corrosponding permission.

posting form data with javaws in play

Hy,
I want to do calls to a different rest api from my play application. I'm using the javaws included library.
The specific call requires that I send form data. However I have no idea how I can send the correct data along with my request.
As far as I can see the library only supports sending url-encoded-form-data.
Does anyone know how I can send form-data along with my request like a normal website doing a form submission?
At the moment I have this:
Promise<WSResponse> promise = WS.url("http://localhost:"+port+"/login").setContentType("multipart/form-data").post("emailAddress=" + email +"&password=" + password);
Thanks,
Use application/x-www-form-urlencoded instead of multipart/form-data.
Promise<WSResponse> promise = WS.url("http://localhost:"+port+"/login")
.setContentType("application/x-www-form-urlencoded")
.post("emailAddress=" + email +"&password=" + password);

how to get access token sharepoint 2013 in java

This is the sample given by microsoft.How I will get access token and put into that respective java code to create folder in sharepoint server location.Please provide some idea.
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "/_api/web/lists");
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/json;odata=verbose";
endpointRequest.Headers.Add("Authorization", "Bearer " + accessToken);
HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse();
You can take a look of this project i've created. It provides you most common operations (sill working on it to create a full implementation of the rest api). It has a helper class where you can see the logic behind how to get a sharepoint auth token to call rest api actions.
https://github.com/kikovalle/PLGSharepointRestAPI-java
You can look at JShare . It is Java API for Microsoft SharePoint Server and SharePoint Online (Office 365). The API cares about authentication and access token and you do not need to implement it yourself.

Categories

Resources