client_secret not required on refresh token azure b2c - azure

I have an azure b2c application. When I create a user through the Users application in portal.azure.com (or making a post request with postman) I have to send the client_secret of my b2c app to refresh a token.
But with users created through Powershell with the azureAD module I have an error saying that I shouldn't send the client_secret.
{
"error": "invalid_request",
"error_description": "AADB2C90084: Public clients should not send a client_secret when redeeming a publicly acquired grant.\r\nCorrelation ID: 39abec35-770c-42e6-bd65-438d6501a124\r\nTimestamp: 2018-04-09 14:43:13Z\r\n"
}
Why is that difference? How can I do to create a user that not requires the client_secret using the graph api?
Thanks in advance!
Germán

According to the error message, I assume that the App that you're using is a Native app (as juunas said, Powershell is also a native app), which also called public client in Oauth. client_secret is only required when your application is Web App/API,which also called confidential client in Oauth.
Refreshing the access tokens with Native App:
// Line breaks for legibility only
POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&grant_type=refresh_token
&resource=https%3A%2F%2Fservice.contoso.com%2F
NOTE: The application secret that you created in the app registration
portal for your app. It cannot be used in a native app (public
client), because client_secrets cannot be reliably stored on devices.
It is required for web apps and web APIs (all confidential clients),
which have the ability to store the client_secret securely on the
server side.
So, you can just delete the client_secretin the request body to resolve that.
Additional, Azure AD B2C doesn't support client_credentials flow. See details about this here.

Related

How to authenticate a frontend SPA app and API when both use Azure Easy Auth

The situation
I have a backend API and frontend SPA app both hosted in Azure. I have protected both these app services with Azure AD Easy Auth using the same app registration. This works - if I try and visit the frontend application I am redirected to the Microsoft login page where I can login and if I visit the API I am returned a 401 (I can login to it interactively via /.auth/login/aad). In both applications, I can visit /.auth/me to retrieve the id_token and access_token among other things. My SPA app will query this endpoint to retrieve the id_token. It then uses this token to communicate with the API via a Bearer token. This communication works and I can successfully call endpoints in this way.
The problem I am facing is that after some time, the id_token stored and sent by the frontend becomes invalid. I assumed the frontend would ask the use to login again which would refresh the id_token but this does not seem to be the case. I did some digging and apparently I should be sending the access_token up instead of the id_token. However, my API rejects that with:
{
"code": 401,
"message": "IDX10511: Signature validation failed. Keys tried: '[PII is hidden]'. \nkid: '[PII is hidden]'. \nExceptions caught:\n '[PII is hidden]'.\ntoken: '[PII is hidden]'."
}
https://jwt.io also fails to verify the access token.
I am having a lot of trouble in finding resources/documentation for an SPA app and API which both use Easy Auth and how to get them to talk to each other.
Things already tried
Removing any Microsoft Graph permissions from the app registration
Changing the manifest "accessTokenAcceptedVersion" to 2 for the app registration
Enabling both "ID tokens" and "Access tokens" for "Implicit grant and hybrid flows" for the app registration in the Azure portal
Using cookie auth (sending up the cookie with requests from the SPA)
Exposing an API and adding a permission for it
What is the standard way of authenticating a frontend and a backend when both are protected by Azure Easy Auth? Should I be using the access_token or id_token to authenticate? If the latter, how do I refresh it?
Looks like you are receiving access token for graph .
Please make sure scope is created for the backend web api .
Note:User.Read is for graph api access and may have nonce in token
generated which may make the signature invalidated for you web api.
So please create a new scope in the portal that identifies your backendapi i.e ; modify your app to acquire an access token for your API.
Your spa App > Expose an API > Add Scope.
(Create a new scope: say name = access_as_user)
In API permissions: Add a new permission for registered application and scope access_as_user. something like api://<app id>/ scope name
Make sure you place this name of scope where ever you are using in your app scope ( remove user.read if present and add scope of your api) and grant admin consent .
Now try again and check the token in https://jwt.io .
If there is further error saying audience invalid:
Go to Manifest: Change entry "accessTokenAcceptedVersion" from (null or 1) to 2
And try .If not successful ,try by removing api:// prefix from your app configuration scope.
References:
Tutorial: Authenticate users E2E - Azure App Service | Microsoft
Docs
azure - Setting additionalLoginParams with auth v2 - Stack Overflow
IDX10511 -issue (github.com)

Incomplete bearer token when using authentication-managed-identity tag in azure api management

