Azure Active Directory ServicePrincipal SecurityGroup AppRoleAssignment fails to resolve appRole - azure-active-directory

Within Azure AD B2B I have created an application registration (the resource) with an appRole for "User" and "Application".
If I assign the servicePrincipal (the client) to this appRole -> the accessToken contains the appRole.
servicePrincipal(client) <-> appRoleAssignment <-> servicePrincipal(resource)
this works as expected
If I assign the serviceprincipal (the client) to a top level security group and assign the security group to the appRole -> the accessToken does NOT contain the appRole.
servicePrincipal(client) <-> security group <-> appRoleAssignment <-> servicePrincipal(resource)
this indirection works for users, am I missing something why this would not work for servicePrincipals?

All of your steps are right.If you want to assign an app role to an service principle , you should assign one by one, it not works if you add a service principle into a group that assigned with an app role. As #juunas said , maybe this is something like a bug .

I don't think you have missed anything. It does indeed work for users.
It's either a bug or a feature :) Could be that application permissions are not wanted to be assigned via groups.
(which is what appRoles of type Application are)

Related

Kerberos Delegation and Authentication: Impact due to Domain change

[I'm fairly new to Kerberos Protocol]
We have a customer, who back in 2020 was using a domain let's call it customdom.itm, which has a user account krb-test-cd setup for Kerberos delegation and this domain is part of a domain Active Directory forest itm.
Since they're a large corporation with many users across different countries, they also have another huge domain AD forest with many child domains (and domain controllers) as part of this forest let's call it top.abc. Here the domain relevant to us is aust.top.abc, which has krb-test-aust user account setup for Kerberos.
Since the forests itm and top.abc are different, the same servicePrincipalName for both krb users is safely set to HTTP/testloadbalancer.com, while their userPrincipalName is of course different, i.e.:
krb-test-cd uPN is HTTP/testloadbalancer.com#CUSTOMDOM.ITM
krb-test-aust uPN is HTTP/testloadbalancer.com#AUST.TOP.ABC
And since https://testloadbalancer.com is part of the intranet sites at the customer, their browsers do not challenge the users to enter their AD credentials.
Now here's the problem:
Last month the customer decided to migrate the users in customdom.itm to a new domain can.top.abc which is part of forest top.abc. The user krb-test-cd and some other accounts were not migrated, however, and customdom.itm still exists in its own forest.
Due to the migration, these users are now challenged everytime to enter their AD credentials and are granted access only with the old domain name, i.e.
customdom\michael and password
I have setup a new user account krb-test-can in the domain can.top.abc for Kerberos delegation with setspn and the SPN HTTP/testloadbalancer.com, and the first time, I got this error:
The operation failed because SPN value provided for addition/modification is not unique forest-wide.
Next, I tried ktpass with SPN HTTP/testloadbalancer.com#CAN.TOP.ABC, and I get another error:
Failed to set property 'servicePrincipalName' to 'host/<host name>' on
Dn 'CN=<CN Name>,CN=Users,DC=<DC Name>,DC=<DC Name>,DC=abc': 0x13.
WARNING: Unable to set SPN mapping data.
Later, I finally understood that the SPN is already set to user krb-test-aust.
My question is:
How can I still successfully assign the SPN HTTP/testloadbalancer.com and eventually UPN HTTP/testloadbalancer.com#CAN.TOP.ABC to the user krb-test-can without affecting Kerberos delegation to user krb-test-aust?
Or is there a workaround on how I can use only the user krb-test-aust to delegate Kerberos authentications to the users now residing in domain can.top.abc without the need for user krb-test-can at all?
Any help is highly appreciated.
Thanks in advance!
[Some background]
We have an Access Management software on our side where we have configured many Identity Providers, 2 Policy Enforcement Points and Kerberos authentication for SingleSignOn for each of the above 2 domains.
We only need to inject the uPN and the password of the krb users into the respective PEPs and the software doesn't require a keytab file.
We are identity providers and the customer uses some links like https://testloadbalancer.com/xyz/efg_idp/entityid to make an IdP initiated login and is redirected to the target application.
Taking a hint from Steve, I finally found the solution to my own problem:
Since the domains can.top.abc and aust.top.abc and other domains are part of the same forest top.abc, they SHOULD have a cross-domain trust (I'm not sure if the trust is default or needs to be setup separately).
Hence, I only need the user account krb-test-aust to delegate Kerberos authentications to the users residing in all domains under top.abc.
The uPN of krb-test-aust remains HTTP/testloadbalancer.com#AUST.TOP.ABC.

Add RoleAssignment to a Resource Group programmatically

I'm implementing an application in Java that has access to Azure via a secure principal and that creates some Resource Groups.
I would like, given an AD Group Name specified via configuration, to add a specific Role Assignment for that AD Group to the Resource Groups.
Is it feasible via Azure Java SDK or I need to use REST APIs?
Which permissions the service principal needs to:
Read an AD group given its name
Assign a RolePermission to a newly created Resource Group for that AD Group
I need to ask to our ActiveDirectory team which permission must be enabled to my Service principal.
TIA
Best regards
I don't know if we can use java sdk to implement this requirement, but I know we can request rest api to do it. Please refer to the steps below:
1. We need to get the id of the role definition by request this api: GET https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-07-01
The URI parameter {scope} should be like /subscriptions/{your subscription id}/resourceGroups/{your resource group name}
For example, here I get the id of "Contributor" role.
2. Then request this api: PUT https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}?api-version=2015-07-01 to create role assignment(assign the role for resource group contributor to your ad group).
The {scope} should be /subscriptions/{your subscription id}/resourceGroups/{your resource group name} and you can specify a {roleAssignmentName} as you like(should be valid GUID).
The request body should be like below:
{
properties: {
"roleDefinitionId": "{the id of Contributor role which we get in step 1}",
"principalId": "{the object id of your AD group}"
}
}
3. Finish the two apis request above, we can find the AD group has been assigned with the role of "Contributor" for the resource group.

Restricting claims in Azure App Registration?

Within Azure Active Directory, I have created an App Registration.
For most users, this works great. They can login to my application via federating in from Azure AD, and their claims are coming through.
For some users, however, they have over 150 group memberships in Azure AD. For them, they receive an HTTP 400 bad request. I've increased the maxRequestBytes and maxFieldLength of my server according to this post: https://support.microsoft.com/en-us/help/820129/http-sys-registry-settings-for-windows, but it didn't solve the issue for all users. Some received access after this, but there's a handful that still cannot login.
My application only has ~10 groups in Azure AD that it cares about. I customized my App Registration's manifest to have "groupMembershipClaims": "SecurityGroup".
Is there a way I can restrict the claims coming out of Azure AD to only the 10 groups that I care about?
Per my understanding, this issue is due to too many groups claim in some your Azure AD user access token and you want to limit the group claims.
As far as I know, there is no way to do that. But there will be two workarounds here :
1. this official doc which indicated claims about groups and hasgroups, maybe provides some tips to handle your scenario. As the doc indicated, it suggested you to call an API to fetch all user groups if a user has too many group claims.
In your scenario, you will need to check about 10 groups membership with a user. To avoid the issue that too many group claims in your user's token, you can just remove group claims in token and check groups membership with a user with this API.
2. Using Azure AD app roles claim instead of groups claim. In Azure AD application, we can create Add app roles and assign the role to users or groups. Once be assigned the role , role claim will be added in users' token.
As you only care about 10 groups, you can create corresponding app roles and assign the roles to your groups that you cared about(i,e role1 assign to group1).With this,users in groups will have corresponding role claim(i,e , users in group1 will have a role claim:role1) so that we can use this claim to replace groups claim .
What's more
except for increasing maxRequestBytes and maxFieldLength of your server, you can try to modify maxAllowedContentLength , details see this post .

Can ADFS as SAML2.0 SP have more than one entity id, depending on RPs?

Basically I have a scenario which requires that the same ADFS SAML SP has two separate SAML entity id, can this be done? How? Do I need to have separate RP for each entity ID?
You can use claims rules to change the identifier before issuing claims. But the federation metadata will always reveal the real true entityid as nzpcmad said.
So if you federate with AD FS without using the metadata endpoint and manually specify the entityID and endpoints, you can use claims rules to achieve this.
Customers with Office 365 have experience with this. If one AD FS is used to federate more than one domain in use (on O365/Azure AD) then a claims rule is used to change the http://schemas.microsoft.com/ws/2008/06/identity/claims/issuerid before issuance.
here is the relevant rule as used in O365 and Azure AD. The below rule extracts the UPN suffix and uses this to make an identifier like http://domain.com/adfs/services/trust/ (where domain.com is UPN suffix as defined in AD for the user)
c:[Type == "http://schemas.xmlsoap.org/claims/UPN"]
=> issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/issuerid", Value = regexreplace(c.Value, ".+#(?<domain>.+)", "http://${domain}/adfs/services/trust/"));
So if you add claims rules to your relevant RP trust as deemed necessary you can either use default AD FS identifier or make it appear as something else.
The standard ADFS entity ID in the metadata is:
entityID="http://xxx/adfs/services/trust"
There is only one and it is actually the ADFS URL.
There is no way to change the metadata as well.
You would need two separate ADFS instances.

"A referral was returned from the server" error only while querying LDAP from outside the domain

I have 2 domains in the forest. 2nd one is the child domain of the first one. Like below...
Domain1 = abc.com on machine machine1
Domain2 = child.abc.com on machine macnihe2
I have c# application which tries to create a DirectoryEntry on the child domain.
LDAP://machine1/OU_IN_CHILD_DOMAIN/PARENT_DOMAIN_USERNAME_AND_PASSWORD
This works when my c# application is on parent domain i.e on abc.com but if my c# application is on any un-related domain like unrelateddomain.com, I get A referral was returned from the server error.
Please let me know why is this? In first case AD is able to do 'Referral chasing' but not in second case. Is there something am I missing?
I had this exact problem for months and just solved it this afternoon. Here's what you will need to do: prepend a domain controller hostname from the child domain to the LDAP string. In your example, it might be like this for the sub/child domain:
LDAP://MyChildDomainController1.child.abc.com
You also mention connecting from an unrelated domain/LDAP/Active Directory. If there is no trust between Active Directory on the two domains and their LDAP structure is unrelated, then you will not be able to use the above method. If it's possible, you're only approach in that circumstance would be to use an authenticated connection. Never tried it but this is a possible answer:
https://stackoverflow.com/a/9252303/1569434
"...ensure that the service account (or computer account if network
service) hosting the code above is allowed to delegate to the LDAP
service on all of the DCs in your environment"

Resources