Grant Admin Consent using Microsoft Graph API - Java - azure-ad-b2c

I have created an application using graph API and I have assigned them permission - both delegated and application...
ServicePrincipal servicePrincipal = graphClient.servicePrincipals(resSerPrinId)
.buildRequest()
.get();
List<AppRole> appRoles = servicePrincipal.appRoles;
List<PermissionScope> scopes = servicePrincipal.oauth2PermissionScopes;
List<ResourceAccess> raList = new ArrayList<ResourceAccess>();
for (AppRole appRole : appRoles) {
ResourceAccess access = new ResourceAccess();
access.id = appRole.id;
access.type = "Role";
raList.add(access);
}
System.out.println("Roles added...");
for (PermissionScope permissionScope : scopes) {
ResourceAccess access = new ResourceAccess();
access.id = permissionScope.id;
access.type = "Scope";
raList.add(access);
}
System.out.println("Scopes added...");
RequiredResourceAccess reqResAccess = new RequiredResourceAccess();
reqResAccess.resourceAccess = raList;
reqResAccess.resourceAppId = resSerPrinAppClientId;
List<RequiredResourceAccess> rraList = new ArrayList<RequiredResourceAccess>();
rraList.add(reqResAccess);
Application application = graphClient.applications(clientAppObjId)
.buildRequest()
.get();
application.requiredResourceAccess = rraList;
graphClient.applications(clientAppObjId)
.buildRequest()
.patch(application);
Here in the code above, resSerPrinId is resource service principal Id which has app roles in manifest and a scope in "expose an api" section...
So I am pulling out appRoles and oauth2Permission from that resource service principal and sending them to client service principal...
In the UI I am seeing that the permissions do not have grant...
Is it possible to give them admin grant using some graph API or or manually loading these permission and then giving them admin grant...or do I need to always use the UI to do it...?

