I have a share-point addin need to create the xamarin application. So need access to all the share-point online rest API.
As per the Microsoft document we need to register app on Azure AD.
I don't want to register the app in Azure AD, I already have share point adding
I have Tried the MSAL and ADAL Library provide by Microsoft for accessing. To used them we need to register app on Azure AD.
here is the code which I have written to access direct share-point rest API.
private const string GetCalendarEventsUrl = "{tenant}/_api/web/lists/getbytitle('Project')/items?$top=4900";
public List<CalendarEvent> GetCalendarEvents()
{
var username = "{tenant}.onmicrosoft.com";
var password = "{password}";
var domain = "{domain}";
var handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential(username, password, domain);
using (var client = new HttpClient(handler))
{
using (var request = new HttpRequestMessage(HttpMethod.Get, new Uri(GetCalendarEventsUrl)))
{
request.Headers.Add("Accept", "application/json;odata.metadata=minimal");
using (var response = client.SendAsync(request).Result){
if (response.IsSuccessStatusCode) {
Console.WriteLine("response");
}
}
}
}
throw new Exception("Could not get calendar events");
}
Can I access the share-point online rest API directly?
You can't directly access the Sharepoint rest api from mobile.
Here are my findings:-
A - You need to create your own web-services which will authenticate with the Sharepoint online web apis and deploy it then you will have to connect to the newly created web-services with your mobile app to fetch and update the data.
you can find the proper description from this link
https://www.codemag.com/Article/1411031/Mobile-Apps-for-SharePoint-and-Office-365-Part-1
B - Another way is that you can add a new app, create a new app and register into the Azure AD with your own custom logics for the interactions with Sharepoint online rest api
you can find the proper description from this link
https://learn.microsoft.com/en-gb/azure/active-directory/develop/app-types
Let me know,if it helps
Related
I have a .Net Core application attempting to download the latest sales reports from my Google Play account to view and track sales statistics. These reports are stored on a Google Cloud Storage bucket "owned"/managed by the Google Play Store.
I've been unable to find many other examples or related issues in .Net and have been experiencing a storage permission issue.
I'm following the rather limited guide here: https://support.google.com/googleplay/android-developer/answer/6135870#export under "Download reports using a client library and service account"
Step 1: Create a service account
I've created a new service account for a new project as shown below. I've also granted that service account permissions for all storage objects as shown.
Step 2: Add the service account on your play console
I've also invited this new service account user to my play console and granted it permissions to the app to view it's information and financial reports.
Step 3: Fetch reports using an API call
I've created and downloaded a .JSON key for the service user.
// Scope as specified in https://support.google.com/googleplay/android-developer/answer/6135870#export
string[] scopes = new string[] { "https://www.googleapis.com/auth/devstorage.read_only" };
// Import JSON credential
var credential = GoogleCredential.FromFile(Path.Combine(Environment.CurrentDirectory, "keys/googleplay.json")).CreateScoped(scopes);
// Bucket ID of Google Play Store - Found from reports page "Copy URL"
string bucketId = "pubsite_prod_5XXXXXXXXX2";
var storage = StorageClient.Create(credential);
var bucketObjects = storage.ListObjects(bucketId);
foreach (var bucketObject in bucketObjects)
{
Console.WriteLine(bucketObject.Name);
}
This results in a permission error:
Google.Apis.Requests.RequestError\r\nsupportapp-googleplay#ascendant-nova-300105.iam.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. [403]\r\nErrors [\r\n\tMessage[supportapp-googleplay#ascendant-nova-300105.iam.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket.
The service account I've created has the storage.objects.list permission and has been invited to my Play Console as well (as shown in the screenshots). This is a storage bucket hosted/owned by Google Play and not me. How can this permissions issue be resolved to allow my linked account to access Google Play's sales reports via API?
I came back in the morning and magically things now work.
I have also changed to using fromStream instead of fromFile when creating the Google credential.
Changed:
string[] scopes = new string[] { "https://www.googleapis.com/auth/devstorage.read_only" };
var credential = GoogleCredential.FromFile(Path.Combine(Environment.CurrentDirectory, "keys/googleplay.json")).CreateScoped(scopes);
To:
GoogleCredential credential;
using (var stream = new FileStream(Path.Combine(Environment.CurrentDirectory, "keys/googleplay.json"), FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream).CreateScoped(scopes);
}
However, both of these credential creation systems work just fine... Perhaps it took Google 12 hours to sync the permissions? Hopefully this example can help someone else out in the future.
I need some help as I'm really stuck!!!! I have spent days and hours on this one but I can't figure it. I have searched all possible forums and other similar posts without any success.
So, the requirement :
We are trying to integrate Classroom API on our .Net platforms. The tricky part is that they want to use service accounts.
The problem :
Google.Apis.Requests.RequestError The caller does not have permission [403]
The caller does not have permission] Location[ - ] Reason[forbidden] Domain[global]
I have followed the documentation as shown in :
https://developers.google.com/identity/protocols/OAuth2ServiceAccount.
I understand that we need to set up a service account in the Google API Console, so I've done the following:
1) I have created a service account and enabled G Suite Domain-wide Delegation in the Google API Console
2) In the Admin Console, in Manage API Client Access, I have entered the service account's client id and have enabled scopes.
3) A have downloaded the json file with all the service account credentials (private key, email)
and the code...
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(cr.client_email)
{
Scopes = new[] { ClassroomService.Scope.ClassroomCourses },
}.FromPrivateKey(cr.private_key));
// Create the service.
service = new ClassroomService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Demo-School",
});
and the actual call to the Classroom API to create a course :
var resource = service.Courses.Create(course);
var result = await resource.ExecuteAsync();
So, despite all that, whenever i try to create a course, I get the above error.
When I try to create a Course using the Reference page (https://developers.google.com/classroom/reference/rest/v1/courses/create) it works fine. I can create courses, teachers, set permissions etc..
But when I try to do that programmatically.. i.e from a console app, there is NO way I can get it working.
Can ANYONE please advice???????What am I missing??
I am developing an APP with Xamarin.Forms, and I need to access the data hosted on my Dynamics 365 platform..
In the developer resources section, Microsoft offers me a URL for access: https://XXXXXX.api.crm4.dynamics.com/api/data/v9.1/ and a Client ID.
With this data, is it enough to access to the platform? According to the Microsoft documentation, I need to register the APP in Active Directory but following the steps indicated in it I have not managed to connect.
But the Client ID offered to me when registering the APP in Azure is totally different from the one offered in the platform. I have also obtained the access credentials but there is no way.
I have the following code.
Values of the constants:
Constantes.API_URL = https: //XXXXXX.api.crm4.dynamics.com/api/data/
Constantes.CLIENT_ID = By registering the application at Active Directory (Not the one that they give me in the platform)
Constantes.CLIENT_KEY = By registering the application at Active Directory.
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(
new Uri(Constantes.API_URL)).Result;
String authorityUrl = ap.Authority;
String resourceUrl = ap.Resource;
//return resourceUrl;
ClientCredential creditential = new ClientCredential(Constantes.CLIENT_ID, Constantes.CLIENT_KEY);
AuthenticationContext authContext = new AuthenticationContext(authorityUrl, false);
AuthenticationResult result = null;
result = await authContext.AcquireTokenAsync(resourceUrl, creditential);
return result.AccessToken;
Current scenario:
Web App and Web API are authenticated using AAD B2C and working fine. Each customer has a unique tenant. OpenIdConnectAuthenticationOptions (web app) and OAuthBearerAuthenticationOptions (api) are set at the application Startup.
As described here: Token based authentication for both Web App and Web API using Azure AD B2C
Unfortunately both Web app and API have to be deployed for each and every customer to keep them separated.
Requirement:
Use same Web app and API for multiple customers rather than deploying them for every customer. Each customer will have a different URL for the web application.
Question 1 (Web App): How to redirect (for authentication) users to the correct tenant based on the request URL?
i.e. Set OpenIdConnectAuthenticationOptions (tenant, applicationId, signInPolicy etc.) from the database (or memory) on the fly based on the Request.Url rather than at application Startup.
Question 2 (API): How to validate the received token using the correct tenant?
i.e. Set OAuthBearerAuthenticationOptions configurations on the fly based on the received token clientId rather than at the application Startup
There are a couple of things within this that will not work based on what I think are assumptions.
Firstly, B2C has no concept of multiple "tenants". B2C is essentially
a Directory within your tenant and cannot be separated further. You
can have multiple B2C Directories within your tenant, say for each
customer, but you cannot have multiple segregated customers within a
single B2C Directory.
Secondly, if you did have your application connected to multiple B2C
directories, you would need to manage then connectors, App ID's, keys
etc for each one. It is then up to your application to work out which
one to use based on some data (URL accessed etc.).
There are also a couple of questions I would ask around how are you on-boarding users ? Can they register themselves ? Do they have their own user stores ?
If you really want to keep user accounts separate for each organisation (and they don't have a SAML / OIDC identity provider already) then I would do the following:
Create a B2C instance for each customer
Create a B2C instance for your application / web API
Use Custom Policies to connect your application B2C instance with your customer B2C instances (making sure to use the <Domain> element for the claims provider in the XML)
Use domain hints within your application to force the application to chose the correct B2C instance (see this: http://www.cloudidentity.com/blog/2014/11/17/skipping-the-home-realm-discovery-page-in-azure-ad/)
In this way your application only needs to trust and maintain the single B2C directory, and if you do have customers who have their own OIDC or SAML endpoints they become a claims provider within the directory, rather than a separate B2C instance.
Per #ManishJoisar's request this is how I resolved my issue long ago. This is an old .net framework 4.8 code sample.
Please note that B2C v2 policies provide better implementation with federation through custom policies these days.
public void ConfigureAuth(IAppBuilder app)
{
int index = 2000;
foreach (var record in SystemConfig.ApiToWebUrl)
{
app.MapWhen(
context => System.Web.HttpContext.Current.Request.Url.BaseURL() == record.Key,
config =>
{
var customer = SystemConfig.GetWebSettings(true)[record.Value];
config.UseOAuthBearerAuthentication(CreateBearerOptionsFromPolicy(index, customer.B2CSignInPolicyId,
customer.B2CAadInstance, customer.B2CTenant, customer.B2CApplicationId));
}
);
index++;
}
}
public OAuthBearerAuthenticationOptions CreateBearerOptionsFromPolicy(int index, string b2cPlicyName,
string b2cInstance, string b2cTenant, string b2cClientId)
{
TokenValidationParameters tvps = new TokenValidationParameters
{
// This is where you specify that your API only accepts tokens from its own clients
ValidAudience = b2cClientId,
AuthenticationType = string.Format("{0}_{1}", b2cPlicyName, index)
};
var aadInstance = string.Format("https://{0}{1}", b2cTenant.Split('.')[0], ".b2clogin.com/{0}/{1}/v2.0/.well-known/openid-configuration");
var config = String.Format(aadInstance, b2cTenant, b2cPlicyName);
return new OAuthBearerAuthenticationOptions
{
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(config)),
Provider = new CustomOAuthBearerProvider()
};
}
We are creating a third-party application to access partner center API.
We have registered a SharePoint site using JSOM architecture as third-party application where we use MSAL library for login. After which using accessToken we call a WebAPI used for securely accessing the data from our database. Now we need to access partner center API for partner details. As per the documentation provided to us we have the following code:
var clientcred = new ClientCredential(clientId, appKey);
var authContext = new AuthenticationContext(string.Format("https://login.microsoftonline.com/{0}/", tenantID), tokenCache);
var result = await authContext.AcquireTokenAsync("https://api.partnercenter.microsoft.com", clientcred, new UserAssertion(idToken));
var pcAccessToken = result.AccessToken;
Should we use the same id token here on web api obtained from the ajax call. Or should we have to refresh the access token. If yes, how to do it on Web API?
Also, how can we generate the tokenCache at WebAPI?
Based on the description, it seems that you were accessing the web API which protect by Azure AD. And you want to access the partner center API in the web API.
And you integrated the web API with third-party application using MSAL(Azure AD V2.0 endpoint). However, AFAIK the Azure AD V2.0 doesn't support the like Partner Perter API(refer Restrictions on services and APIs).
If the Partner Center API is able to access by the token acquiring using the client credentials flow, then you can using this flow to acquire the token in the web API and call the Partner Center API.
The other way is using the on-behalf-flow. Here is the progress for this flow,
the third-party application acquire the access_token to call the web API. Then the web API acquire the token for Partner Center API using on-behalf-flow and call the Partner Center API using the new token. This solution using the Azure AD endpoint instead v2.0( register the app on Azure portal). And it is not able to using the MSAL to login since this library is for Azure AD V2.0 endpoint. We can use the azure-activedirectory-library-for-js to login with Azure AD endpoint.