Multiple Prompt Values for Microsoft Identity Endpoint - azure-active-directory

Is there a way to include both login and consent prompts via Microsoft Identity platform?
The docs do NOT explicitly mention support for multiple prompt values:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
I attempted this PowerShell script with space delimited login and consent values. The space is encoded as "%20" e.g., prompt=login%20consent.
$clientId = "MyClientId
Start-Process "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=$clientId&scope=openid%20profile%20https://ads.microsoft.com/ads.manage%20offline_access&response_type=code&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient&state=ClientStateGoesHere&prompt=login%20consent"
$code = Read-Host "Grant consent in the browser, and then enter the code here (see ?code=UseThisCode&...)"
Write-Output "code: " $code
$response = Invoke-WebRequest https://login.microsoftonline.com/common/oauth2/v2.0/token -ContentType application/x-www-form-urlencoded -Method POST -Body "client_id=$clientId&scope=https://ads.microsoft.com/ads.manage%20offline_access&code=$code&grant_type=authorization_code&redirect_uri=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fnativeclient"
$oauthTokens = ($response.Content | ConvertFrom-Json)
Write-Output "Access token: " $oauthTokens.access_token
Write-Output "Access token expires in: " $oauthTokens.expires_in
Write-Output "Refresh token: " $oauthTokens.refresh_token
This results in an unsupported prompt error:
Request Id: 9e072f53-23f2-4317-9dda-240e18c15c00
Correlation Id: f7a29334-c4e3-40d4-9810-c22f6a78c4d9
Timestamp: 2020-01-31T15:57:50Z
Message: AADSTS90023: Unsupported 'prompt' value.
Via the live endpoint I can include space delimited login and consent prompts. The space is encoded as "%20" e.g., prompt=login%20consent. This PowerShell script prompts for login and consent as expected.
$clientId = "MyClientId"
Start-Process "https://login.live.com/oauth20_authorize.srf?client_id=$clientId&scope=bingads.manage&response_type=code&redirect_uri=https://login.live.com/oauth20_desktop.srf&prompt=login%20consent"
$code = Read-Host "Grant consent in the browser, and then enter the code here (see ?code=UseThisCode&...)"
$response = Invoke-WebRequest https://login.live.com/oauth20_token.srf -ContentType application/x-www-form-urlencoded -Method POST -Body "client_id=$clientId&scope=bingads.manage&code=$code&grant_type=authorization_code&redirect_uri=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf"
$oauthTokens = ($response.Content | ConvertFrom-Json)
Write-Output "Access token: " $oauthTokens.access_token
Write-Output "Access token expires in: " $oauthTokens.expires_in
Write-Output "Refresh token: " $oauthTokens.refresh_token

As the error shows, it's unsupported to set both login and consent prompts currently.
According to design principles, when your resources are integrated with Azure Active Directory, permissions to access them is requested using the Azure AD consent framework.
This results in a consent prompt being shown the first time an application is used, which is often a one-time operation.
So there is no need to add consent prompt into the request to trigger the OAuth consent dialog each time after the user signs in.
Forcing a username and password might make sense, but forcing consent after every login is not.

Related

Can I add a custom static claim to auth tokens with a AAD OIDC app registration?

I have a basic Azure AD App Registration. This is a non-interactive client IE console/machine client with a secret and no redirect URI. I would also like this to also work for interactive clients however.
How can I add a claim to my token called "hello": "world"?
To add a custom claim like "hello": "world" in the token, you can create claim mapping policy using PowerShell.
1)Make sure to have AzureADPreview module installed, before running below commands.
Connect-AzureAD
New-AzureADPolicy -Definition #('
{
"ClaimsMappingPolicy":
{
"Version":1,"IncludeBasicClaimSet":"true",
"ClaimsSchema": [{"Source":"user","ID":"extensionattribute1","SamlClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/hello","JwtClaimType":"hello"}]
}
}') -DisplayName "HelloExtraClaim" -Type "ClaimsMappingPolicy"
Output:
2)Note the ID of the policy and assign it to your service principal using below command:
Add-AzureADServicePrincipalPolicy -Id serviceprincipal_ObjectID -RefObjectId policy_ID
3)To confirm whether the policy is assigned or not, run below command:
Get-AzureADServicePrincipalPolicy -Id serviceprincipal_ObjectID
Output:
4)To assign value to that claim, sign in as admin to Microsoft Graph Explorer and run the below query:
PATCH https://graph.microsoft.com/beta/me
{
"onPremisesExtensionAttributes":
{
"extensionAttribute1": "world"
}
}
Response:
5)Make sure to set "acceptMappedClaims": true in App's Manifest like below:
Go to Azure Portal -> Azure Active Directory -> App registrations -> Your App -> Manifest
6)Go to Expose an API tab and set Application ID URI to your domain like below:
7)Generate a token to your application by signing with admin account.
After decoding the above ID token in jwt.ms, I got the claim "hello": "world" successfully as below:
Credits: How to add custom user defined claims to azure ad token | GitHub by TiagoBrenck

