Not able to use identity platform within iFrame/MS Teams custom tab - microsoft-teams

I am trying to use identity platform to authenticate users into my custom app that is to be used from within MS Teams.
I am aware that Teams uses iFrame to load the custom apps. So I followed the method mentioned in the FAQs - Q5. I used redirectUri property in the MSALConfig. I am using the index file provided by MS for testing purposes by calling it inside an iFrame tag.
In both cases of acquireTokenSilent and acquireTokenPopup, it gets stuck at the popup window loading the redirect page. Neither the authentication is getting completed nor the popup window getting closed.

The following steps can unblock the Teams Tab scenario for the desktop/mobile apps.
Manual Steps
Step 1. Assure you have approved requests in the new API Permission Management Page on the Tenant Admin Site. This creates a client secret behind the scenes.
Step 2. Go to -> https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview
Step 3. Click on SharePoint Online Client Extensibility Web Application Principal
Step 4. Click Manifest on the left menu
Step 5. Copy the id from the oAuth2Permission array
"oauth2Permissions": [
{
"adminConsentDescription": "Allow the application to access SharePoint Online Client Extensibility Web Application Principal on behalf of the signed-in user.",
"adminConsentDisplayName": "Access SharePoint Online Client Extensibility Web Application Principal",
"id": "2143704b-186b-4210-b555-d03aa61823cf",
"isEnabled": true,
"lang": null,
"origin": "Application",
"type": "User",
"userConsentDescription": "Allow the application to access SharePoint Online Client Extensibility Web Application Principal on your behalf.",
"userConsentDisplayName": "Access SharePoint Online Client Extensibility Web Application Principal",
"value": "user_impersonation"
}
],
Step 6. Replace “preAuthorizedApplications” entry with the following json
"preAuthorizedApplications": [
{
"appId": "00000003-0000-0ff1-ce00-000000000000",
"permissionIds": [
"ID OF THE USER_IMPERSONATION Scope"
]
}
],
Step 7. Hit Save.

This issue was solved by changing the implementation to use new feature - SSO instead of MSAL library.

Related

Remove sensitive information from source control for Blazor projects

I'm using the default template for Blazor Webassembly Hosted with ASP.NET Core (.NET 6), with Microsoft Identity enabled.
I was however, unable to figure out how it was able to authenticate with Microsoft AAD and what source files need to be removed from version control to prevent others from getting access to Microsoft authentication against my app registration.
I couldn't find anything in the Client project. In the Server project, I only found this configuration which the builder was binding but there was no Secret or Certificates (details and IDs changed for privacy)
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "contoso.com",
"TenantId": "4e590f17-467e-4085-adc1-1c4992f82f3a",
"ClientId": "e67489f6-44d1-4658-86b6-20eb1c71b154",
"CallbackPath": "/signin-oidc",
"Scopes": "access_as_user",
"ClientSecret": "Client secret from app-registration. Check user secrets/azure portal.",
"ClientCertificates": []
},
Would it be sufficient to just remove this file from version control? I would like to share the source code publicly.
How does the app registration work? Are the TenantId and ClientIds enough for letting an app use Microsoft Authentication?
I've broken the three main questions you have down and provided some resources for further info.
Q: Would it be sufficient to just remove this file from version control?
A: You are correct in saying that removing the configuration will indeed prevent others from being able to access your AAD via the app registration.
There is some useful documentation over on the Microsoft ASP.Net Core site that may be of some help with regards to authentication using AAD if you're looking for further information, the link is: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-azure-active-directory?view=aspnetcore-7.0
Q: How does the app registration work?
A: The Server project connects with AAD utilising the Tenant and Client ID's as well as a client secret or certificate to authenticate. The app registration acts works by providing a client secret and id to utilise within your project to manage permissions and access to your Azure resources through RBAC.
To quote the Microsoft documentation regarding App Registrations, "Registering your application establishes a trust relationship between your app and the Microsoft identity platform. The trust is unidirectional: your app trusts the Microsoft identity platform, and not the other way around." Source: https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
Q: Are the TenantId and ClientIds enough for letting an app use Microsoft Authentication?
A: You will also need to include the client secret or certificate in your config to ensure that your project successfully authenticates with AAD.
You will need to add a client secret to your App Registration as it is not created by default upon making an app registration. Here is the Microsoft documentation on creating a new client secret: https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app#add-a-client-secret
Hope these are of some help and good luck with your project!

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.

