How to automate PIM login in Azure? - azure-active-directory

How to automate PIM login in Azure. Daily it takes 3-5 mins to activate the login and which is valid for 8 hours, so again whenever it is required I need to reactivate it. Please suggest any automation approach for PIM Login.

To active the PIM automatically, you could follow the steps below.
1.Create automation account(need to create Run As account) and runbook(powershell type).
2.Navigate to the automation account in the portal-> Modules gallery -> search for AzureADPreview module and import it.
3.Follow this doc to assign the Global Administrator to the Run As account i.e. the service principal, just search for the name of your automation account, the name of the service principal has the format as automationaccount_xxxxxxxx.
4.In your runbook, use the script below to login with the service principal, use Open-AzureADMSPrivilegedRoleAssignmentRequest to active an eligible assignment for a user you need.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Connect-AzureAD `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId 'aadRoles' -ResourceId '926d99e7-117c-4a6a-8031-0cc481e9da26' -RoleDefinitionId 'f55a9a68-f424-41b7-8bee-cee6a442d418' -SubjectId 'f7d1887c-7777-4ba3-ba3d-974488524a9d' -Type 'UserAdd' -AssignmentState 'Active' -schedule $schedule -reason "dsasdsas"
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
5.Navigate to the runbook in the portal -> Schedules -> create and link a recurrence schedule to your runbook, e.g. every day, details depend on you.

Related

Azure app registration returns error code AADSTS70001

I have created a provisioning mechanism not unlike this here:
group provisioning mechanism
I have successfully implemented the whole workflow on my developer tenant. Now our productive environment, I always receive this error:
[Error]Invoke - RestMethod: {
"error": "unauthorized_client",
"error_description": "AADSTS70001: Application 'ffffffff-...' is disabled.\r\nTrace ID: ffffffff-180f-4bc4-8087-867633c83e00\r\nCorrelation ID: ffffffff-2e5d-481d-adee-f068dbebaab1\r\nTimestamp: 2018-10-29 09:06:59Z",
"error_codes": [70001],
"timestamp": "2018-10-29 09:06:59Z",
"trace_id": "ffffffff-180f-4bc4-8087-867633c83e00",
"correlation_id": "ffffffff-2e5d-481d-adee-f068dbebaab1"
}
This is my code, that should do the authentication:
function Initialize-Authorization {
param
(
[string]
$ResourceURL = 'https://graph.microsoft.com',
[string]
[parameter(Mandatory)]
$TenantID,
[string]
[Parameter(Mandatory)]
$ClientKey,
[string]
[Parameter(Mandatory)]
$AppID
)
$Authority = "https://login.microsoftonline.com/$TenantID/oauth2/token"
Write-Output "auth: $Authority"
[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
$EncodedKey = [System.Web.HttpUtility]::UrlEncode($ClientKey)
$body = "grant_type=client_credentials&client_id=$AppID&client_secret=$EncodedKey&resource=$ResourceUrl"
Write-Output "body: $body"
# Request a Token from the graph api
$result = Invoke-RestMethod -Method Post ` #`
-Uri $Authority ` #`
-ContentType 'application/x-www-form-urlencoded' ` #`
-Body $body
$script:APIHeader = #{'Authorization' = "Bearer $($result.access_token)" }
}
I already tried generating new keys but I'm stuck. How can the app registration be disabled?
Can someone guide me in the right direction with this?
It appears the ServicePrincipal object for your app, in your production tenant, has been disabled. The ServicePrincipal object is represented under "Enterprise apps" in the Azure portal.
In the production tenant, navigate to the Azure portal > Azure AD > Enterprise applications. Search for your app (if it doesn't show up initially, make sure you've selected "All Applications", under "Application Type"). Choose the app, and in the new blade, choose "Properties", on the left.
If "Enabled for users to sign in?" is set to "No", then the app is disabled in that tenant. Setting it to "Yes" will enable it.
Apps don't generally get disabled automatically, so it will probably be a good idea for you to understand why this was disabled, and ensure everyone is clear on what the requirements are.