Add an Azure AD user to a Azure DevOps project group using Azure Logic Apps

I am trying to add an Azure AD user to an Azure DevOps project group using the Azure Logic Apps DevOps Connector, action Send an HTTP request to Azure DevOps but I receive status Unauthorized while with the same user I am able to do it manually in the portal. Because there is almost no documentation regarding this tool and APIs it's using, I guess it is something with the URI but not sure. Any ideas?
Thank you
We could not add an Azure AD user to a Azure DevOps project group via Azure Logic Apps. This is an known issue in the action Send an HTTP request to Azure DevOps
We are using this REST API to add an AAD user as member of a group, it need the permission scope vso.graph_manage
And according to this doc Action Send an HTTP request to Azure DevOps has a limited set of scopes which control what resources can be accessed by the action and what operations the action is allowed to perform on those resources.
The Scopes contain:
vso.agentpools_manage
vso.build_execute
vso.chat_manage
vso.code_manage
vso.code_status
vso.connected_server
vso.dashboards_manage
vso.entitlements
vso.extension.data_write
vso.extension_manage
vso.identity
vso.loadtest_write
vso.packaging_manage
vso.project_manage
vso.release_manage
vso.test_write
vso.work_write
Since it does not contain the scope vso.graph_manage, and we could see the error message : TF400813: The user xxx is not authorized to access this resource in the output content
Update1
Power shell script:
$connectionToken="{PAT}"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$URL = "https://vssps.dev.azure.com/{Org name}/_apis/graph/users?groupDescriptors={groupDescriptors}&api-version=6.0-preview.1"
$body =#"
{
"principalName": "{User email}"
}
"#
$Result = Invoke-RestMethod -Uri $URL -ContentType "application/json" -Body $body -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method POST

Reset Password REST call returns 403 using service principal

I am trying to execute the following API using a bearer token issued to a service principal NOT an AD User. Yes I know this is the AD Graph versus Microsoft Graph endpoint, but I have my reasons :)
https://graph.windows.net/GUID-REDACTED/users/GUID-REDACTED?api-version=1.6
I get a 403 error despite the fact that I have granted all Application Permissions for "Windows Azure Active Directory" (and Microsoft Graph) to that principal. I also applied admin consent (via Grant Permissions) in the portal. Note that a request to read all users (i.e., remove last GUID off URL above) DOES succeed.
The bearer token contains the following seven claims (curiously in AD, EIGHT permissions are granted):
"Device.ReadWrite.All",
"Directory.Read.All",
"Member.Read.Hidden",
"Directory.ReadWrite.All",
"Domain.ReadWrite.All",
"Application.ReadWrite.OwnedBy",
"Application.ReadWrite.All"
The token was acquired via:
var context = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}");
var m = new HttpRequestMessage()
var accessToken = context.AcquireTokenAsync("https://graph.windows.net", credentials).Result.AccessToken;
m.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
I have tried the analog of this via the Microsoft Graph endpoint, but with the ADAL AuthenticationContext and get the same 403 result. If I use the Microsoft Graph Explorer though, it works. In that case I am logged in as a user though. Upon comparing the scopes in the tokens (scp) there are differences (because the user has certain 'user' scopes), but nothing that immediately looks suspicious.
Directory.AccessAsUser.All is on the user scope but not the application identity scope, but that makes sense to me, unless that scope is (incorrectly?) required for the operation I am trying.
Any ideas what I am missing here? Is there a reference that maps the scopes/roles required to the actual API operations? Does the SP need a directory role, like a user would need?
As #MarcLaFleur said, it's not a good idea to give an application permissions to reset users' password. But if you don't have other choices you can still use client credentials flow to achieve this. But this is not recommeded unless you don't have other choices.
Solution:
You can assign Company Administrators Role to your Service principal. You can refer to this document to do that.
Use AAD Powershell to Connect AAD:
Connect-AzureAD
Get the Role of Company Administrator:
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Company Administrator'}
Assign the role to your SP:
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $yoursp.ObjectId

401 bad credentials with good credentials

