Can't access the calendars in office365 groups - azure

I got Unauthorized when calling to get Calendar in the Microsoft graph API, I use this verification to retrieve an access token.
I think the problem is that when I want to retrieve the Get HTTP request on Calendar the access token isn't created with credentials which result in the Unauthorized call. How can I change my code to be able to send Credentials with it and get a better Token with more privileges?
In the Azure portal, I granted all permissions to see whether that the application permissions weren't set correctly.
AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);
ClientCredential clientCred = new ClientCredential(_azureAd_ClientId, _azureAd_SecretKey);
string tokenResult;
AuthenticationResult authenticationResult;
try
{
authenticationResult = await authenticationContext.AcquireTokenAsync(_azureAd_GraphResource, clientCred);
var user = authenticationResult.UserInfo;
string_token = authenticationResult.AccessToken;
tokenResult = JsonConvert.SerializeObject(authenticationResult);
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex.InnerException);
}

Reading through the comments it seems that you may need to trigger a new consent prompt in order to grant the application the permissions you have re-configured. If this is a V1 app, you can do so by adding prompt=admin_consent to the end of your request. If this is a V2 app, you will want to use the /adminconsent endpoint. More info on that is here.
There is also some more documentation on admin consent in general here.

Related

Scope needed to get access token to pull user groups from Azure using client id and client secret and graph API

I am trying to get the groups in my azure tenant using my client secret and client id. Problem is I don't know what scope to pass when getting an access token to use the graph api. I used https://graph.microsoft.com/.default to get an access token but this doesn't include permission to pull groups. What's the appropriate scope to use
https://learn.microsoft.com/en-us/graph/api/group-list?view=graph-rest-1.0#permissions
Permissions
One of the following permissions is required to call this API. To learn more, including how to choose permissions, see Permissions.
Permission type Permissions (from least to most privileged)
Delegated (work or school account) Group.Read.All, Group.ReadWrite.All
Application Group.Read.All, Group.ReadWrite.All
You need to configure the API access within AAD, not with the scope. Make sure that you don't forget to click on "grant permissions".
Example assumes that you require application permission. Delegated permission works similarly.
Sample code for getting the data using MSAL for authentication:
IConfidentialClientApplication app = new ConfidentialClientApplication(
"clientId",
"https://login.microsoftonline.com/yourtenant.onmicrosoft.com",
"http://localhost (redirecturi)",
new ClientCredential("secret"),
new TokenCache(), new TokenCache());
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
try
{
AuthenticationResult result = await app.AcquireTokenForClientAsync(scopes);
System.Console.WriteLine(result.AccessToken);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
var groupResponse = await http.GetAsync("https://graph.microsoft.com/v1.0/groups");
var groupJson = await groupResponse.Content.ReadAsStringAsync();
System.Console.WriteLine(groupJson);
}
}
catch (Exception ex)
{
System.Console.WriteLine(ex.Message);
}

How to access Microsoft Office 365 Planner programmatically