How to get the Azure AD objectid of the signed in user?

I'm trying to invoke an ARM template that requires a PrincipalId of the currently signed in user.
https://learn.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults
I've signed in using powershell, as a guest account in the organisation's AAD.
When I check the resulting context, I get:
Name : [sky.sigal#ministryof.me, 5f813400-5b93-43b0-af8f-5fd04714f1ef]
Account : me#here.com
SubscriptionName : SomeSubscriptionName
TenantId : e6d2d4cc-b762-486e-8894-4f5f540d5f31
Environment : AzureCloud
I'm wondering how to get the AAD ObjectId from the above, without string parsing "Name"?
Note that the documentation for the ARM Template is not very clear so not sure if me#here.com would work just as well (am assuming it's talking about a Guid).
Thank you.
You can also get it using the azure cli
az ad signed-in-user show --query objectId -o tsv
You could try Get-AzureRmADUser to get the ObjectId .
Sample:
Get-AzureRmADUser -UserPrincipalName "xxxx#xxxx.com"
Result:
The Id is the ObjectId, you could get it. Also, you could get it via other properties, not only -UserPrincipalName, just refer to the link of the command.
Update:
If you use a Guest account, you could try the command below.
Get-AzureADUser | ?{$_.UserType -eq "Guest"} | ?{$_.UserPrincipalName -like "*partofyouraccount*"}
Note: Before using this command, you need to install Azure AD powershell module.
The info on "Name" you are seeing is related to the subscription. Use the command below to get the objectId under "Account":
(Get-AzContext).Account.ExtendedProperties.HomeAccountId.Split('.')[0]
I am not an expert in AAD but I have found that my own personal Azure subscription unrelated to my work one returns nothing for the following command:
# does not work sometimes
(Get-AzADUser -UserPrincipalName (Get-AzContext).Account).Id
However I found that I can reliably get my user principal name (UPN) and object ID using the Az CLI to get an access token then the Microsoft Graph API to each back the user information.
$token = Get-AzAccessToken -Resource "https://graph.microsoft.com/"
$headers = #{ Authorization = "Bearer $($token.Token)" }
Invoke-RestMethod https://graph.microsoft.com/v1.0/me -Headers $headers
With Powershell cmdlets:
$myObjectId = (Get-AzADUser -UserPrincipalName (Get-AzContext).Account).Id

How to know permissions to other apis of my app

How to know the permissions of my azure ad app have for other APIs, such as Microsoft Grahp API .
In portal , i could check that in the [API Access]-->[Required permissions] , but how do i check that with powershell , i used
Get-AzureRmADApplication -ObjectId ,
Get-AzureRmADApplication -ObjectId xxxxx | fl *
But little attributes returned and AppPermissions is null , but with fiddle , i notice it use below request :
GET https://graph.windows.net/mytenant/applications/id?api-version=1.6 HTTP/1.1
And i could find a lot of attributes of that app ,which one shows the permission of the app and how do i get that in powershell ?
You could try the Azure Active Directory PowerShell Version 2 , the use command like :
$app = Get-AzureADApplication -Filter "appId eq '$appId'" | fl *
to get the RequiredResourceAccess claim ,that is the collection that is shown under "permissions to other applications" in the azure ad classic portal and "Required permissions" in new portal .
In addition , PowerShell essentially wraps the API's and just presents them to you in a simplified interface. If you don't find a command to do what you want you can always using PowerShell to invoke the Graph API directly. Please refer to below article for how to call Azure Active Directory Graph Api from Powershell :
https://blogs.technet.microsoft.com/paulomarques/2016/03/21/working-with-azure-active-directory-graph-api-from-powershell/
And here is a test code sample :
PS C:\Users\v-nany> $header = #{
>> 'Content-Type'='application\json'
>> 'Authorization'=$token.CreateAuthorizationHeader()
>> }
PS C:\Users\v-nany> $uriSAs = "https://graph.windows.net/xxxxxxx/applications/xxxxxx?api-version=1.6 "
PS C:\Users\v-nany> $appInfo = (Invoke-RestMethod -Uri $uriSAs –Headers $header –Method Get –Verbose)
PS C:\Users\v-nany> $appInfo.requiredResourceAccess
You will get resourceAppId represents the resource , and related resourceAccess which is a scope list.