Visual Studio 2019 can't use Azure US gov AD for authentication in project creation?

Our Azure account is US government. I'm trying to create a new project in VS 2019 with "work or school accounts" authentication. Using "Cloud - Single organization", I provide my domain (ex mydomain.onmicrosoft.com). However it is not able to find my domain because it's looking in microsoftonline.com and not microsoftonline.us (the government domain platform). The error is:
Invalid domain name. No domain metadata was found at 'https://login.microsoftonline.com/mydomain.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml'.
Which is happening because it's supposed to use login.microsoftonline.us as opposed to .com
How can I get this to work with US government domain? I have set the environment to Azure US Government in VS, so I'm not sure where else VS is supposed to look.
Sorry for the late response on this. Spoke with the VS team and the feature that does this while creating new projects currently only works with Azure commercial - this new project experience will work with Azure Government later this year.
In the meantime, you can do auth the way you want with Azure Government - you just can't do it via this new project wizard. In fact, in the latest version of VS 2019, if you select the Microsoft Identity platform as your auth provider, it creates a JSON file like this:
{
/*
The following identity settings need to be configured
before the project can be successfully executed.
For more info see https://aka.ms/dotnet-template-ms-identity-platform
*/
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "qualified.domain.name",
"TenantId": "22222222-2222-2222-2222-222222222222",
"ClientId": "11111111-1111-1111-11111111111111111",
"CallbackPath": "/signin-oidc"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
You can just go into the Azure Government portal to create your app registration yourself. Then fill in the values in this json file by changing:
Instance: https://login.microsoftonline.us
Domain: your tenant
TenantId: your Azure Gov tenant
ClientId: your Azure Gov app registration ClientID

HTTP Google Sheets API v4 how to access without OAuth 2.0?

my idea is to create a google sheet, make it public and then access it from my work computer linux/bash to read/write values on a daily basis.
i have a public google doc sheet that anyone can find/edit.
this is the sheet ID: 1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0
doing it by the book https://developers.google.com/sheets/api/samples/reading
curl 'https://sheets.googleapis.com/v4/spreadsheets/1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0/values/Sheet1!A1:A3'
returns:
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"status": "PERMISSION_DENIED"
}
}
i've read a lot and especialy here Google Sheet API v4 i've found a complicated solution. that is if you want to access your public sheet in a short 1 hour period.
you browse to https://developers.google.com/oauthplayground/ get authorization for the v4 api, then get "Authorization code", then get "Refresh token", and finally "Access token".
using this "Access token" you can access the public sheet like this
curl 'https://sheets.googleapis.com/v4/spreadsheets/1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0/values/Sheet1!A1:A3' -H "Authorization: Bearer ya29.GlvaBLjrTdsSuSllr3u2nAiC-BOsjvIOE1x5afU3xiafB-FTOdLWDtfabuIMGF1rId5BsZxiTXxrx7VDEtxww4Q1uvW9zRndkfm3I2LZnT1HK2nTWzX_6oXu-NAG"
returns:
{
"range": "Sheet1!A1:A3",
"majorDimension": "ROWS",
"values": [
[
"a1"
],
[
"a2"
],
[
"a3"
]
]
}
perfect. in theory the "Access token" expires after an hour, the "Refresh token" never expires. so you would save the tokens, try to read the sheet with the "Access token", if it fails use the "Refresh token" to gain a new "Access token" and carry on.
but, i've had a dozen of "Refresh token"s that were redeemed/expired, "Authorization code"s expired, all in all nothing works after a few hours. why?
how can i access my google sheet form bash with curl without this kind of authorization?
especially since my sheet is public and can be edited by anyone with a browser.
is there another way to do this with some other permanent authorization?
why not use email and pass?
"API key" is mentioned but never explained. can some one please explain this method step by step?
All Google APIs require that you create a project on Google developer console and identify yourself and your application, even to access public data. Since you have set the sheet to public you can just go to google developer console and create a public api key remember to active the google sheets api. Then just add key=[YourKey] as a parameter on your request.
Update Dev console:
Create project and get key:
Google developer console -> create a project -> credentials drop down -> API Key
Enable it:
Google developer console -> library find sheets enable it.
Update:
{ "error": { "code": 403, "message": "The request is missing a valid API key.", "status": "PERMISSION_DENIED" } }
Means that you have not identified yourself to Google. In 2015 Google Start to require that we identify ourselves you cant just use a Google API without telling google who you are. You do that by creating a project on [Google developer console1. Create an API key and use that API key in all of your requests. This only works with Public data.
https://sheets.googleapis.com/v4/spreadsheets/1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0/values/Sheet1!A1:A3?key=YOurKEY
Note: With private user data you would need to use OAuth and use either access_token=your token or set the header
Authorization: Bearer ya29.GlvaBLjrTdsSuSllr3u2nAiC-BOsjvIOE1x5afU3xiafB-FTOdLWDtfabuIMGF1rId5BsZxiTXxrx7VDEtxww4Q1uvW9zRndkfm3I2LZnT1HK2nTWzX_6oXu-NAG.
An access token is not the same as a API Key.
If you don't want to mess with OAuth2, maybe the simpler solution is to use third-party soft. https://sheetdb.io allows you to work with Google spreadsheets and does OAuth2 for you. Additionally, the API is simpler than Google, check out the docs here: https://docs.sheetdb.io
Another approach is to share the sheet with a Google Cloud service account, and then use the service account to authorize with the API client. If the document is public you do not need to share it.
Instructions on creating a service account and reading a Google doc, which should also apply to sheets https://www.futurice.com/blog/read-goog-doc-using-service-account
A piece of advice - NEVER allow write access to a public Google Sheet.
Anyone can add lots of data and cause all sort of problems.
Always control access to who can edit.
Allow arbitrary edits by anyone programmatically is even worse. I can whip up a script that fill in your Google Sheet to capacity in seconds with garbage data. To everyone else viewing it, the sheet will look like a jumble of data.
Now to answer your question. Here are the basic steps for creating an OAuth 2.0 ClientID:
In the Google Cloud console, go to Menu menu > APIs & Services > Credentials.
Go to Credentials
Click Create Credentials > OAuth client ID.
Click Application type > Desktop app.
In the Name field, type a name for the credential. This name is only shown in the Google Cloud console.
Click Create. The OAuth client created screen appears, showing your new Client ID and Client secret.
Click OK. The newly created credential appears under OAuth 2.0 Client IDs.
Save the downloaded JSON file as credentials.json, and move the file to your working directory.
Follow the rest of the instructions for setting up the environment for a Go app to authenticate, authorize and manipulate the Google Sheet via Golang. For other languages, select the corresponding entry in the left sidebar of the web page.

Implementing an Identity Provider

I have implemented App Fabric Labs' mechanism for authentication into my MVC3 app so now I can log in with Facebook, Google, Yahoo and LiveID. yea!!
now, what if a user doesn't want to use any of those systems? I need to provide "traditional" signup forms. I'm thinking that calls for implementing an identity provider so my app can be left unmodified.
any templates/projects out there all ready for use?
thx - e
The WIF SDK comes with a few project templates: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=4451
To use them you have to start a new "Website" (not "Project") in Visual Studio: File -> New... -> Website
The "ASP.NET Security Token Web Site" template is what you want.
For a more complex STS solution I recommend you to have a look at http://identityserver.codeplex.com/.

Resources