Error AADSTS65001 but no consent prompt for just one user - azure-active-directory

I am writing a C# .NET app. It is connected to our service on Azure which is configured for using AAD. In turn, our service tries to make calls to Exchange via EWS.
This all worked fine for me until we recently deployed our service bits to a new Azure web app with new app registrations. They are all configured correctly and other developers on our team can authenticate with the service and use it as expected.
When I try to connect to the service, I get the following error:
AADSTS65001: The user or administrator has not consented to use the application with ID '61a8b794-7f67-4a01-9094-fcdd45693eaa'. Send an interactive authorization request for this user and resource.
Trace ID: ece7c5d0-2ecb-4096-a87a-2cd33271d65d
Correlation ID: 093b5935-3b06-4d76-91a9-6619bc179544
Timestamp: 2017-02-09 23:19:28Z
The consent prompt never appeared for me when trying to connect after deploying the new service.
I'm not sure what it is about my user account that causes this error to occur (it happens on multiple machines with my account) while others can connect successfully.
Here’s some of the code used to acquire the token in the service:
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
var upn = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn);
var email = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email);
var userName = upn != null ? upn.Value : email?.Value;
accessToken = bootstrapContext.Token;
ClientCredential clientCred = new ClientCredential("61a8b794-7f67-4a01-9094-fcdd45693eaa", appKey);
UserAssertion assertion = new UserAssertion(accessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/microsoft.onmicrosoft.com");
AuthResult = authContext.AcquireToken("https://outlook.office365.com", clientCred, assertion);
Any ideas why I wouldn't get the consent prompt, but other users on my team have?

Based on the description, you are developing multi-tier application using Azure AD.
Since you mentioned this issue was occurred after using the new app, did you config your new app as the knownClientApplications of your service app(61a8b794-7f67-4a01-9094-fcdd45693eaa)?
If yes, you should can give the consent for the service app when you sign-in your web app( refer here about multi-tier applications).
The problem why only you get this issue may others have given the consent to this app before.
Please let me know if it helps.

Related

deamon authentication on powerapps admin REST API

In scope of a compliance monitoring app for our powerapps usage, we created a C# console app which crawls powerapps.
environments
applications
permissions
(similar REST call than powershell commands Get-AdminPowerAppEnvironment Get-AdminPowerApp provided by Microsoft.PowerApps.Administration cmdlets)
proof of concept was done by stealing the Bearer header from fiddler when connected with my admin AAD account. POC is now validated, time to make it clean. And as often with AAD auth flow (for me), it's more complex than expected (sum up of hours of try & fails).
I find really little internet reference on how to authenticated & crawl (this part is ok) this API.
I tried different auth workflow and lib
MSAL
ADAL
fiddler on top of powershell command (but in powershell I'm not using a service principal)
and either I can't spot the correct scope or my service principal has no permission on the resource.
I have an App registration called AAA powerapps with ... quite a lot of permission (try & fails)
Created a client secret
just in case, put into Power Apps administrator
string authority = $"https://login.microsoftonline.com/[tenant-guid]/";
var app = ConfidentialClientApplicationBuilder
.CreateWithApplicationOptions(new ConfidentialClientApplicationOptions { ClientId = "[client-id]", ClientSecret = "[shhuuuu]" })
.WithAuthority(authority).Build();
// tried with https://management.azure.com/.default / https://api.bap.microsoft.com/.default / https://service.powerapps.com./default
var token = app.AcquireTokenForClient(new[] { "https://management.azure.com/.default" }).ExecuteAsync().Result;
//var client = new RestClient("https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments?api-version=2016-11-01");
var client = new RestClient("https://management.azure.com/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments?api-version=2016-11-01");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + token.AccessToken);
IRestResponse response = client2.Execute(request);
I get a token, but I don't think it's on the correct scope/resource unfortunately.
Depending on the scope, I either get
Forbidden
{"error":
{"code":"Forbidden","message":"The service principal with id '[service principal guid (not client id)'
for application <null> does not have permission to access the path 'https://api.bap.microsoft.com:11779/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments?api-version=2016-11-01' in tenant [tenant-guid]."}}
or
Unauthorized
{"error":{"code":"AuthenticationFailed","message":"Authentication failed."}}
Didn't succeed with client id & client secret but managed to call api.bap.microsoft.com/../Microsoft.BusinessAppPlatform with AAD user.
eg https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments?api-version=2016-11-01
re-used same method as Microsoft.PowerApps.Administration cmdlets
AAD account with AAD Power platform administrator role
If Multi Factor Access enabled for admin, create exception rule
use ADAL nuget Microsoft.IdentityModel.Clients.ActiveDirectory
dotnet
AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/common");
var credentials = new UserPasswordCredential("admin_powerapps#domain.net", "password");
// "1950a258-227b-4e31-a9cf-717495945fc2" = client ID for Azure PowerShell.
// available for any online version
var token = authContext.AcquireTokenAsync("https://management.azure.com/", "1950a258-227b-4e31-a9cf-717495945fc2", credentials).Result;
// any REST call
Header "Authorization" : "Bearer " + token.AccessToken
Endpoint : https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments?api-version=2016-11-01
results
The benefit from this method is that it can crawl "all" environments seamlessly (not sure the approach with creating a user on each was working).
Another approach I spotted was using Powerapps connector for admin but it involved extra configuration on each environments and required a license.
Not fully sure this method would be supported long term (eg xx.windows.net). Open minded for any other suggestion.
I was facing the same issue. What solved it with me is to register the app with tenant admin rights on the power platform admin using this command New-PowerAppManagementApp. Please, find MSFT article here.
After your client application is registered in Azure AD, it also needs to be registered with Microsoft Power Platform. Today, there's no way to do this via the Power Platform admin center; it must be done programmatically via Power Platform API or PowerShell for Power Platform administrators. A service principal cannot register itself—by design, the application must be registered by an administrator username and password context. This ensures that the application is created knowingly by someone who is an administrator for the tenant.
$appId = "CLIENT_ID_FROM_AZURE_APP"
# Login interactively with a tenant administrator for Power Platform
Add-PowerAppsAccount -Endpoint prod -TenantID $tenantId
# Register a new application, this gives the SPN / client application same permissions as a tenant admin
New-PowerAppManagementApp -ApplicationId $appId

How to Authenticate WPF Application with AAD B2C to gain access to Azure App Service

I'm quite stuck at the moment trying to implement authentication into a project I'm working on. The end goal of this project is to have two WPF apps and on web based app hosted on Azure. One WPF app is for an administrator, the other for staff, and lastly the web app for customers. Each application will be connected to one Azure App Service for a shared database and needs to have authentication so separate all the users. For authentication I am planning on using Azure Active Directory B2C.
I've been researching and trying to implement this for several days now on one of the WPF apps but as I stated before I'm quite stuck. From what I understand, the only way to do B2C authentication for WPF is through client managed authentication. Following the code shown on the Azure tutorial sites, other SO posts, and the Azure Git Repos, I have come up with the following code:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
authResult = await App.PublicClientApp.AcquireTokenAsync(App.ApiScopes,
GetUserByPolicy(accounts, App.PolicySignUpSignIn), UIBehavior.SelectAccount,
string.Empty, null, App.Authority);
Newtonsoft.Json.Linq.JObject payload = new Newtonsoft.Json.Linq.JObject();
payload["access_token"] = authResult.AccessToken;
MobileServiceClient msclient = new MobileServiceClient(App.AzureAppService);
MobileServiceUser user = await msclient.LoginAsync(
MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
Everything starts off great and I'm able to get my Sign-In policy to display. After logging in, I am given an IdToken and an AccessToken. After creating a JObject and adding the access token to it, I attempt to use it to login with my MobileServiceClient. But that's where I am having issues. No matter what I do, no matter what I try, I only get an exception with a 401 Error telling me I'm unauthorized. And this is the point I've been stuck at for the past few days.
Obviously I'm not doing anything special here and I imagine many people have done this before me but I just can't seem to get past this point and was hoping someone may be able to offer me some guidance. Am I way off track? Is there a better way that I could be doing this? Any suggestions or advice would be greatly appreciated as I am very new to Azure.
Thanks all!
Update:
Here's how I have my Azure Settings:
On the app service side
Client Id: "{Client Id of the AAD B2C App}"
Issuer URL: "login.microsoft.com{TennatName}.onmicrosoft.com/v2.0/.well-known/openid-configuration"
Allowed Token Audiences: "https://{App Service Name}.azurewebsites.net" (App Service URL)
On B2C side:
Web and native client enabled
Web Reply URL: "https://{AppServiceName}.azurewebsites.net/.auth/login/add/callback"
Native App: I did not know what custom redirect URL to have so I have both
"{TennatName}.onmicrosoft.com://auth/" and
"{AppServiceName}.azurewebsites.net/.auth/login/add/callback"
Update 2:
My authority is login.microsoftonline.com/tfp{tenant}/{policy}/oauth2/v2.0/authorize
And my ApiScopes = { "https://{Tenant}/thisisatest/user_impersonation" };
If the authority for the client is set to https://{your-tenant-name}.b2clogin.com/tfp/{your-tenant-name}.onmicrosoft.com/{your-policy-name}/, then the issuer URL in the app service must refer to the metadata for this authority; i.e. https://{your-tenant-name}.b2clogin.com/tfp/{your-tenant-name}.onmicrosoft.com/{your-policy-name}/v2.0/.well-known/openid-configuration.

Get SharePoint Office 365 data using Client Id

I am accessing SharePoint online list data using the following code but i get the following error.
The remote server returned an error: (403) Forbidden.
The web forms application is running in Azure and uses Azure authentication. I would like to use the same credentials for authentication
string siteUrl = "[url]";
string aadAppId = "[appid]";
string clientSecret = "[redacted]";
OfficeDevPnP.Core.AuthenticationManager authManager = new OfficeDevPnP.Core.AuthenticationManager();
ClientContext context = authManager.GetAzureADNativeApplicationAuthenticatedContext(siteUrl, aadAppId, appurl, null, AzureEnvironment.Production);
if (context != null)
{
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
}
I do not want to access the SharePoint using the user credentials.
I have enabled AAD Azure authentication on the web app. The web app authenticates with Azure credentials.
On the CORS setting i have also set the Domain Url to "https://domainname.sharepoint.com";
In the manage permissions section of AAD app I have given the app Permission to read and write sharepoint list and web data.
You example is attempting to retrieve a token as a native client application, which is an app that cannot keep a secret and cannot authenticate by itself. (That's why you'll notice you never use clientSecret.)
If you want to use OfficePnP, you can try one of the AuthenticationManager.GetAzureADAppOnlyAuthenticatedContext methods to authenticate in the app-only context. Note that they all require a certificate for authentication, rather than a secret.

Aquire Token with ADAL.Net throws Unknown User Type for Managed AD Account

I am trying to call a web (api) service using a OAuth2 token based on a AAD managed user account logged in to an AAD joined machine using ADAL.Net - specifically using this example:
https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/AcquireTokenSilentAsync-using-Integrated-authentication-on-Windows-(Kerberos)
However I keep getting the exception: Unknown User Type
In my setup I have logged onto a machine inside an AAD private network with a synced AAD user account. I then run the example code using WindowsAuthentication.
After some debugging I can narrow the exception to be thrown from this method in ADAL.Net
protected internal /* internal for test only */ override async Task PreTokenRequestAsync()
{
await base.PreTokenRequestAsync().ConfigureAwait(false);
if (!SupportADFS)
{
var userRealmResponse = await _commonNonInteractiveHandler.QueryUserRealmDataAsync(Authenticator.UserRealmUriPrefix)
.ConfigureAwait(false);
if (string.Equals(userRealmResponse.AccountType, "federated", StringComparison.OrdinalIgnoreCase))
{
WsTrustResponse wsTrustResponse = await _commonNonInteractiveHandler.PerformWsTrustMexExchangeAsync(
userRealmResponse.FederationMetadataUrl,
userRealmResponse.CloudAudienceUrn,
UserAuthType.IntegratedAuth).ConfigureAwait(false);
// We assume that if the response token type is not SAML 1.1, it is SAML 2
_userAssertion = new UserAssertion(wsTrustResponse.Token, (wsTrustResponse.TokenType == WsTrustResponse.Saml1Assertion) ? OAuthGrantType.Saml11Bearer : OAuthGrantType.Saml20Bearer);
}
else
{
throw new AdalException(AdalError.UnknownUserType);
}
}
}
Since everything in my setup is managed with AAD I do not see why the user account type needs to be "federated" in order for a token to be retrieved.
So I suspect that I need to get my token in another way!?
Any help will be appreciated ;)
After investigating we found that the above code (ADAL.Net) can only be used with a federated setup.
Federation means that you have an on premise network - which holds your windows user accounts - connected to an Azure AD network - which then "federates" these accounts to Azure AD. However it would be good to have a member of the ADAL team to comment on this.
Obtaining a token for a windows user account in a pure Azure AD (Managed setup) can supposedly be done using this code:
var connString = $"RunAs=App;AppId={appId};TenantId={tenantId};AppKey={appKey};";
var azureServiceTokenProvider = new AzureServiceTokenProvider(connString2);
var accessToken = azureServiceTokenProvider.GetAccessTokenAsync(service, tenantId).Result;
which is descripbed here: https://learn.microsoft.com/en-us/azure/key-vault/service-to-service-authentication#running-the-application-using-managed-identity
Again its not that well documented so any clarity from microsoft would be good.

Facing issues in consuming an Azure Active Directory enabled Azure Functions in a azure web application

I have enabled AAD Authentication for an Azure Function and then tried to consume the Function App (HTTP Trigger) in a web application but getting Unauthorized issue.
I also tried consuming it by creating a function proxy but the issue still persists.
Process Followed:
Created two AD Application (Web App, Azure Functions) and gave the
permission of Azure Functions AD to the Web App AD Created a basic
http trigger function
Enabled Authentication for Azure Functions by providing the details of Azure
Functions
Created a web application and during the access token generation, provided
the Client ID,Secret of web application and Audience URI( App ID) of Azure F
Unctions AD.
ClientCredential clientCredential = new ClientCredential(ConfigurationManager.AppSettings["ida:ClientId"], ConfigurationManager.AppSettings["ida:SecretKey"]);
AuthenticationContext authContext = new AuthenticationContext(Startup.Authority);
AuthenticationResult result = await authContext.AcquireTokenAsync(ConfigurationManager.AppSettings["azrfunc:ResourceID"], clientCredential);
string requestUrl = "https://xxxx.azurewebsites.net/api/HttpTriggerCSharp1?code=Gxxxxx==&name=xxxx";
// Make the GET request
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = client.SendAsync(request).Result;
According to your description, I assumed that you are using Authentication and authorization in Azure App Service for your azure function app.
And as How authentication works in App Service 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.
Based on your scenario, I created my two aad apps and set the required permission for my web app to access the aad app of my function app as follows:
And enable AAD authentication for my azure function app as follows:
Then getting the access token by using the following code:
var clientCredential = new ClientCredential("{clientId-for-my-web-app}", "{clientSecret-for-my-web-app}");
var authContext = new AuthenticationContext("https://login.windows.net/{tenantId}");
var result = await authContext.AcquireTokenAsync("{clientId-for-my-function-app}", clientCredential);
TEST:
In summary, you could decode your access token by using https://jwt.io/ and check the aud as follows:
Moreover, I noticed that your requestUrl contains the query string code. If you both enable the function level authorization and the user-based authentication, you also need to make sure your function key or master key is correct. Also, you could just set the anonymous authorization level for your azure function and just leverage the user-based authentication.

Resources