What "domain" should I specify in JNDI login to an Active Directory Server?

I'm wondering what "principal" I should specify to login in to an Active Directory server. Should the principal be a user inside the AD I try to log into? Or it can be a user in the domain I specify as long as the user has privileges to access the AD?
I tried both with credentials error 49. But I can log in to the AD with ldp.exe by using the Administrator account of the server that AD is installed on.
Here is my code. Many thanks for any prompt help.
Hashtable env= new Hashtable(11);
env.put(Context.SECURITY_AUTHENTICATION,"simple"); // Also tried none w/ the same error
// What principal should I use??
env.put(Context.SECURITY_PRINCIPAL,"CN=Ross,OU=Eng,DC=RossInc");//User
//env.put(Context.SECURITY_PRINCIPAL, user + "#" + domain); // Tried w/ the same error
env.put(Context.SECURITY_CREDENTIALS, "ross");//Password
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL,"ldap://myserver:389/DC=RossInc");
DirContext ctx = new InitialDirContext(env); <-- Fails with AuthenticationException: [LDAP: error code 49 - 8009030C
You either can provide:
NT-style login name
Kerberos UPN (implicit UPN)
explicit UPN (if additional UPN suffices have been defined)
More over, NEVER ever perform a simple bind! Either Digest or GSS-API.
According to the following example from Oracle site, the security Principal is a distinguished name.
Here is some code working for me from a computer inside the domain :
Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, "ldap://societe.fr:389");
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=administrateur,cn=users,dc=societe,dc=fr");
ldapEnv.put(Context.SECURITY_CREDENTIALS, "test.2011");
ldapContext = new InitialDirContext(ldapEnv);
The principal can be a user inside the AD as long as he has privileges to access the AD.

Winform user authorization via active directory

I have a situation where I am using the following code to verify user membership in AD before executing tasks in my app
using System.Security.Principal;
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole("someGroup");
The above code works fine for machines on my domain, however I do have some machines which are not on my domain on which I have the WINFORM application installed. How can I verify the user membership in AD?
Edit - is there a way to prompt the windows login?
Since your computer is not joined to domain at all, we cannot use WindowsIdentity or WindowsPrincipal and then check its IsInRole() method. The IsInRole() method works only if your computer is joined to the domain and it's using your domain machine account to do S4USelf.
You cannot use LogonUser approach too because your computer won't let you create a logon session from an untrusted forest.
I think we can only query the Active Directory directly to get the information we want. The code in your posted Microsoft KB does not work very well as far as I can tell. It's trying to query from memberOf attribute. The group information is not always available from the memberOf attributes.
I just wrote an IsInRole() function using AccountManagement. I guess this is what you want. The IsInRole() function will call a recursive function IsInGroup() to find out all the groups the user belongs to.
private bool IsInRole(string domain, string username, string password, string role)
{
using (var context = new PrincipalContext(ContextType.Domain, domain, username, password))
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, role);
UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
return IsInGroup(user, group);
}
}
private bool IsInGroup(Principal principal, GroupPrincipal group )
{
if (principal.IsMemberOf(group))
return true;
foreach (var g in principal.GetGroups())
{
if (IsInGroup(g, group))
return true;
}
return false;
}
To use this IsInRole() function, you need to provide your domain name and domain credentials. If the username and password provided are wrong, you will get an exception.
You need .NET 3.5 SP1 to use AccountManagement API. Also, you may like to pay attention to this hotfix. The AccountManagement API got some bugs if running in some environment. You may need to apply the hotfix.

Resources