I successfully retrieved a Microsoft Graph token with clientCredentials, but when I try to query the getActivitiesByInterval route (for a SharePoint site) I am receiving an HTTP 500 :
"code": "generalException",
"message": "The remote server returned an error: (500) Internal Server Error."
The application I registered has the following rights (Application) on Microsoft Graph (Files.Read.All, Files.ReadWrite.All, Sites.Read.All, Sites.ReadWrite.All, User.Read.All).
If I do exactly the same query with a token retrieved from graph explorer I received an HTTP 200 with the content I ask for.
The token I am using seems correct as I can retrieve the users on the Microsoft Graph without having an HTTP 500.
The code I am using to do the request is the following (it's an Azure Function with a Microsoft Graph binding to get the token):
[FunctionName("SharepointSitesViews")]
public static async Task Run([TimerTrigger("0 */5 * * * *", RunOnStartup = true)]TimerInfo myTimer,
[Token(Identity = TokenIdentityMode.ClientCredentials, IdentityProvider ="AAD", Resource = "https://graph.microsoft.com")] string graphToken,
ILogger log)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
var response = await client.GetAsync("https://graph.microsoft.com/beta/sites/****MySiteId*****/getActivitiesByInterval?startDateTime=2018-09-12T09:59:19.817Z&endDateTime=2018-12-11T00:00:00.000Z&interval=day");
var me = await response.Content.ReadAsStringAsync();
}
The same code with the url "https://graph.microsoft.com/v1.0/users" returns a 200.
I have also reproduce the same 500 error using postman :
GET /beta/sites/****MySiteId****/getActivitiesByInterval?startDateTime=2018-09-12T09:59:19.817Z& endDateTime=2018-12-11T00:00:00.000Z& interval=day HTTP/1.1
Host: graph.microsoft.com
Authorization: Bearer *****myToken****
cache-control: no-cache
Related
I have created a standalone netbeans java 8.0 application which uses EWS to connect to Office 365 mailbox. I have registered the same in the Azure Directory.
Currently using basic authentication ,I can download the mails from the Office 365 mailbox and check the attachements. But the momment i change it to xoauth method using access token i get above mentioned error (The remote server returned an error: (421)). Can you please help me out with this.
I have used below code.
IClientCredential credential = ClientCredentialFactory.createFromSecret(CLIENT_SECRET);
ConfidentialClientApplication app = ConfidentialClientApplication
.builder(PUBLIC_CLIENT_ID, credential)
.authority(AUTHORITY)
.build();
Set<String> scopes = new HashSet<String>();
scopes.add("api://"+PUBLIC_CLIENT_ID"/.default");
ClientCredentialParameters clientCredentialParameters = ClientCredentialParameters.builder(scopes).build();
CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParameters);
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.setUrl(new URI("https://outlook.office365.com/EWS/exchange.asmx"));
BearerAccessToken bat = new BearerAccessToken(future.get().accessToken());
ExchangeCredentials credentials = new TokenCredentials(bat.getValue());
EnumSet<TraceFlags> es = EnumSet.of(TraceFlags.EwsRequest, TraceFlags.EwsRequestHttpHeaders, TraceFlags.EwsResponse, TraceFlags.EwsResponseHttpHeaders,TraceFlags.DebugMessage);
service.setCredentials(credentials);
service.setTraceEnabled(true);
service.setTraceFlags(es);
FindItemsResults findResults = service.findItems(WellKnownFolderName.Inbox, itemview);
The last last step above give me the error.
I am new to this msal4j and EWS . Can you please help me out with this. I need to access a office 365 mailbox for example: abc#abc.biz
If your using Service principal authentication (client credentials flow) then you also need to use Impersonation in EWS. So in your code you need something like
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "abc#abc.biz");
EWS Request:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"><soap:Header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa="http://www.w3.org/2005/08/addressing"><t:RequestServerVersion Version="Exchange2010"></t:RequestServerVersion><t:ExchangeImpersonation><t:ConnectingSID><t:SmtpAddress>lsrtestingmbx01#neustar.biz</t:SmtpAddress></t:ConnectingSID></t:ExchangeImpersonation><wsa:Action soap:mustUnderstand='1'>http://schemas.microsoft.com/exchange/services/2006/messages/FindFolder</wsa:Action><wsa:ReplyTo><wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address></wsa:ReplyTo><wsa:To soap:mustUnderstand='1'>https://outlook.office365.com/EWS/Exchange.asmx/wssecurity</wsa:To><wsse:Security soap:mustUnderstand='1'> nulleyJ0eXAiOiJKV1QiLCJub25jZSI6InUwc05rV2hLTjNrdXo0UzFCWWtKQzFwckxZYlZ6QWxFTHNXWEloSTBFSkkiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiJodHRwczovL291dGxvb2sub2ZmaWNlMzY1LmNvbSIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzczYTJiYmMxLWYzMDctNDdjNC04Zjk0LTVmMzc5YzY4YmMzMC8iLCJpYXQiOjE2MjQ2MDQyMjYsIm5iZiI6MTYyNDYwNDIyNiwiZXhwIjoxNjI0NjA4MTI2LCJhaW8iOiJFMlpnWUdncmNyWHBYUlo1YlJmRFdVTlhJU05WQUE9PSIsImFwcF9kaXNwbGF5bmFtZSI6IklNQVBPQVVUSFRlc3RBcHAiLCJhcHBpZCI6IjRmMmUwMjJjLTljOTEtNGZiMy04YTQzLWE1NmIwNTU0ODQzYyIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzczYTJiYmMxLWYzMDctNDdjNC04Zjk0LTVmMzc5YzY4YmMzMC8iLCJvaWQiOiJjMWFkYjYxMC02ZmQ1LTQxMjUtODJjYy1jYjUwNGRmMDE1NjgiLCJyaCI6IjAuQVM0QXdidWljd2Z6eEVlUGxGODNuR2k4TUN3Q0xrLVJuTE5QaWtPbGF3VlVoRHd1QUFBLiIsInNpZCI6IjFhYzQ3NWRiLWNmZGItNDQzNy1hZmIxLWQ4NTY2NmJmOTJlOSIsInN1YiI6ImMxYWRiNjEwLTZmZDUtNDEyNS04MmNjLWNiNTA0ZGYwMTU2OCIsInRpZCI6IjczYTJiYmMxLWYzMDctNDdjNC04Zjk0LTVmMzc5YzY4YmMzMCIsInV0aSI6IkZVUkUwQmNrdGt1SDVMSXVXckNSQUEiLCJ2ZXIiOiIxLjAiLCJ3aWRzIjpbIjA5OTdhMWQwLTBkMWQtNGFjYi1iNDA4LWQ1Y2E3MzEyMWU5MCJdfQ.G35t65b5V0MBXhPpXADZNKZlnqGpeb5T7iu4jIAnciCchkYhfurlSztTwf_M1DT9QgVymI9fy1RtLwZ5Xr4qXRtIAywFW9N5HJHzhC05-4612ORkVF7G7X0f_NIg057k1dED2qO-xpXU52dYgZFWa83t5g46Nj_DaB8Yci2vvwu4CjLhZwQ3cQOCkYK2Bq2AFJNQ68e50tOx6nueZruIlIMADoWBXGpLF9L1aVibTg7dloumtyuh1IoTtWzZrCEMt6tW_-H5YxFccB04NzCpi7Tg1Ju1PDeqLNRx17-EE1LZM0wisqke4FOf_OLjmzm3lxJCvLc-jLGts_ZFDrgP4g</wsse:Security></soap:Header><soap:Body><m:FindFolder Traversal="Shallow"><m:FolderShape><t:BaseShape>AllProperties</t:BaseShape></m:FolderShape><m:IndexedPageFolderView MaxEntriesReturned="10" Offset="0" BasePoint="Beginning"></m:IndexedPageFolderView><m:ParentFolderIds><t:DistinguishedFolderId Id="inbox"></t:DistinguishedFolderId></m:ParentFolderIds></m:FindFolder></soap:Body></soap:Envelope>
I am now getting below HTTP Header:
TRACE FLAG:EwsResponseHttpHeaders VALUE:
401 null
X-Proxy-BackendServerStatus : 401
Server : Microsoft-IIS/10.0
X-Proxy-RoutingCorrectness : 1
WWW-Authenticate : Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trusted_issuers="00000001-0000-0000-c000-000000000000#*", token_types="app_asserted_user_v1 service_asserted_app_v1", authorization_uri="https://login.windows.net/common/oauth2/authorize", error="invalid_token",Basic Realm=""
X-CalculatedBETarget : DM5PR1701MB1900.NAMPRD17.PROD.OUTLOOK.COM
request-id : e64c6048-3827-e102-de0b-8e25f54c83c4
X-RUM-Validated : 1
X-FEProxyInfo : DM5PR17CA0062.NAMPRD17.PROD.OUTLOOK.COM
Date : Mon, 28 Jun 2021 06:09:17 GMT
x-ms-diagnostics : 2000008;reason="The token contains no permissions, or permissions can not be understood.";error_category="invalid_grant"
X-CalculatedFETarget : DM5PR17CU003.internal.outlook.com
X-BEServer : DM5PR1701MB1900
X-BackEndHttpStatus : 401
X-DiagInfo : DM5PR1701MB1900
Set-Cookie : exchangecookie=4b4d794dbe6c41a89fba4e5b34fb9d66; expires=Tue, 28-Jun-2022 06:09:18 GMT; path=/; secure; HttpOnly
X-BeSku : Gen9
X-FEServer : BL0PR02CA0136
Content-Length : 0
X-Powered-By : ASP.NET
Instead of this:
service.setCredentials(credentials);
Try this:
service.getHttpHeaders().put("Authorization", "Bearer " + bat.getValue());
I have an oAuth Provider which uses Authentication URL. In some cases, my Authentication URL returns "non-200" with meaning messages e.g. incorrect username, incorrect password, user locked etc.
I wonder how to pass the meaningful message from Authentication URL to the client who is requesting the token via API (oauth2/token)??
I have tried many ways, the API Connect always results 401 - invalid grant only.
Here is my oAuth Provider Code
x-ibm-configuration:
testable: true
enforced: true
phase: realized
oauth2:
client-type: confidential
scopes:
weather: Weather Information
openid: Enable OIDC
grants:
- password
identity-extraction:
type: basic
authentication:
x-ibm-authentication-url:
url: 'https://8hxovobj7g.execute-api.eu-west-2.amazonaws.com/Prod/auth'
authorization:
type: authenticated
access-token:
ttl: 1500
refresh-token:
count: 2048
ttl: 2682000
gateway: datapower-gateway
assembly:
execute:
...
...
when authen fail due to incorrect username, the authentication URL return
401 Unauthorized
{
"error": "incorrect username"
}
However, when I use postman to post a request to API Connect Gatwatway to the oAuth Provider (path: /oauth2/token)
if correct username password (authen URL user registry return 200-OK, I will get
{
"token_type": "bearer",
"access_token": "AAIkNTU4M2RlMzktODY1NS00ZDQ1LTgyMjctODEyMDM4MDUzMTE2m7lBYXfx73OVPONAHoLT5VNdtSVD40Hu-M3nAQPu6wdviOxcIfbsOXBwt-Iy8EAgLzuATlZB7RBME_U5Ymd5fDkRTwy05G9zGmV7mIkawaELtiOj4xdzQr7Vn-indlv-y1NFEjvRv2VrK0d3TOqZnTEj5heDdY7Q0X9BFeydV4MtS-gCpnj-9l6TU3XqyeiK5hGnBZkZRAWOIskLm4KCyf8n_mnsi42vN9GLxlxoO9EmuHAwXOxr_aocKaaVlLKK5vDMHBRws2Vguqk3eVuoh9EnkRZvjbTurmW57bCgX3nMTd6MwcEYFkAGh-cOcEDyydZR6BI_pLuwaUM9RN8Vnb7EATQjzW2d_eHKQyjShcyM0TqxzhYq3q90fLfJLo08WxDgTFaKpGHA6qoZmUpYRLeyyImhOPtyd9p1l9z87g52duHbL1cyVGErHktTVpeXsmIRtn-QTTvI4jWmjxPZnSYj_rEeR9S8QAxYpHSEPmJQQmsjISf2SIRLABwuhG9dKyrrzs3UTotVyIotxmJjc9lfEsEtDTz9Ej--yQFw97ESHCVEvOkifeyIJ9F5MyPFh7fMEoGGwyDmWEfZSYRpkLg4_ib3dbjkGAuthiwjdA0",
"metadata":
...
}
if incorrect username/ password (authen URL user registry return 401-Unauthorized with response-body (error message), I will get
401-Unauthorized
{
"error": "invalid_grant"
}
The Authentication URL is custom made. I have tried to make different returns in authentication URL (different http response code/ body/ headers) which all cannot affect the end-user's oauth's oauth/token result which always return the msg "invalid grant". what I really want to pass the authentication URL result message to the end-users to let the users know what is wrong such as incorrect username
Thanks for your kindly help
Unfortunately, it seems that in APIC v5 it is not possible to adjust OAuth error based on the response from Authentication URL call.
You can check DataPower XSLT code which handles this case (local:/isp/aaa-ldap-lib.xsl) to see more details. For any non-200 response code returned by an authentication URL, the same hardcoded error is produced. Only a response code is checked and all response information is discarded after that check - including a response code.
In the case of non-200 response code returned by authentication URL following XSLT code is executed:
<xsl:call-template name="error">
<xsl:with-param name="code" select="'401'"/>
<xsl:with-param name="reason" select="'Unauthorized'"/>
<xsl:with-param name="challenge" select="'Basic'" />
</xsl:call-template>
That means it is not possible to distinguish between errors caused by different authentication URL responses in OAuth API assembly catch. You can catch UnauthorizedError in the created assembly in OAuth API but you would have no additional information based on which you could create custom error response.
However, if you are using on-premise APIC v5 and you have access to the DataPower Gateway you could:
change mentioned xsl file to propagate status code/reason from authentication URL (possibly using gateway extensions)
info necessary, add a custom assembly to your OAuth API where you would catch UnauthorizedError and add GatewayScript code to adjust behavior
GatewayScript code to adjust behavior in case of UnauthorizedError caught would be something like:
let p = session.name('policy');
let e = p.getVariable('fw/exception');
let statusCode = e.httpCode;
let statusReason = e.httpReasonPhrase;
...
I am working with an API that wants me to send the token along with Header, specifically Content Header.
Here is my code block.
string path_current_user = "me";
var cookie = HttpContext.Request.Cookies.Get("cookietoken");
string cookie_with_token = "ACCESS_TOKEN="+cookie.Value+";";
client.DefaultRequestHeaders.Add("Cookie", cookie_with_token);
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
HttpResponseMessage response = await client.GetAsync(path_current_user);
I always get a 410 Unauthorized response. However, during debugging I can collect the values from the client object, and copy paste them into https://www.hurl.it, and I get the expected 200 OK response. So, I know the values that are being stored in the above code are correct. Its not a credentials issue for sure.
I have looked at almost 50 different threads on stack overflow, but none of them talk about this specification situation. Doing a GET with the Header Content set. Here is a screenshot of the HURL that works just fine.
Update 1 - Here is the API documentation for what I am trying to achieve.
Endpoint
GET me
Request Route
GET me
Headers
Content-Type: application/json Cookie: ACCESS_TOKEN="token characters
come here and remove the quotes"; Host: x.x
Update 2 - One of my mentors, recommended the following.
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://small-project-api.herokuapp.com/me");
request.Headers.Add.("Content-Type", "application/json");
request.Headers.Add.("Cookie", cookie_with_token);
var response2 = await httpClient.SendAsync(request);
var responsestring = await response2.Content.ReadAsStringAsync();
}
He is of the opinion that may be such a request, as mentioned below, simply won't work in dot net. I am all but ready to give up here.
I tried to send a bearer token to an Auth0 API using Postman and it works perfectly.
I then tried the same using RestSharp (in c#) but it doesn't work at all.
Below is my code. I've tried many different formats but none of them work.. Is there any other way I can try to make it work?
var client = new RestClient("http://domain.auth0.com/api/v2/users");
RestRequest request = new RestRequest(Method.GET);
//request.AddHeader("authorization", "Bearer eyJhbGcJ9.eyJhdWQiOiJ6VU4hVWUE2.token");
//request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
//request.AddHeader("Accept", "application/json");
//RestClient client = new RestClient("http://domain.auth0.com");
//RestRequest request = new RestRequest("api/v2/users", Method.GET);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Accept", "application/json");
request.AddParameter("Authorization",
string.Format("Bearer " + "eyJhbGciOI1NiIsI9.eyJhdWQiOiWmVhTWpD2VycyI6eyJhY.token"),
ParameterType.HttpHeader);
//request.AddParameter("Authorization",
// String.Format("Bearer {0}", token),
//ParameterType.HttpHeader);
var response = client.Execute(request);
PS: the token was changed.
The problem is that you're using an HTTP URL. When you issue the first request the token is included, but you receive a redirect response informing that you should be calling the HTTPS endpoint.
Since RestSharp will not include the token in the second request performed automatically due to the first redirect response you get an unauthorized response.
You need to update the URL to be HTTPS which will prevent the redirect and as a consequence solve your problem. If you want to make multiple authenticated request using the same client you also change your code to be:
using RestSharp;
using RestSharp.Authenticators;
class Program
{
static void Main(string[] args)
{
// Use the HTTPS scheme
var client = new RestClient("https://[domain].auth0.com/api/v2/users");
client.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(
"eyJhbGciJIUz.eyJhdWQi4QW5OXhCNTNlNDdjIn0.vnzGPiWA", // Update the token
"Bearer");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
Console.WriteLine("{0}", response.StatusCode);
}
}
If you really need to handle redirects and still send the token, check: https://github.com/restsharp/RestSharp/issues/414
I am trying to use a custom java application of mine to upload videos to my youtube account via an access limited device like a Raspberry pi running as a server.
For this I am using the Google Oauth 2.0 for limited input device as a reference.
I followed the steps mentioned with my custom java application, Fiddler and curl, the surprise is as follows:
All of the calls worked right as mentioned by Google Oauth 2.0 for limited input device for curl.
But issues were observed with Fiddler and my custom java app for the following call:
When I am trying to get the access token from Google server (Step 4 from Google Oauth link) by posting similar request:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=1084945748469-eg34imk572gdhu83gj5p0an9fut6urp5.apps.googleusercontent.com&
client_secret=hDBmMRhz7eJRsM9Z2q1oFBSem&
code=4/YMSlR3fSCC1NtUh073DuZKTJJ3ss&
grant_type=http://oauth.net/grant_type/device/1.0
but instead of getting the 'access_token' as response I am getting the following :
Status Code:400 Response: { "error" : "invalid_request",
"error_description" : "Required parameter is missing: grant_type" }
Note : With or without url encoding, my problem stays the same.
I am unable to understand what the issue is with my custom java app or with fiddler, Please help.
Following are my fiddler requests:
(One can get oauth credentials (client_id and client_secret) by following this)
Fiddler request:
(url encoded, obscured client secret)
POST HTTP/1.1
https://accounts.google.com/o/oauth2/token?client_id=308065994473-ur9dd7003ajs6mvr5s4kqnugr6j8tsf2.apps.googleusercontent.com&client_secret=XXXXXXXXXXXXXXX&code=4%2FWR-qiTquqB0e4-0LCy0-7rZ2kkE2&grant_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fdevice%2F1.0
Content-Type: application/x-www-form-urlencoded
(non url encoded, obscured client secret)
POST HTTP/1.1
https://accounts.google.com/o/oauth2/token?client_id=308065994473-ur9dd7003ajs6mvr5s4kqnugr6j8tsf2.apps.googleusercontent.com&client_secret=XXXXXXXXXXXXXX&code=4/WR-qiTquqB0e4-0LCy0-7rZ2kkE2&grant_type=http://oauth.net/grant_type/device/1.0
Java code project is available at (maven project, check the test case for the Oauth calls):
https://docs.google.com/file/d/0B8ltWBtPF-DVMDZFNHNMZXpCQlk
The parameters need to be added in the http post request body not in the url, Google documentation is confusing on this part.
public synchronized HttpResponse executePOST(HttpEntity httpEntity, String path) throws IOException {
if (!parameters.isEmpty()) {
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
}
httpPost = new HttpPost(path);
logger.info(target.toHostString());
logger.info(httpPost.getURI().toString());
logger.info(httpPost.getRequestLine().toString());
for (Header header : headers) {
logger.info(header.getName() + ": " + header.getValue());
httpPost.addHeader(header);
}
httpResponse = httpClient.execute(target, httpPost);
return httpResponse;
}