401 bad credentials with good credentials - active-directory

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!

Related

SonarQube to Azure AD is failing with 401 error in logs

I have nginx-->SonarQube.
nginx is able to forward requests successfully.
We want to integrate Authentication with Azure AD.
We followed instructions from here:
https://www.emtec.digital/think-hub/blogs/sonarqube-integration-azure-active-directory/
So when I access https://mycompany.com, I get login page which has "Login with Microsoft" and More options(you can login with local user).
When I enter username and password for Microsoft , we see that Azure AD is returning the token, but SonarQube rejects after that. I see that in the sonarqube access log
"GET /api/navigation/global HTTP/1.1" 401 - "https://mycompany.com/sonar/oauth2/callback/aad?co
So it goes back to login page again. Not sure what I am doing wrong.
Please check with below points:
Try upgrading sonarqube to the latest version.
The redirect URL should be configured with a correct URL, e.g. https:// sonarqube.example.com/oauth2/callback/aad. Here /oauth2/callback/aad is a must in addition to the application URL. For example, if your main URL is "https://sonarqube.example.com" in sonar server base url , you would enter "https://sonarqube.example.com/oauth2/callback/aad" as redirect url in aad.
Make sure the user has required role or permissions to access .
Set the required permissions in portal and grant consent if required
i) Sign in and read user profile
ii) Read all users’ basic profiles
Also please check http redirection - Stack Overflow reference .The redirect URL must have a https or loopback address, else the Azure AD login will not work.
Try clearing the cookies and Restart after any changes made
Referencs:
sonar-auth-aad (github)
running-sonarqube-behind-an-iis-reversed-proxy
docs.sonarqube.org

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

az account get-access-token - fails to fetch token in user's context

I have a user managed identity, for which I want to generate a token
I tried in user's context
az login
az account get-access-token --resource "<client-id of user managed identity>"
I get the error
Get Token request returned http error: 400 and server response: {"error":"invalid_grant","error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID '04b07795-8ddb-461a-bbee-02f9e1bf7b46' named 'Microsoft Azure CLI'. Send an interactive authorization request for this user and resource.
Regarding the above error, I have come across threads which suggest to add Azure CLI as preAuthorizedApplication. However I did not find this managed identity in App RegistrationsI did find an entry in `Enterprise Applications, but did not find how to pre-authorize Azure CLI here.
I tried to achieve the same in a non-user context
az login --service-principal -u <capp-id> -p <client-secret> --tenant <tenant-id>
az account get-access-token --resource "<client-id of user managed identity>"
This works.
Why does the command fail in user context? How can I make it work?
Managed Identities do not have app registrations, only a service principal (aka enterprise app).
The way you are trying to use them is not the way they are meant to be used in my opinion.
The second one working is actually just the feature of Azure AD that allows an application using the client credentials flow (client id + secret) to acquire a token for any app in the tenant.
The token won't have any permissions though, so it wouldn't be valid if you are doing authorization correctly.
You usually don't want to use the managed identities as token targets, only for acquiring tokens.
So if you need to protect an API, you'd need an app registration, where you can then allow Az CLI to call it.
You can also define application permissions and allow applications using client credentials flow to access the API with proper authorization.

IdentityServer4 with integrated Windows authentication

I'm fairly new IdentityServer4 and I'm trying to configure access control for our different internal APIs. By internal I mean that it's not over the internet. I've chosen IdentityServer4 since it seem to have great flexibility when it comes to different clients and grant types.
Right now I'm trying to get Windows Authentication (against AD) to work. First let me show you how I want it to work, then I will show you what I've tried.
Any user that's logged in to the AD should be able to request a token from the token endpoint. So for any application with integrated Windows authentication it should work automatically.
Here is an example of how I would like if to work in PowerShell. I'm not sure exactly how the body should look like, but you hopefully get the point.
$cred = Get-Credential
$body = #{grant_type='client_credentials';client_id='client'}
Invoke-RestMethod http://localhost:5000/connect/token -Method POST -Credential $cred -Body $body
So I studied the Quickstart examples of IdentityServer4 and I read the docs on Windows Authentication. I took the simplest quickstart example and tried to modify it to work with windows authentication.
The example use WebHost.CreateDefaultBuilder for the server which means that Kestrel should be automatically configured (according to the docs). Then I modify ConfigureServices accordingly:
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
services.Configure<IISOptions>(iis =>
{
iis.AuthenticationDisplayName = "Windows";
iis.AutomaticAuthentication = false;
});
}
and in the launchSettings.json I set
iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5000/",
"sslPort": 0
}
}
However, this doesn't work. When I run the server and try to request a token with the above PowerShell script I get the following error log from the IdentityServer:
[10:24:56 Debug] IdentityServer4.Validation.ClientSecretValidator
Start client validation
[10:24:56 Debug] IdentityServer4.Validation.BasicAuthenticationSecretParser
Start parsing Basic Authentication secret
[10:24:56 Debug] IdentityServer4.Validation.PostBodySecretParser
Start parsing for secret in post body
[10:24:56 Debug] IdentityServer4.Validation.PostBodySecretParser
client id without secret found
[10:24:56 Debug] IdentityServer4.Validation.SecretParser
Parser found secret: PostBodySecretParser
[10:24:56 Debug] IdentityServer4.Validation.SecretParser
Secret id found: client
[10:24:56 Debug] IdentityServer4.Validation.HashedSharedSecretValidator
Hashed shared secret validator cannot process NoSecret
[10:24:56 Debug] IdentityServer4.Validation.SecretValidator
Secret validators could not validate secret
[10:24:56 Error] IdentityServer4.Validation.ClientSecretValidator
Client secret validation failed for client: client.
[10:24:56 Verbose] IdentityServer4.Hosting.IdentityServerMiddleware
Invoking result: IdentityServer4.Endpoints.Results.TokenErrorResult
I feel a bit clueless and like I'm missing something here (like setting up the client correctly?). I would greatly appreciate any help here!
The logs says it - you are missing the client secret.
But you have a bigger missing here. You are trying to use client credentials grant type. From what I understood from your explanations, you want to authenticate with the current Windows user, am I right?
If so - your approach is wrong. Client credentials grant type is for client (understand app) authenticating. In other words - it will authenticate the app itself (no matter is it your powershell script, console app or whatever else), but not the user that is using it.
For example if we (me and you) execute the same script on different machines, under different user credentials, we will still receive the same claims in the access token, because we are authenticated as the client.
Check the token endpoint documentation for more options.
If you want to get a token, based on the user and password, you need to use the password grant type.
Hope that this helps and gives you some clues.

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