How to add simple authentication to azure mobile/web apps with Azure Active Directory? - azure

My goal is to secure my mobile app custom API methods and use then via httpclient(c#).
As a part of the testing I used Postman to request a token and use it to access the resource.

I will explain with the vanilla template that comes when creating a new Mobile App.
Create a new mobile app.
Publish it to Azure.
Open it on Azure portal, Go to Settings blade. Find Authentication / Authorization.
Turn App Service Authentication to On and select Azure Active Directory>Express>Create a new AD app.
Open Active Directory (Management Portal), pick the directory for your account.
Select Applications, the one you just created.
Go to Configure tab and copy the ClientId, Create a Key, copy it too.
Click on View EndPoints at the bottom and copy the OAuth 2.0 Token EndpointOauth2.0 Token
Now open the mobile app project and decorate the controller/method you want to project with [Authorize].
You should be all set with the setup.
Now open your favorite client, in my case Postman and
Step 1: Request a token
Method: POST
URL : {Oauth TokenEndPoint from Step. 8}
grant_type : client_credentials
client_id : {one copied from AD section in Step. 7}
client_secret : {one copied from AD section in Step. 7}
resource : {one copied from AD section in Step. 7}
You will receive a response like this
"token_type": "Bearer",
"expires_in": "3600",
"expires_on": "1453151213",
"not_before": "1453147313",
"resource": "yyyyyyyyyyyyyyyyyy",
"access_token": "xxxxxxxxxxxxxxxxxxx"
Now copy the access_token and use it in your request to the mobile app.
Method: Get
URL : https://MyMobileApp.azurewebsites.net/api/values?ZUMO-API-VERSION=2.0.0
Headers : Authorization : Bearer xxxxxxxxxxxxxxxxxxx
In case if you run into any issues, here is a key step. Go to Azure portal and turn on Application Logging, Detailed error messages, Failed request tracking under Diagnostics logs (Settings blade).
Now you can see whats happening and much more detailed logging under Log Stream(Tools blade).

Related

Generate Embed Token using Power BI REST API 403 error

We are currently working on Embedding Power BI Reports into our web application. To achieve that we are following the instructions on official power bi documentation:
https://learn.microsoft.com/en-us/power-bi/developer/embed-service-principal#get-started-with-a-service-principal
We are on the “app owns data” case thus we will user service principal. There is also “access with master account” option but I could not find a way to generate token via REST API, it works only via .NET samples provided which is not compatible with out stack. Moreover, in all the samples I have examined, token is retrieved from the security context of currently logged in user(So not via REST API). So “access with master account” is not an option for us.
We followed the steps in the link above one by one:
Registered a server-side web application.
Created a security group in Azure AD and added our new server side
web application to this group.
Enabled service principal (as power bi admin) for the new security
group we created.
Created and published our reports.
Added the service principal as an admin to the workspace (new
workspace ) that we have created.
On step 6 where we embed the report in our applications we are having issues. Here is what we do:
Generate Access Token For Service Principal.
URL: https://login.microsoftonline.com/{$tenantId}/oauth2/v2.0/token
Request Body:
grant_type: client_credentials
scope:https://graph.microsoft.com/.default
client_id:${clientId} (from our created server-side web application) >
client_secret:${client_secret} (from our created server-side web application)
Header: Content-Type:
application/x-www-form-urlencoded
Response: {
"token_type": "Bearer",
"expires_in": 3600,
"ext_expires_in": 3600,
"access_token": "eyXXXXXXXXXXXXXXXXX....XXX" }
Generate Embed Token using Power BI REST API
URL:
https://api.powerbi.com/v1.0/myorg/groups/${groupId}/reports/${reportId}/GenerateToken (groupId and reportId fetched from power bi dev portal where we have our reports)
Request Body: { "accessLevel": "View", "allowSaveAs": "false" }
Header: Content-Type: application/json
Charset:utf-8 Accept: application/json
Authorization: Bearer ${access_token_from_step1}
Response: HTTP 403 (which means forbidden)
Unfortunately we are stuck at this point. We can not generate embed token which we will use to embed our reports/dashboards into our application. Although we have been through lots of online docs/discussions we could not find a solution. So here is what we need help.
Notes:
-We are creating/publishing reports using Power BI Desktop and our power bi pro account. (Although we are trying to embed them using service principal)
-We have run into this stackoverflow answer that claims we need to use resource owner flow instead of client credentials flow. But I believe it is against power bi documentation that states service principal can be applied without using any user/password.
The scope you defined when generating Access Token For Service Principal is not correct.
Try to use https://analysis.windows.net/powerbi/api/.default instead of https://graph.microsoft.com/.default
Note: There are many limitations when use service principal.

How to call azure graph api using postman

I am trying to call graph api to get user information. I am using postman to get the token first and then using that token trying to make a request to graph api
I get the token with below post request and with 4 key values for grant_type, client_id, client_secret and resource.
https://login.microsoftonline.com/{{tenantid}}/oauth2/token
The response is
{
"token_type": "Bearer",
"expires_in": "3600",
"ext_expires_in": "3600",
"expires_on": "1555583717",
"not_before": "1555579817",
"resource": "https://management.azure.com/",
"access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxNiIsIng1dCI6IkhCeGw5bUFlNmd4YXZDa2NvT1UyVEhzRE5hMCIsImtpZCI6IkhCeGw5bUFlNmd4YXZDa2NvT1UyVEhzRE5hMCJ9.yyyyyyyLTBjYjZmZDNiM2UwNCIsInRpZCI6IjM3NGY4MDI2LTdiNTQtNGEzYS1iODdkLTMyOGZhMjZlYzEwZCIsInV0aSI6ImVWTWdDbkU4QWtPVXY3bFQ2QlRSQUEiLCJ2ZXIiOiIxLjAifQ.kxHCm2oGsuUvlXbncXQe7Wb0l-ZENqqG9_P_co0SPdYA3GkhFKDi6sQ7OaaHeDs4S6kN0-Diw5qBOzmFipSA5EUorA7UDbJfiSVVlaEzLY3IX_4WSV4Exc-kLOaX0j7KgvsEQbc5TEk8e4dPfokG98gGPmhy19xLyV84lX1v6DzgXINzP8gPkGmqR_J7iVFQ3m-Y18dHlxDpqQMTKxvQGnrsa7rflyxGUwEwwFZJH8t5NRv_mjQOIQBuosfhMAH88l-J8zEmXWLFqEzFBBWrz9UxT6X-XxRQZW4WBSoHTKd3vuBcEo6kUclfe4G7COOvI4zG0-j10mmGziKlzjNVMw"
}
Then I use the token to make GET request
https://graph.windows.net/{{company}}/users/{{email}}?api-version=1.6
and header
Key Value
Authorization Bearer {{token}}
but it fails with this error
{
"odata.error": {
"code": "Authentication_MissingOrMalformed",
"message": {
"lang": "en",
"value": "Access Token missing or malformed."
}
}
}
What is the correct way to make a request to graph api ?
Updated answer according to your case
Okay I am showing the step from the beginning. Make sure you have complete following step exactly.
Step:1 : Application Registration
Go to your azure portal and click on azure active directory. Now click on App registrations and Enter a name for your app. Make sure you have select Web app / API as application type. Put any Sign on URL it does not have any impact though.
See the screen shot below:
Step:2 Application Configuration
Configure your application setting by clicking on settings option. Copy the Application Id which is your client ID. Generate your client_secret on Key menu. Now click on Required permission option and click on Add at new window. Choose Select an API choose Microsoft Graph Then Select it.
See the below screen shot
So your azure portal configuration is all set.
Step:3 Token Access Flow
For getting token I am using OAuth 2.0 Client Credentials Grant Flow. Let fire up POSTMAN Enter your token endpoint your like below:
https://login.microsoftonline.com/`YourTenantNameOrID`.onmicrosoft.com/oauth2/token
Enter following data in right format:
grant_type:client_credentials
client_id:Your Portal Application ID
client_secret:Your application Key
resource:https://graph.microsoft.com/
Note: I am using Microsoft Graph API so resource has chosen
//graph.microsoft.com/
See the screen shot for more details
Step: 4 Check Claims Of your Token
You can make sure your token contains required information by validating it claims on JWT. You can use https://jwt.io/ to validate your token.
See the picture of claims below:
Step:5 Access Your Microsoft Graph API Resource
Define your Microsoft Graph API resource URL
For example : https://graph.microsoft.com/v1.0/users
Select your API http verb
Select Your Token Type to Bearer Token
Enter your token on left token text box
You are done click send and check your response as expected. See the screen shot for details.
Request Format:
Response From API:
Note: Make sure you have resource access permission unless you would get access denied error.
For more information you could take a look here
If you have any more confusion feel free to ask in comment line. Thank you and Happy coding!

oAuth2 - AADSTS90009 : Issue in connecting Azure Active Directory

I am getting below error while connecting to Azure Active Directory
"AADSTS90009: Application 'xxxxxxxxxxxxxxxxx' is requesting a token for itself. This scenario is supported only if resource is specified using the GUID based App Identifier.
If you want to use web application to call web API, please refer to the sample. The detailed steps.
Register your Web API application in Azure Portal. For more details, please refer to the document.
Register your Web app application in Azure Portal
Grant permission.(add you web API application in you web app application)
a. select you web application
b. set permissions.
Get access token
Method : POST
URL : https://login.microsoftonline.com/ [Directory ID]/oauth2/token
Headers
Cache-Control : no-cache
Content-Type : application/x-www-form-urlencoded
Body
grant_type : password
resource : Your App ID URI
client_id : [application id]
client_secret : [key value]
username : [account name]
password : [Password]
This error is saying that the field you provided in the resource parameter is requesting tokens for itself.
Alternatively, you can provide an app ID URI of a web API you've registered or another resource with scopes to get tokens for that resource (Microsoft Graph, Office API, etc).
The error information indicates that you are using Azure AD application url as resource.
As qwe mentioned that you need to use the WebApp API(Not Azure AD application) you wanted to access as resource. For more information please refer to this link.
POST https://login.microsoftonline.com/{tenantId}/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id={clientId}&client_secret={secret key}=&resource={resourceaddress}
Note: If we want to use the OAuth 2 grant type: password, we need to registry Azure AD native application. For more information please refer to another SO thread.

B2C OAuth2 API error: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier

I have spent quite a bit of time getting our .NET MVC web application to integrate with Azure Active Directory B2C, with reasonable success, using a custom profile to allow users of other Azure Active Directories to log in to us.
Now I want to incorporate an API, roughly following this process:
https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi
I say roughly because I'm trying to fit this functionality into an application that's already been under development for several months.
I'm using Postman to hit this URL a and get a bearer token:
https://login.microsoftonline.com/ourtenant.onmicrosoft.com/oauth2/token
I use the grant_type=client_credentials, and the client_id and client_secret specified in Active Directory (added in the the "not-B2C" App registrations blade because apparently B2C doesn't yet support the client_credentials flow)
It appears to work fine and I get a response like this:
{
"token_type": "Bearer",
"expires_in": "3599",
"ext_expires_in": "0",
"expires_on": "1513906161",
"not_before": "1513902261",
"resource": "00000002-0000-0000-c000-000000000000",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyIsImtpZCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMvIiwiaWF0IjoxNTEzOTAyMjYxLCJuYmYiOjE1MTM5MDIyNjEsImV4cCI6MTUxMzkwNjE2MSwiYWlvIjoiWTJOZ1lKaTJWbkhKTXQwNUcrZmMrL2pFNmRQLzdRQT0iLCJhcHBpZCI6IjZkZmVkNGVkLTU2ZDktNDQ5Ny04M2JhLTkzOWJmNGI3OGUyNSIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzdiNjVkNjQ0LTE0MzQtNDFkNC1hMWEwLTgyNWVmODA5MDJkMy8iLCJvaWQiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJzdWIiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJ0ZW5hbnRfcmVnaW9uX3Njb3BlIjoiTkEiLCJ0aWQiOiI3YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMiLCJ1dGkiOiJjV2lzVmxDRDEwdW9Ra3BHbWRBdkFBIiwidmVyIjoiMS4wIn0.BiXHI5Sp0t2k_npJYdWjclSXGOMbxniR8G1ifOCNUuiNUZRFG6DsbIqkJEBXSFFUxQpvtGkBaI5oF2u4oJ5Ed37thh_gOLJ1TKBaubGusv7vgUVoIk9A5F8H_HeX57zyRR2XU3czdSC4uZC_XpVwV7eT4-Z4bNooL0WJi1ZNx6ZFBC4qktNf7yifc7-iAEEDTWj3clwA81RJwAe9YbUMI3q640sNg8QlrZDiKFzuEuFocHces0bAYSyfLu5cwDw2wvJwQzYEMahjQ3V7RXpqg-YktsUoSTkLOHm7QNrM2Pko8ZAye58O-nTv1gD5yYDZ8st74x4MUHhNZhaR44byjw"
}
When I use this bearer token in the Authorization header an API call, I get the response:
{"Message":"Authorization has been denied for this request."}
I switched on diagnostic tracing and found this in the output:
Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
System.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 2,
Clause[0] = X509ThumbprintKeyIdentifierClause(Hash = 0xC78EFCC723A996C3351FB35793B4B1D7BC75BA97),
Clause[1] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
)
',
token: '{"typ":"JWT","alg":"RS256","x5t":"x478xyOplsM1H7NXk7Sx17x1upc","kid":"x478xyOplsM1H7NXk7Sx17x1upc"}.{"aud":"00000002-0000-0000-c000-000000000000","iss":"https://sts.windows.net/7b65d644-1434-41d4-a1a0-825ef80902d3/","iat":1513901664,"nbf":1513901664,"exp":1513905564,"aio":"Y2NgYPg7bbbRmu/aXjwejXZs73e5AgA=","appid":"6dfed4ed-56d9-4497-83ba-939bf4b78e25","appidacr":"1","idp":"https://sts.windows.net/7b65d644-1434-41d4-a1a0-825ef80902d3/","oid":"1a614c9c-4779-4697-98c4-99cee2ee5dcb","sub":"1a614c9c-4779-4697-98c4-99cee2ee5dcb","tenant_region_scope":"NA","tid":"7b65d644-1434-41d4-a1a0-825ef80902d3","uti":"5nMOpv6eok60JyzWwksuAA","ver":"1.0"}
RawData: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyIsImtpZCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMvIiwiaWF0IjoxNTEzOTAxNjY0LCJuYmYiOjE1MTM5MDE2NjQsImV4cCI6MTUxMzkwNTU2NCwiYWlvIjoiWTJOZ1lQZzdiYmJSbXUvYVhqd2VqWFpzNzNlNUFnQT0iLCJhcHBpZCI6IjZkZmVkNGVkLTU2ZDktNDQ5Ny04M2JhLTkzOWJmNGI3OGUyNSIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzdiNjVkNjQ0LTE0MzQtNDFkNC1hMWEwLTgyNWVmODA5MDJkMy8iLCJvaWQiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJzdWIiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJ0ZW5hbnRfcmVnaW9uX3Njb3BlIjoiTkEiLCJ0aWQiOiI3YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMiLCJ1dGkiOiI1bk1PcHY2ZW9rNjBKeXpXd2tzdUFBIiwidmVyIjoiMS4wIn0.mPzogfR2ndo89P-qWIypdPjrrBb0uEOO0Fo-H164C4Rm21zFQpkwVSFe-NP4MtvMnB5fJdhzGxzPDACFHBiQi7k7ZZVGv5bWaIbhGlPmKCQ1j6XaweYp7pm66R-RIsokZvR87nJ4ZkvYJIkuxnXPjChC-3FjsLDf43FKcByDPvvJKpVj48JW9N79vq77HQ2w8bnq172zOUflxGbuC2nDiwzkgWQiFboL-H3LLUxHqZHeE46u7pDSOrE3DSY1F5aPqBq1IDCg6ELcBcaLN27509oAH2rghkvXjHWOs9Nw3tszVoza7CpEGV7fjtSGN874GV_vx-ziqIOf1EgSBPEH6Q'.
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateToken(String securityToken, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.Owin.Security.Jwt.JwtFormat.Unprotect(String protectedText)
at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()
What am I missing?
The sample that you linked shows you how to secure and call a web API using Azure AD B2C. It seems like you are trying to obtain an Azure AD token, and then trying to use that to sign into an API that is secured using Azure AD B2C.
While client credentials is not supported in Azure AD B2C, it doesn't seem like you need the client credential flow. Client credential flow is used for an API to API call. If you want to call an API from the app that the users are signing into, you can use access tokens. Check out this document: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-access-tokens

Azure AD Token Issuing Endpoint doesn't return "scope" parameter

I'm querying the Microsoft Graph using a service app as described in this article: http://graph.microsoft.io/en-us/docs/authorization/app_only
I'm successfully able to make the POST request to the tenant-specific URL and get the JSON response specified:
{
"token_type": "Bearer",
"expires_in": "3599",
"scope": "User.Read",
"expires_on": "1449685363",
"not_before": "1449681463",
"resource": "https://graph.microsoft.com",
"access_token": "<token>"
}
except the "scope" parameter is missing. I have all "Office 365 Exchange Online" "Application Permissions" checked in my AD configuration panel. When using the returned token against the Graph API, I'm able to successfully call https://graph.microsoft.com/v1.0/users/ but no other endpoints.
I just had this issue and wanted to elaborate on the answer marked as correct since it is the correct answer but an incomplete solution. If there are no scope parameters, it means that your app is registered, however the admin has not consented to the app accessing your AD instance. Once you register your app, you have to build and go to the following URL to authorize the app (with admin account, of course):
GET https://login.microsoftonline.com/{TenantID}/adminconsent?
client_id=<APP ID>
&state=<This is optional for your app to use>
&redirect_uri=<ReturnURL>
TenantID: comes from Azure portal - if you click on the Help icon in the upper right and then choose 'Show Diagnostics' you can find the tenant id in the diagnostic JSON.
AppID: comes from the Azure portal - when you register your app, you go to the management console and cut/paste
This article has a TON of useful info for people trying to do graph integration.
You need to select the application scopes from the list available in the Microsoft Graph service then have the admin consent

Resources