I've been trying to expose an API through azure API Management and I can't figure out what I'm doing wrong. Here's the situation:
My API is going to be called from an external application
They don't have an Azure Account in the same tenant
I want to enable external calls for my API by just using a subscription key (hence, why I'm using API Management), but also want to keep my actual API secured with Azure AD.
I have an API which is secured with Azure AD using OAuth2 and published into a Windows AppService
I have an App registration for that API, which i use to authenticate (it works from postman, for example)
app registration
I have Managed Identities turned on and permissions set.
I have added the API in API management
I added the authentication-managed-identity inbound rule, used the API Id Uri of the app registration as the resource value for it.
Api Management Config
When testing an endpoint from the APIM interface, I can successfully get a bearer token, but I get a 500 exception from the API which says: Neither scope or roles claim was found in the bearer token
bearer response
Here is the decoded bearer token, it doesn't have a scp attribute
bearer decoded
I'm not sure where I can specify a scope. If I use the full scope uri (api://guid/access.api.management) it will fail when trying to get a bearer token (The resource principal named api://guid/access.api.management was not found in the tenant).
I've even tried adding the Owner role to the APIM Identity for the AppService.
Maybe I'm not using this correctly, I'm pretty new at using Azure cloud and API Management so any suggestions are welcome.
Thanks.
You have expose an api protected by Azure, and currently you have an api application. Next, you need to create another application that represents the client, and then add the client application to the api application.
Next, go to the client application.
Under 'API permissions' click on 'Add permission', then click on the 'My APIs' tab.
Find your api application and select the appropriate scope.
Click 'Add permissions'.
Grant admin consent for your APIs.
Next, you need to use the auth code flow to obtain an access token,which requires you to log in to the user and obtain the authorization code, and then use the authorization code to redeem the access token.
1.Request an authorization code in the browser.
https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize?
client_id={client app client id}
&response_type=code
&redirect_uri={redirect_uri}
&response_mode=query
&scope=api://{api app client id}/{scope name}
&state=12345
2.Redeem token.
Parse the token:
I managed to get it working using the client credentials flow and storing the client secret in key vault.

Azure AD B2C Resource Owner Password Credentials Authentication

In my application I want to call Azure Web API using Resource Owner Password Credential flow. I have implemented Azure AD b2c Auth for my Web API. I have created 2 Application in Azure, one for Web API and Native client App for ROPC. I gave WEB Api Access in ROPC app. I followed this article and got the Token from ROPC app. But when i pass my ROPC token to Web API I am getting 401. I dont know how to pass the scope of my web api scope in ROPC Token Request. Any help would be appreciated
Thanks in Advance,
Subbiah K
When you are requesting /token from Native APP (ROPC flow), you can add scopes in the request.
From the doc scope default set to
openid <ApplicationId/ClientId> offline_access
Modify this to like below to add scopes from Web API app. Make sure you should not put ClientId in scope
`openid https://tenant.onmicrosoft.com/hello/demo.read https://tenant.onmicrosoft.com/hello/user_impersonation offline_access`
Hope you already given API access (scopes) to Native Application.
Once you get access_token, that token will contain all the scopes you requested and you can send this to Web API to authorize.

Authenticate Azure app service with AAD custom login in mobile app

I have created app service for mobile app. Then i have added Authentication to the app service. Then Selected Authentication type as "Log on with Azure AD". It is working fine.
Is it possible to have custom login page instead of browser based login screen?
I was able to get the token by using https://login.microsoftonline.com//oauth2/token. But not able to authorize the app service with this bearer token.
Is it possible to have custom login page instead of browser based
login screen?
This page is the authentication endpoint of AzureAD. Though it can be configured by Company branding, I think it cannot be customlized by yourself for Moblie APP.
I was able to get the token by using
https://login.microsoftonline.com//oauth2/token. But not able to
authorize the app service with this bearer token.
Authencation/Authorization for Web App is a feature that securing Web App behind those IDPs, NOT just like other azure resources you can use REST API to access it. I understand what you want to do . But this action is not recommended or supported.
I was able to get the token by using https://login.microsoftonline.com//oauth2/token. But not able to authorize the app service with this bearer token.
As juunas answered, your token may does not match the AAD provider you configured on Azure Portal. Details you could follow here to check your configuration. Moreover, you could use https://jwt.io/ to decode your access_token and validate the related properties (e.g. the aud should be the clientId you configured on Azure Portal,etc.).
As App Service Authentication / Authorization (EasyAuth) states as follows:
Users who interact with your application through a web browser will have a cookie set so that they can remain authenticated as they browse your application. For other client types, such as mobile, a JSON web token (JWT), which should be presented in the X-ZUMO-AUTH header, will be issued to the client. The Mobile Apps client SDKs will handle this for you. Alternatively, an Azure Active Directory identity token or access token may be directly included in the Authorization header as a bearer token.
For Azure Web App or Azure Mobile App, you could just access your endpoint as follows:
https://{your-app-name}.azurewebsites.net/api/values
Header: Authorization:Bearer {the id_token or access_token of AAD}
Or
https://{your-app-name}.azurewebsites.net/api/values
Header: x-zumo-auth:{authenticationToken}
Moreover, if you retrieve the access_token in your mobile app, you could also use it to retrieve the authenticationToken and use the authenticationToken for communicating with the backend endpoint.
POST https://{your-app-name}.azurewebsites.net/.auth/login/{provider-name,for your scenario, it would be AAD}
Body: {"access_token":"<your-access-token>"}
For your mobile client, you could use the client for Azure Mobile Apps, details you could follow here. Also, you could follow Authenticate users to understand the client-flow and server-flow authentication for App Service Authentication.
As Wayne Yang said, customization of the login page is limited to logos and some text.
I'm not sure if you can use the "Easy Auth" for APIs.
You might need to actually implement the authentication in your app.
In that case your API would validate the incoming JSON Web Token so that its signature is valid and that the audience and issuer are what is expected.
Most frameworks have JWT authentication available, so it mostly comes down to configuring that properly.

MobileServiceClient InvokeApiAsync gets 401 while try to access asp.net core web api

I have a Xamarin Forms app that intereacts with a Asp.net Core Web api hosted on Azure App Service with client authentication flow with Azure B2C authentication.
The app can login succesfully to the Azure with the LoginAsyc (I get the idtoken) but when I try to invoke a service that requires authorization using the MobileServiceClient I get a 401. The api is called using the InvokeApiAsync.
If I invoke a an api method that does not require authorization it works fine.
I opened the Azure logs, and only see 401 error.
Any idea how to call this secure action method from Xamarin using the MobileServiceClient.
Please help
David
The app can login succesfully to the Azure with the LoginAsyc (I get the idtoken) but when I try to invoke a service that requires authorization using the MobileServiceClient I get a 401. The api is called using the InvokeApiAsync.
According to your description, I assumed that you are using App Service Authentication / Authorization. For Client-managed authentication, you directly contact the AAD identity provider and retrieve the id_token or access_token. At this time, you could just access the authorized endpoint as follows:
https://{your-app-name}.azurewebsites.net/api/values
Authorization: Bearer {aad id_token or access_token}
Note: When constructing the MobileServiceClient, you could pass your custom DelegatingHandler to append the bearer token before sending request(s) to your Azure backend.
I just created a single Native app in my B2C tenant and use MSAL to retrieve the id_token or access_token as follows:
var authority = "https://login.microsoftonline.com/tfp/{Tenant}/{Policy}";
PublicClientApplication IdentityClientApp = new PublicClientApplication("{native-app-id}", authority);
IdentityClientApp.RedirectUri = $"msal{native-app-id}://auth";
var scopes = new string[] {
//"https://bruceb2c.onmicrosoft.com/EasyAuthB2CApp/user.read"
""
};
var result=await IdentityClientApp.AcquireTokenAsync(scopes);
Note: I just created a single native app, the parameter scopes in AcquireTokenAsync method does not support the clientId, so I just pass the empty scopes, at this point, you would not receive the access_token, you just need to use the id_token as the bearer token to access your Web API. For the Web API web app, I used the native app to configure my AD authentication on Azure Portal.
Moreover, you could create a native aad app for your mobile client and a WebAPI aad app for your azure web app. At this time, you could specify the valid scopes for your native aad app to access the WebAPI app. Then, you would retrieve the access_token, at this time you need to set the WebAPI app id as the Client ID or add it to the ALLOWED TOKEN AUDIENCES list on Azure Portal.
In summary, you need to make sure the aud property in the id_token or access_token matches your Azure Active Directory Authentication Settings on Azure Portal. Note: You could use https://jwt.io/ to decode the token and check the related properties.
Moreover, for client flow authentication using LoginAsync, you need to pass the access_token to log in with your web app, then you would retrieve the authenticationToken. And the mobile client library would add the authenticationToken as the x-zumo-auth header to the subsequent requests (e.g. using MobileServiceClient.InvokeApiAsync).
Additionally, here are some tutorials, you could refer to them:
App Service Auth and Azure AD B2C
Integrate Azure AD B2C into a Xamarin forms app using MSAL
Azure AD B2C: Requesting access tokens
ASP.NET Core 2.0 web API with Azure AD B2C using JWT Bearer middleware

Resources