I'm getting below error while updating a security group (created through API) to mail enabled security group via Microsoft Graph API.
{
"error": {
"code": "Request_BadRequest",
"message": "The service does not currently support writes of mail-enabled groups. Please ensure that the mail-enablement property is unset and the security-enablement property is set.",
"innerError": {
"request-id": "34bc9a4d-9e52-4c2e-b847-99f8dbf43518",
"date": "2018-04-09T13:05:10"
},
"details": [
{
"target": "mailEnabled",
"code": "InvalidValue"
}
]
}
}
As per https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/group_update#request-body documentation, I believe it is possible to have a security group with mail enabled feature.
This is raw request(Captured through Fiddler).
PATCH https://graph.microsoft.com/v1.0/groups<<groupId>> HTTP/1.1
Accept: application/json
Authorization: Bearer <<Authorization Token>>
Content-Type: application/json; charset=utf-8
Host: graph.microsoft.com
Content-Length: 96
Expect: 100-continue
Connection: Keep-Alive
{"mailEnabled":true,"mailNickname":"<<mailNickName>>"}
Please suggest if the request need to formed in a different format?
I'm afraid Mail-enabled Security Groups are not fully supported by Microsoft Graph. From the documentation:
Mail-enabled security groups can't be created through the API, but other group operations work. Mail-enabled security groups are read only.
Mail-enabled security groups can be managed via Exchange. You can find more details on this in Manage mail-enabled security groups in Exchange 2016.
Related
I'm trying to create a Microsoft Teams team in Migration mode via the Graph API. However I get a 400 response that I can't figure out. The query is shared in the link below.
Shared Query
For those that don't want to view it that way, here is my request:
POST https://graph.microsoft.com/beta/teams
Authorization: Bearer ...
Content-Type: application/json
{
"#microsoft.graph.teamCreationMode": "migration",
"template#odata.bind": "https://graph.microsoft.com/beta/teamsTemplates(\u0027standard\u0027)",
"displayName": "SlackMigrationTest",
"description": "testing slack migrations",
"createdDateTime": "2021-01-14T00:00:00.000Z"
}
I created this based on the microsoft doc here.
The reponse I get is:
The remote server returned an error: (400) Bad Request.
{
"error": {
"code": "BadRequest",
"message": "Required functionality is not supported.",
"innerError": {
"date": "2021-01-20T15:51:21",
"request-id": "dc4189cf-db4a-4a60-a271-f63b5d759a05",
"client-request-id": "dc4189cf-db4a-4a60-a271-f63b5d759a05"
}
}
}
I'm sure its something obvious that I'm missing but any help would be greatly appreciated.
Here you are using the User Context token and trying to make the call. This API call only works in Application context as shown in the below screenshot.
So use Client Credential flow and set Application permissions and then make a call.
As you can see below, it worked for me with App token.
You cannot test it in graph explorer because the Graph Explorer gets user token.
I have done OAuth2.0 using PKCE flow in .NET Framework (C# Winforms).
Now I have tokens_response in my hand.
But I'm wondering is it possible to fetch all of the organisation (not only one)?
You can check the organisations (tenants) that you can access with a given token using the /connections endpoint, like this:
GET https://api.xero.com/connections
Authorization: "Bearer " + access_token
Content-Type: application/json
Response:
[
{
"id": "e1eede29-f875-4a5d-8470-17f6a29a88b1",
"authEventId": "d99ecdfe-391d-43d2-b834-17636ba90e8d",
"tenantId": "70784a63-d24b-46a9-a4db-0e70a274b056",
"tenantType": "ORGANISATION",
"tenantName": "Maple Florist",
"createdDateUtc": "2019-07-09T23:40:30.1833130",
"updatedDateUtc": "2020-05-15T01:35:13.8491980"
},
{
"id": "32587c85-a9b3-4306-ac30-b416e8f2c841",
"authEventId": "d0ddcf81-f942-4f4d-b3c7-f98045204db4",
"tenantId": "e0da6937-de07-4a14-adee-37abfac298ce",
"tenantType": "ORGANISATION",
"tenantName": "Adam Demo Company (NZ)",
"createdDateUtc": "2020-03-23T02:24:22.2328510",
"updatedDateUtc": "2020-05-13T09:43:40.7689720"
}
]
If you need more information than the organisations' id and name, you'll need to call the /organisation endpoint individually for each.
The connections endpoint is described more in section 5 on this page of the docs: https://developer.xero.com/documentation/oauth2/auth-flow
I use the Microsoft Graph API to crawl emails in Exchange Online.
If you try to crawl the ArchiveMsgFolderRoot folder using this API, you will get a ErrorInvalidMailboxItemId error.
GET https://graph.microsoft.com/v1.0/users/user_id/mailFolders/ArchiveRoot/
HTTP/1.1 404 Not Found
Cache-Control: private
Content-Type: application/json
request-id: ce60b00e-1703-450e-b8d2-0e8629519985
client-request-id: ce60b00e-1703-450e-b8d2-0e8629519985
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"Japan East","Slice":"SliceC","Ring":"2","ScaleUnit":"000","RoleInstance":"AGSFE_IN_5"}}
Strict-Transport-Security: max-age=31536000
Date: Mon, 18 May 2020 06:40:06 GMT
Connection: close
Content-Length: 257
{
"error": {
"code": "ErrorInvalidMailboxItemId",
"message": "Item Id doesn't belong to the current mailbox.",
"innerError": {
"request-id": "ce60b00e-1703-450e-b8d2-0e8629519985",
"date": "2020-05-18T06:40:07"
}
}
}
The error did not return at least around March.
The same applies to the following folders.
https://graph.microsoft.com/v1.0/users/user_id/mailFolders/ArchiveMsgFolderRoot/
https://graph.microsoft.com/v1.0/users/user_id/mailFolders/ArchiveDeletedItems/
Has the Microsoft Graph folder naming scheme changed?
This is not possible: The API does not support accessing in-place archive mailboxes, not on Exchange Online nor on Exchange Server.
That's why neither ArchiveMsgFolderRoot nor ArchiveDeletedItems is not listed under the Well-known folder names.
Finally, Cross-mailbox API calls will fail starting April 15, 2020.
I'm trying to test on the China sovereign network.
Using these 2 API endpoints for Authentication and Graph API.
https://login.chinacloudapi.cn, https://microsoftgraph.chinacloudapi.cn
Microsoft.Graph.GraphServiceClient graphClient = GraphProvider.GetGraphServiceClient(tenantName, clientId, clientSecret);
graphClient.BaseUrl = "https://microsoftgraph.chinacloudapi.cn/V1.0";
...
var notebooks = await graphClient.Users[userPrincipalName].Onenote.Notebooks.Request().GetAsync();
This does not seem to be working for the China sovereign network. (Works fine for ordinary US endpoint)
Here's the packet dump
Request
GET
/V1.0/users/??????/onenote/notebooks
HTTP/1.1
SdkVersion: Graph-dotnet-1.12.0
Authorization: Bearer
eyJ0eXAiOiJKV1QiLCJub25jZSI6IlFrQ1dPOTFCcWhuMWVub0d3MmRLT3B3aXozS1ZPNnB2TV93Tjl2Vk1va0kiLCJhbGciOiJSUzI1NiIsIng1dCI6InljS3RWOG1aX0pmM25CVmJmZzRmblp1TFFSYyIsImtpZCI6InljS3RWOG1aX0pmM25CVmJmZzRmblp1TFFSYyJ9.eyJhdWQiOiJodHRwczovL21pY3Jvc29mdGdyYXBoLmNoaW5hY2xvdWRhcGkuY24iLCJpc3MiOiJodHRwczovL3N0cy5jaGluYWNsb3VkYXBpLmNuLzljZGE1YzQ2LTk1NjItNGFhNy05NzQyLTE3MjBjZjRlMmQwZi8iLCJpYXQiOjE1Nzk3MTk1NjcsIm5iZiI6MTU3OTcxOTU2NywiZXhwIjoxNTc5NzIzNDY3LCJhaW8iOiJZMlZnWUpqeTdqN1hVOG05TExFOGZjNHJwdDVZQ2dBPSIsImFwcF9kaXNwbGF5bmFtZSI6IkNvbW12YXVsdF9UZXN0IiwiYXBwaWQiOiI2YjliNTE0Mi0xOWY4LTQ2MGUtYWNjOC02ZTU5M2MxNGI0NTYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy5jaGluYWNsb3VkYXBpLmNuLzljZGE1YzQ2LTk1NjItNGFhNy05NzQyLTE3MjBjZjRlMmQwZi8iLCJvaWQiOiI1ZGQ0ZTM3Mi03NWVjLTRhYTEtODhkNy00ZDliOTAyZDI1ZjYiLCJyb2xlcyI6WyJTaXRlcy5SZWFkV3JpdGUuQWxsIiwiRGlyZWN0b3J5LlJlYWQuQWxsIiwiVXNlci5SZWFkLkFsbCJdLCJzdWIiOiI1ZGQ0ZTM3Mi03NWVjLTRhYTEtODhkNy00ZDliOTAyZDI1ZjYiLCJ0aWQiOiI5Y2RhNWM0Ni05NTYyLTRhYTctOTc0Mi0xNzIwY2Y0ZTJkMGYiLCJ1dGkiOiIwRS1Wdmp0WFBrLURVdUZXaFpBWEFBIiwidmVyIjoiMS4wIiwieG1zX3RjZHQiOjE1NzM0NjEzNzF9.y5QkGFjb2_EFB0oexXgdSZxbkHkKrkcc5GgpmrH0I2865LQ0vPkkK2efyJU19tEKNhkWXXADAsD76SalzSheu7hQ69sCj-HsXyRbG-Ue03KMmD2KsXRVFK-bVrjF1vJl9k5zKUeYP0rw5sjc7G33GmYh6L6iFm8y_PHg9W14JOfvCaMsvu0QXK9UTc7AWUy09L71ZVw6SGEokfayFfjqh8bkq7jI8CuvOV61tAUgmUJvIijSsl6HwoHVrMJ5D_RLLPdkOD01fN4YDkYCsleEDsgLnqXpzmtOPABzgVuyDfk-saAo4PLl-omN4OTx5-_bJjq5LM_SqTnELihSrYCkaw
Cache-Control: no-store, no-cache
Host: microsoftgraph.chinacloudapi.cn
Response
{ "error": {
"code": "Request_BadRequest",
"message": "Unexpected segment OpenPropertySegment. Expected property/$value.",
"innerError": {
"request-id": "a4cf5da0-715e-4dbd-ad1e-fd4b5e8f2134",
"date": "2020-01-22T19:04:31"
} } }
Am I missing something when calling the API?
Thanks.
Sorry Locke but OneNote is not supported on Microsoft Graph in China for now
When a client asks a resource server to get a protected resource with an OAuth 2.0 access token, how does this server validate the token? The OAuth 2.0 refresh token protocol?
Google way
Google Oauth2 Token Validation
Request:
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=1/fFBGRNJru1FQd44AzqT3Zg
Respond:
{
"audience":"8819981768.apps.googleusercontent.com",
"user_id":"123456789",
"scope":"https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
"expires_in":436
}
Microsoft way
Microsoft - Oauth2 check an authorization
Github way
Github - Oauth2 check an authorization
Request:
GET /applications/:client_id/tokens/:access_token
Respond:
{
"id": 1,
"url": "https://api.github.com/authorizations/1",
"scopes": [
"public_repo"
],
"token": "abc123",
"app": {
"url": "http://my-github-app.com",
"name": "my github app",
"client_id": "abcde12345fghij67890"
},
"note": "optional note",
"note_url": "http://optional/note/url",
"updated_at": "2011-09-06T20:39:23Z",
"created_at": "2011-09-06T17:26:27Z",
"user": {
"login": "octocat",
"id": 1,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "somehexcode",
"url": "https://api.github.com/users/octocat"
}
}
Amazon way
Login With Amazon - Developer Guide (Dec. 2015, page 21)
Request :
https://api.amazon.com/auth/O2/tokeninfo?access_token=Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...
Response :
HTTP/l.l 200 OK
Date: Fri, 3l May 20l3 23:22:l0 GMT
x-amzn-RequestId: eb5be423-ca48-lle2-84ad-5775f45l4b09
Content-Type: application/json
Content-Length: 247
{
"iss":"https://www.amazon.com",
"user_id": "amznl.account.K2LI23KL2LK2",
"aud": "amznl.oa2-client.ASFWDFBRN",
"app_id": "amznl.application.436457DFHDH",
"exp": 3597,
"iat": l3ll280970
}
Update Nov. 2015: As per Hans Z. below - this is now indeed defined as part of RFC 7662.
Original Answer: The OAuth 2.0 spec (RFC 6749) doesn't clearly define the interaction between a Resource Server (RS) and Authorization Server (AS) for access token (AT) validation. It really depends on the AS's token format/strategy - some tokens are self-contained (like JSON Web Tokens) while others may be similar to a session cookie in that they just reference information held server side back at the AS.
There has been some discussion in the OAuth Working Group about creating a standard way for an RS to communicate with the AS for AT validation. My company (Ping Identity) has come up with one such approach for our commercial OAuth AS (PingFederate): https://support.pingidentity.com/s/document-item?bundleId=pingfederate-93&topicId=lzn1564003025072.html#lzn1564003025072__section_N10578_N1002A_N10001. It uses REST based interaction for this that is very complementary to OAuth 2.0.
An update on #Scott T.'s answer: the interface between Resource Server and Authorization Server for token validation was standardized in IETF RFC 7662 in October 2015, see: https://www.rfc-editor.org/rfc/rfc7662. A sample validation call would look like:
POST /introspect HTTP/1.1
Host: server.example.com
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer 23410913-abewfq.123483
token=2YotnFZFEjr1zCsicMWpAA
and a sample response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"active": true,
"client_id": "l238j323ds-23ij4",
"username": "jdoe",
"scope": "read write dolphin",
"sub": "Z5O3upPC88QrAjx00dis",
"aud": "https://protected.example.net/resource",
"iss": "https://server.example.com/",
"exp": 1419356238,
"iat": 1419350238,
"extension_field": "twenty-seven"
}
Of course adoption by vendors and products will have to happen over time.
OAuth 2.0 spec doesn't define the part. But there could be couple of options:
When resource server gets the token in the Authz Header then it calls the validate/introspect API on Authz server to validate the token. Here Authz server might validate it either from using DB Store or verifying the signature and certain attributes. As part of response, it decodes the token and sends the actual data of token along with remaining expiry time.
Authz Server can encrpt/sign the token using private key and then publickey/cert can be given to Resource Server. When resource server gets the token, it either decrypts/verifies signature to verify the token. Takes the content out and processes the token. It then can either provide access or reject.
Updated Answer for 2021
It is generally not recommended that you roll any part of the OAuth 2 / OIDC implementation on your own, especially now that token introspection is part of the standard. Much like attempting to roll your own encryption library, it is far too easy to make critical mistakes with such a complex spec.
Here's a list of recommended libraries in other languages that implement OAuth 2. Here's another of ones that have been certified by the OpenID Foundation; many of those libraries also implement OAuth 2.
If you're in .NET and using the IdentityServer library (version 2.2 and up), the introspect endpoint accomplishes exactly this. It's published as part of the discovery document (also standard), and is an endpoint against which the resource server can validate access tokens.
If you've come this far and you still really want to roll your own, take some tips from how the bigger libraries have done it.
OAuth v2 specs indicates:
Access token attributes and the methods used to access protected resources are beyond the scope of this specification and are defined by companion specifications.
My Authorisation Server has a webservice (SOAP) endpoint that allows the Resource Server to know whether the access_token is valid.