I have an Artifactory server (5.6.2) set up with SAML SSO and I'm trying to use my personal admin credentials to download a file:
https://internalartifactory/artifactory/prerelease/package/package.1.2.3.nupkg
However, I continually receive "401 Bad Credentials". I can enter the credentials of a non-administrator, non-SAML account with an internal password and the download will complete. I can also sign into the GUI with my admin credentials and download it. However, other users need the ability to authenticate through a script with their AD credentials.
My problem sounds like the exact one from this jfrog forum post but, when I follow the solution given there, I have no way to generate an encrypted password. I suspect this is because we are using SAML but I don't want to have to generate an encrypted password or to have to use API keys. Both of those seem like an unnecessary headache to explain to a lot of new users.
How can I programmatically authenticate through SAML to download this file directly from a script? This is what I'm using and it works ok for the non-SAML credentials with an internal password but not for SAML credentials:
$credentials = Get-Credential
Invoke-WebRequest -OutFile $tempPath -Credential $credentials -Uri $url
Thanks!

How to programatically create applications in Azure AD

I'm currently creating my applications on Azure Active directory manually whenever there is a request for a new environment. I was exploring ways to create these applications from the code via REST API. I had success in creating users and groups on existing applications by using 'client_credentials' as shown.
ClientCredential clientCred = new ClientCredential(clientID, clientSecret);
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resAzureGraphAPI, clientCred);
In similar fashion I tried to use the 'access_token' generated from above to create a new application
adClient.Applications.AddApplicationAsync(newApplication).Wait()
But this throws an error- "Insufficient privileges to complete the operation."
I looked at other threads and the Azure AD msdn page and turns out the client_credentials flow does not support creating/updating applications.
Adding Applications programmatically in Azure AD using Client Credentials Flow
The above thread also mentioned that way to workaround it was by using the 'grant_type=password' flow. I tried it as suggested but I keep getting the following error which doesn't make sense to me.
"error": "invalid_grant",
"error_description": "AADSTS50034: To sign into this application the account must be added to the 1283y812-2u3u-u293u91-u293u1 directory.\r\nTrace ID: 66da9cf9-603f-4f4e-817a-cd4774619631\r\nCorrelation ID: 7990c26f-b8ef-4054-9c0b-a346aa7b5035\r\nTimestamp: 2016-02-21 23:36:52Z",
"error_codes": [
50034
],
Here is the payload and the endpoint that I'm hitting. The user that is passed is the owner of the AD where I want to create the application
endpoint:https://login.windows.net/mytenantID/oauth2/token
post data
resource 00000002-0000-0000-c000-000000000000
client_id id
client_secret secret
grant_type password
username principal#mydomain.com
password password
scope openid
Any thoughts or suggestions of where I might be going wrong would be appreciated.
You can use PowerShell to create your apps:
$servicePrincipalName =”Your Client App Name”
$sp = New-MsolServicePrincipal -ServicePrincipalNames $servicePrincipalName -DisplayName $servicePrincipalName -AppPrincipalId “Your Client ID"
New-MsolServicePrincipalCredential -ObjectId $sp.ObjectId -Type Password -Value “Your client secret”
Add-MsolRoleMember -RoleObjectId “62e90394-69f5-4237-9190-012177145e10" -RoleMemberType ServicePrincipal -RoleMemberObjectId $sp.ObjectId
The role denoted by 62e90394-69f5-4237-9190-012177145e10 is the Admin role, and this can be adjusted as required to the ObjectId of any other role. Run Get-MsolRole to get a list of roles and ObjectIds.
You could then run this code from your App or run it manually. You will also need to run your connection code before the above, something along the lines of:
$loginAsUserName = "Your Tenancy Admin Account"
$loginAsPassword = "Your Tenancy Admin Account Password"
$secpasswd = ConvertTo-SecureString $loginAsPassword -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ($loginAsUserName, $secpasswd)
Connect-MsolService -Credential $creds
I was able to create the application in my tenant. The AD tenant which I was using to create the application under was verified for a different domain. Basically I ended up plugging in an user from that domain and using the resource_type=password flow was able to generate an access token. Next, firing the following lines of code did the trick
ActiveDirectoryClient adClient = new ActiveDirectoryClient(
serviceRoot,
AccessToken);
adClient.Applications.AddApplicationAsync(newApplication).Wait();
Check the following things which seem to be a little off in your POST to the OAuth Token endpoint:
When wanting access to the Graph API of your Azure AD, you will need to pass https://graph.windows.net as the resource body parameter; this is (imho) not well documented, but that's what you need to do
As client_id and client_secret you need to pass the Client ID and the Key of a predefined Application inside your Azure AD which in turn you have granted permissions on a per user level to; these need to be sufficient to add applications
See here: https://msdn.microsoft.com/Library/Azure/Ad/Graph/howto/azure-ad-graph-api-permission-scopes?f=255&MSPPError=-2147217396
The scope parameter is not used, I think; you will get the claims you defined inside the Azure AD management portal back (the assigned permissions for your application)
This should render you an access token you can then subsequently use on the https://graph.windows.net/tenantId/ end points.

Resources