How access to instance of Dynamics 365? - xamarin

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;

Related

Using Microsoft Graph API without user (Application Identity) on Teams Custom App

I've been developing a Teams Custom App with the TeamsFx SDK.
I want to use the Microsoft Graph API using an Application identity.
So, I referred to the Microsoft official documentation, however I wasn't able to achieve what I wanted to do.
ใ€€- Referred document: https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/teamsfx-sdk.
Under "Create MicrosoftGraphClient service", "Invoke Graph API without user (Application Identity)" section.
I tried the following:
I created a new Teams app from "SSO-enabled tab" sample with Teams Toolkit on Visual Studio Code.
I edited a Graph.jsx as below to get a user info.
import { createMicrosoftGraphClient, IdentityType, TeamsFx } from "#microsoft/teamsfx";
useEffect(() => {
const getProfile = async () => {
const teamsfx = new TeamsFx(IdentityType.App);
const graphClient = createMicrosoftGraphClient(teamsfx);
const profile = await graphClient.api("/users/username#domain.onmicrosoft.com").get();
return profile;
};
const profile = getProfile();
}, []);
I debugged the project by hitting the F5 key in Visual Studio Code.
Although I tried what the document said, the console log said "Application identity is not supported in TeamsFx".
How should do I edit my projec to use Microsoft Graph API without a user identity (i.e. using Application Identity)?
Application Identity is not supported in browser (Tab page), so you need a server environment to use it.
You could add an Azure Function and use the Application Identity in it to achieve desired effect. Here's the steps in Teams Toolkit v4.0.1:
Create new project from "SSO-enabled tab" template.
Choose "Azure Functions" in "Add features" with default name.
Modify the code in "api/getUserProfile/index.ts".
teamsfx = new TeamsFx(IdentityType.App);
...
const graphClient: Client = createMicrosoftGraphClient(teamsfx, [".default"]);
const profile: any = await graphClient.api("/users/username#domain.onmicrosoft.com").get();
res.body.graphClientMessage = profile;
Configure "User.Read.All" permission and grant admin consent on AAD portal.
Run "F5" and click "Call Azure Function" on tab page, the Azure Function will be invoked and get Graph data using Application Identity. You should see the user information below.
What you're trying to do is insecure, because you have code running as Application level security, but running on the client side. Code running with that kind of privilege should only be running on the server side, or in this case behind a protected API (e.g. one that it validating the user's security using SSO to ensure the user is valid, and then executing on the server).
This video gives a bit of an idea of how it should be working: https://www.youtube.com/watch?v=kruUnaZgQaY
In the video, they're actually doing a token -exchange- (exchanging from the pure client side SSO token, and getting an "on behalf of" token in the backend, and making the call then). You can skip that part and just use the application token, but you should, as I mentioned, have this occurring in the server, not on the client.

Classroom API - Access classroom with Service Account

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??

Need to access sharepoint online addin rest api without azure ad registration

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

Sharing single WebApp and API deployment with multiple B2C Tenants

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()
};
}

Using Delegates with Exchange Web Services

Has anyone used delegates with exchnage web services? I would like one user to be able to control other users' calendars in Exchange. I'm finding this problem to be a little tricky, and I'd like to see how others have been able to get it to work properly.
I'm just getting started here, but i managed to get access to Resource calendars via a delegate account.
I used the recommendations from this article about delegate account and resource accounts. (Resource accounts are tricky because they are disabled in the AD, and you have to use a delegate account to get access to them)
After setting up the delegate account on the server, I set up the ExchangeServerBinding using the credentials of the delegate account:
ExchangeServiceBinding binding = new ExchangeServiceBinding();
binding.Url = #"https://dc1.litwareinc.com/ews/exchange.asmx";
// Setup binding with username and password of the delegate account
binding.Credentials =
new NetworkCredential(delegateuserName, delegatepassword, "litwareinc.com");
(I'm using Microsofts prepared virtual server image for testing)
Then when accessing the mailbox, I set up a FindItemType request and use the smtp address of the account i want to access:
// Prepare request
var findItemRequest = new FindItemType();
// Setup the mailbox using the smtp address of the account wanted
var mailbox = new EmailAddressType {EmailAddress = mailboxId};
findItemRequest.ParentFolderIds =
new[] {new DistinguishedFolderIdType {Mailbox = mailbox}};
((DistinguishedFolderIdType) findItemRequest.ParentFolderIds[0]).Id =
DistinguishedFolderIdNameType.calendar;
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
// Add ItemResponseShapeType and Calendarview to request here ...
// The create a FindItemResponseType using the binding and the request
var response = binding.FindItem(findItemRequest);
So in short:
Setup an account with delegate access on the Exchange server, this can be done via owa or with a Exchange Shell script
Use the account with delegate access on the ExchangeServiceBinding object
Access target account using a FindItemType with the target account smtp-addres as EmailAddressType
Regards
Jesper Hauge

Resources