So we have basically 2 types of permissions - roles (application)/scope (delegated)
So to provide "grant admin consent" to your delegated permissions, use the below snippet
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
OAuth2PermissionGrant oAuth2PermissionGrant = new OAuth2PermissionGrant();
oAuth2PermissionGrant.clientId = "clientId-value";
oAuth2PermissionGrant.consentType = "consentType-value";
oAuth2PermissionGrant.principalId = "principalId-value";
oAuth2PermissionGrant.resourceId = "resourceId-value";
oAuth2PermissionGrant.scope = "scope-value";
graphClient.oauth2PermissionGrants()
.buildRequest()
.post(oAuth2PermissionGrant);
Here is the link to documentation - Read about oAuth2PermissionGrant here
Now to provide "grant admin consent" to application permissions, use the below snippet...
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
AppRoleAssignment appRoleAssignment = new AppRoleAssignment();
appRoleAssignment.principalId = UUID.fromString("33ad69f9-da99-4bed-acd0-3f24235cb296");
appRoleAssignment.resourceId = UUID.fromString("9028d19c-26a9-4809-8e3f-20ff73e2d75e");
appRoleAssignment.appRoleId = UUID.fromString("ef7437e6-4f94-4a0a-a110-a439eb2aa8f7");
graphClient.servicePrincipals("9028d19c-26a9-4809-8e3f-20ff73e2d75e").appRoleAssignedTo()
.buildRequest()
.post(appRoleAssignment);
Here is the link to documentation - Read more about AppRoleAssignment here
You have to use these two bad boys right here and its done - just use the correct Ids (do not confuse client id with client principal id and likewise)
Basically the flow is - get all permissions (both types loaded up using Required Resource Access - then add admin grants to all the permissions using above code. Hope this helps. comment if you need more help.

Related

Azure B2C Graph API issue

I am trying to run the sample at:
https://github.com/Azure-Samples/ms-identity-dotnetcore-b2c-account-management
And am receiving this error:
Enter command, then press ENTER: 7
Create a user with the custom attributes 'FavouriteSeason' (string) and 'LovesPets' (boolean)
Have you created the custom attributes 'FavouriteSeason' (string) and 'LovesPets' (boolean) in your tenant?
Code: Request_BadRequest
Message: One or more property values specified are invalid.
Inner error:
AdditionalData:
date: 2020-06-30T23:24:26
request-id: dad23cee-984b-439c-a943-9e1bc6be4c9b
ClientRequestId: dad23cee-984b-439c-a943-9e1bc6be4c9b
I have created the custom attributes and can clear see them in the tenant...it even returns their ids. I've setup the Graph access level appropriately (I believe).
Any ideas? Thank you!
In Code, you need to update Tenant id, client id, client secret and also give B2cExtensionAppClientId= “your application display name” in appsettings.json
You have to create two custom attributes in the B2C portal
I. FavouriteSeason (string)
II. LovesPets (boolean)
Use below code to create the user with the custom attribute
try
{
//Create user
var result = await graphClient.Users
.Request()
.AddAsync(new User
{
GivenName = "Casey",
Surname = "Jensen",
DisplayName = "Casey Jensen",
Identities = new List<ObjectIdentity>
{
new ObjectIdentity()
{
SignInType = "emailAddress",
Issuer ="AADCxPb2c.onmicrosoft.com",
IssuerAssignedId = "x#AADCxPb2c.onmicrosoft.com",
}
},
PasswordProfile = new PasswordProfile()
{
Password = b2c_ms_graph.Helpers.PasswordHelper.GenerateNewPassword(4, 8, 4)
},
PasswordPolicies = "DisablePasswordExpiration",
AdditionalData = extensionInstance
}) ;
Console.WriteLine(result);
string userId = result.Id;
Console.WriteLine(result.Id);
Console.WriteLine($"Created the new user. Now get the created user with object ID '{userId}'...");
Can find it on your registered App on Azure AD B2C:
Click on "API Permissions" on left panel.
Then Chose "APIs my organization uses".
You can find the value under name "b2c-extensions-app. Do not modify. Used by AADB2C for storing user data.".

Assign AD Group to Azure AD Application Role using Graph API

I have no problem adding a user to a role using
https://graph.windows.net/{TenantId}/users/{UserId}/appRoleAssignments?api-version=1.5
string data = JsonConvert.SerializeObject(new
{
id = roleId,
principalDisplayName = userEmail,
principalId = userId,
principalType = "User",
resourceId = servicePrincipalId
});
But this is not working for groups by changing:
https://graph.windows.net/{TenantId}/groups/{GroupId}/appRoleAssignments?api-version=1.5
principalDisplayName = GroupDisplayName,
principalId = groupId,
principalType = "Group"
Also tried without the principalDisplayName
I am receiving "Bad Request" and in Fiddler "One or more properties are invalid." with no extra information.
Can you login to azure portal with your tenant credential and check if you can assign AAD group to role? It's most likely related to your permission
Azure Active Directory -> Enterprise applications -> Find your application -> Users and Groups -> Add User

extension attributes for ad user in azure active directory using Microsoft.Graph

Hi I am trying to add extension property to azure ad user using Microsoft.Graph package.
var schema = new SchemaExtension()
{
Id = "Location",
TargetTypes = new List<string> { "User" },
Description = "DescribesLocation",
Properties = new List<ExtensionSchemaProperty>() { new ExtensionSchemaProperty { Name = "LocationCode", Type = "String" } }
};
var result = graphClient.SchemaExtensions.Request().AddAsync(schema).Result;
I have created a daemon application in azure ad registered applications and given below permissions to the application
Directory.Read.All
Directory.ReadWrite.All
User.Invite.All
User.Read
User.Read.All
User.ReadWrite.All
Group.Read.All
Group.ReadWrite.All
I am getting error message as Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation. What other permissions are required for this operation and which permissions are not required?
You need the Directory.AccessAsUser.All permission. Here are some test cases that you may find useful.

Assigning an Azure AD Group permissions to a OneDrive For Business file via some API

I have successfully been able to share a OneDrive for Business file with a group using the Sharepoint CMOS API.
Like this:
context.Load(listItem, l => l.HasUniqueRoleAssignments);
context.ExecuteQuery();
if (!listItem.HasUniqueRoleAssignments)
{
listItem.BreakRoleInheritance(true, false);
}
var group = context.Web.SiteGroups.GetByName(groupName);
context.Load(context.Site.RootWeb, w => w.RoleDefinitions);
context.ExecuteQuery();
var roleTypeKind = readOnly ? RoleType.Reader : RoleType.Editor;
var role = context.Site.RootWeb.RoleDefinitions.FirstOrDefault(rd => rd.RoleTypeKind == roleTypeKind);
var roleDefCollection = new RoleDefinitionBindingCollection(context) { role };
listItem.RoleAssignments.Add(group, roleDefCollection);
context.ExecuteQuery();
But the problem is that group belongs to SiteGroups which is really local to one user. So if I have an Azure AD Group I cannot access it using the Sharepoint API.
I can find an Azure AD group using the GraphClient API like this:
var azuregroup = activeDirectoryClient.Groups
.Where(g=> g.DisplayName.Equals("groupname"))
.ExecuteAsync().Result.CurrentPage.ToList().First() as Group;
But how do I grant that group access to the file using an/any API ? It should be possible since it is possible in the OneDrive for Business UI.
It is not possible doing this
listItem.RoleAssignments.Add(azuregroup, roleDefCollection);
because the first parameter to Add has to be a Principal which the azuregroup is not.
Hope anybody can help - I have searched the internet for countless hours.

SharePoint UserProfile from User Principal Name in Claims environment

I have an account that has been persisted in a database using the User Principal Name (UPN) format: jdoe#domain.gobalx.com
I am working in a SharePoint environment that is Claims authenticated using the UPN format.
My problem is I need to get a UserProfile object for the persisted UPN account. I have tried the following but it doesn't work:
string upnAccount = "jdoe#domain.globalx.com";
SPServiceContext ctx = SPServiceContext.GetContext(SPContext.Current.Site);
UserProfileManager upm = new UserProfileManager(ctx);
UserProfile user = upm.GetUserProfile(upnAccount);
I keep getting: Microsoft.Office.Server.UserProfiles.UserNotFoundException: An error was encountered while retrieving the user profile
Does this mean that I have to convert the UPN account into a claim, and if so does anyone have an example on how to do that?
UserProfileManager UPM = null;
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb web = site.OpenWeb())
{
ServerContext serverContext = ServerContext.GetContext(site);
UPM = new UserProfileManager(serverContext);
foreach (UserProfile profile in UPM)
{
an = profile["AccountName"].Value;
title = profile["Title"].Value;
}
}
}
U can try this for get All userprofile. In foreach loop u can check for your fields and get perticular user details
In some cases under SharePoint sites with federated authentication there are no user profiles automatically created until you haven't setup synchronization. For this issue you may check if there already exists user profile for jdoe#domain.globalx.com via Central Admin.
Also your code must be run under impersonation, check the log for exception and try to use SPSecurity.RunWithElevatedPrivileges.

Resources