I am trying to access Microsoft Office 365 Planner using CSOM and Azure App. Whenever I try to access planner using group Id i am getting the below error:
401 - Unauthorized: Access is denied due to invalid credentials. You do not have permission to view this directory or page using the credentials that you supplied.
I have given the required permissions to Azure Graph api.
Application - Read Groups All, Read and Write Groups All.
Delegated - Tasks.ReadWrite
Below is the sample code that i am using:
//Querying plans in current group await
graphClient.Groups[groupId].Planner.Plans.Request().GetAsync();
Is there any option to achieve this. I need to access the planner and need to create Buckets and plans based on Office 365 group.
Any help is much appreciated. Thanks in advance.
You should be using Microsoft Graph rather than Azure AD Graph API.
https://learn.microsoft.com/en-us/graph/planner-concept-overview
Also, you need to authenticate with your user credentials to access the Planner. You can change the GetAccessToken method to authenticate this way (example from linked blog).
private async Task<string> GetAccessToken(string resourceId, string userName, string password)
{
try
{
var authority = ConfigurationManager.AppSettings["ida:AuthorizationLoginUri"] + ConfigurationManager.AppSettings["ida:TenantId"];
var authContext = new AuthenticationContext(authority);
var credentials = new UserPasswordCredential(userName, password);
var authResult = await authContext.AcquireTokenAsync(resourceId, ConfigurationManager.AppSettings["ida:ClientIdNativeClient"], credentials);
// Get the result
return authResult.AccessToken;
}
catch (Exception ex)
{
// TODO: handle the exception
return;
}
You need to also ensure that your app is registered properly in the portal. Please check out this helpful blog that shows how to get past the error you described when accessing the planner:
https://karinebosch.wordpress.com/2017/12/18/microsoft-graph/

B2B users cannot sign in to Tenant using v2.0 endpoint & MSAL Auth flow

I am trying to create a B2B Management portal. I've started off with this sample since it uses MSAL and Graph API.
user#live.se is in the tenant. It's been invited as a "guest user", i.e a B2B user. However, signing in with user#live.se does not work even though it's been added to the tenant. Following error after sign-in:
AADSTS50020: User account 'user#live.se' from external identity provider 'live.com' is not supported for api version '2.0'. Microsoft account pass-thru users and guests are not supported by the tenant-independent endpoint. Trace ID: 2ad8bee0-d00a-4896-9907-b5271a113300 Correlation ID: 0ea84617-4aa1-4830-859f-6f418252765e Timestamp: 2017-10-03 15:35:22Z
I changed the authority (from common) to only allow users from my tenant (requirement):
https://login.microsoftonline.com/tenant.onmicrosoft.com/v2.0
Do guests not count as part of my tenant when using MSAL? that would mean I have to use "old" tech, i.e ADAL and AAD Graph, which is not recommended, and feels kinda lame.
If you pass the specific tenant value in the authority, then
Only users with a work or school account from a specific Azure AD tenant can sign in to the application. Either the friendly domain name of the Azure AD tenant or the tenant's GUID identifier can be used.
That's means the Microsoft Account is not supported in this scenario. Refer here for the Microsoft Account and Work or school accounts. And in this scenario, if you new a user user from other tenant, it should also works.
You can refer the document for tenant from link below:
Fetch the OpenID Connect metadata document
I know this is an old thread but just in case anyone stumbles upon it, here is a solution:
In cases of Personal guest accounts, use Credential Grant Flow (Get access without a user).
To do that, you would first need to grant appropriate permission (of Type Application) for the API you wanted to use on behalf of the signing user. This would let you acquire access token with the application's identity itself rather than the signed in user.
Next get token like this (in this sample, I'm getting access token for Graph API):
public async Task<string> GetAccessToken()
{
using (HttpClient httpClient = new HttpClient())
{
string token = "";
try
{
httpClient.BaseAddress = new Uri($"https://login.microsoftonline.com/{tenantId}");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
HttpRequestMessage request = new HttpRequestMessage();
List<KeyValuePair<string, string>> body = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("client_id", clientId),
new KeyValuePair<string, string>("scope", "https://graph.microsoft.com/.default"),
new KeyValuePair<string, string>("client_secret", appSecret),
new KeyValuePair<string, string>("grant_type", "client_credentials")
};
request.Method = HttpMethod.Post;
request.RequestUri = new Uri($"{httpClient.BaseAddress}/oauth2/v2.0/token");
request.Content = new FormUrlEncodedContent(body);
var response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsAsync<dynamic>();
token = content.access_token;
}
catch (Exception e)
{
}
return token;
}
}
Tip: If your goal is also Graph API, don't try to get logged in user info by using the /me endpoint in this case. Since the token was generated using the application identity rather than the signed in user, /me would be the application not the logged in user. What you want to do is: retrieve logged in user id from the Claim (Type: http://schemas.microsoft.com/identity/claims/objectidentifier) and use the /user/{userid} endpoint.
I found: for personal accounts (Get access without a user) in the body of the request you must to use grant_type = 'client_credentials' and for corporate accounts to use grant_type = 'authorization_code'

Application Token based Request returning not 401 Unauthorized

I have a background application which is supposed to connect to Data Catalog and fetch information related to a table. Since its a background application, I cannot have any user intervention to authenticate the Data Catalog request. So I am trying to authenticate using ClientID and ClientSecret instead.
string authorityUri = "https://login.microsoftonline.com/{adtenanthere}";
string resourceUri = "https://datacatalog.azure.com";
string clientId = "{clientidhere}";
string clientSecret = "{clientsecrethere}";
AuthenticationContext authContext1 = new AuthenticationContext(authorityUri, false);
ClientCredential credential = new ClientCredential(clientId, clientSecret);
AuthenticationResult authResult = authContext1.AcquireTokenAsync(resourceUri, credential).Result;
string token = authResult.CreateAuthorizationHeader();
Getting the token using this method is being successful, however when I use this token for the Data Catalog API request, the request returns "401 - Unauthorized: Access is denied due to invalid credentials. You do not have permission to view this directory or page using the credentials you supplied".
Please suggest what I could be missing here!
First Check Your Application Permission in Azure Ad Permission. I was check No permission in Application Azure data catalog. So, you must access using user credentials.below see the images
Application permission is based on client credentials. the delegate
permission based on login user permission.
you should need without login popup you must pass the user credentials
in authContext1.AcquireTokenAsync directly.
So, Change and Check the you not get 401 Unauthorized
I think it's help for you.
Some data is incorrect, here are the correct values:
string authorityUri = "https://login.windows.net/common/oauth2/authorize";
string resourceUri = "https://api.azuredatacatalog.com";
Hope this helps,
Monica

Authenticate guest user in Azure AD using graph api

I am trying to authenticate users in my web application using Azure AD to store user records. For authenticating the user I am using ADAL4J API (https://github.com/AzureAD/azure-activedirectory-library-for-java). I am using the the AuthenticationContext.acquireToken() method to acquire the token for users. This is working for local users in my directory but not for guest users invited to the directory.
While authenticating guest users I am getting an error : "To sign into this application the account must be added to the directory" . However, I am sure the user has been successfully added to the directory as seen through the Azure Portal. Also, I have verified the same using the graph API where I can see the guest users in the user list in the directory.
So the question is how do I authenticate the guest user in my web application through code (not through redirecting to the Azure UI)?
EDIT :
This the method to which I am passing the username and password of the user:
private static AuthenticationResult getAccessTokenFromUserCredentials(
String username, String password) throws Exception {
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext("https://login.windows.net/<tenant_name>", false, service);
Future<AuthenticationResult> future = context.acquireToken(
"https://graph.windows.net", CLIENT_ID, username, password,
null);
result = future.get();
} catch(Exception e){
e.printStackTrace();
} finally {
service.shutdown();
}
if (result == null) {
throw new ServiceUnavailableException(
"authentication result was null");
}
return result;
}
With the information you provided, I feel like the issue here is related to the login endpoint. Remember that the common endpoint uses the logged in user to help 'guess' which tenant endpoint to authenticate to. If you are doing more tricky things like guest accounts, it is very likely the common endpoint will not figure out all the right details.
I recommend you specifically call your tenant's login endpoint, through the whole process, and see if that resolves your issues.
Let me know if this helps!

Resources