Create a user passing in a user object (Microsoft Graph) - c#

I'm trying to create a user using a microsoft graph call using this link: https://learn.microsoft.com/en-us/graph/api/user-post-users?view=graph-rest-1.0&tabs=csharp
However, is there a way to create a user by passing in a User object or a json representation of a user object in an azure function as a parameter As shown below?
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "user/settings")] HttpRequest req, ILogger logger, User user)
Also, is there a way to read the whole req.Body (w/ additional properties) and create a user, instead of only applying the required parameters (shown below)? Each and every user will have different properties
{
AccountEnabled = true,
DisplayName = "displayName-value",
MailNickname = "mailNickname-value",
UserPrincipalName = "upn-value#tenant-value.onmicrosoft.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "password-value"
}
};
await graphClient.Users
.Request()
.AddAsync(user);

For your first question, I don't think we can pass a User object to function directly to create the user. But we can pass all of the properties into the function to create it. As your second question mentioned, it is not easy for us to create the user if every user has different properties. So we can pass all of the properties as json into function and then read the json from the req and concat these properties as json string. After that, do not use graph sdk to create user. Do a post request with graph api by ourself like below code:
string str = "{\"displayName":\"xxxx\",\"mailNickname\":\"xxxx\"}";
var content = new StringContent(str, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "your token");
var response = client.PostAsync("https://graph.microsoft.com/v1.0/users", content).Result;

Related

Generate user token from AuthenticationContext

I am trying to generate a user token for the purpose of testing an API that requires one. The tests run automatically. I have the following code example, but it seems to be out of date
Uri endpointUri = new Uri("my endpoint");
string resource = "my rid";
string clientId = "my client id";
PlatformParameters parameters = new PlatformParameters(PromptBehavior.Auto);
string authContextURL = "my url";
var authenticationContext = new AuthenticationContext(authContextURL, new TokenCache());
// Here you are sending a request to AAD with the user credentials.
AuthenticationResult result = await authenticationContext.AcquireTokenAsync(resource: resource, clientId: clientId, redirectUri: endpointUri, parameters);
// If the request succeeded you can get the user access token as follows.
return result.AccessToken;
The reason I believe it to be out of date is that PlatformParameters now requires 2 parameters, and I cannot find what the 2nd parameter should be by default.
My question is, how can I create a user-context token to use in testing my API from the test code?
EDIT
According to this answer, PlatformParameters with 1 param is for .netframework, whereas I am using .net 6
Still looking to any leads there may be!

Create a user passing in a json of user object (Microsoft Graph)

I'm trying to create a user by calling microsoft graph and passing in a json string (one that looks like a user object) into the req.body of a httprequest.
The steps I am currently following are:
Call microsoft graph to get the user's properties
Serialize content into a json string (jsonString) and pass it in as the req.Body of a HTTPRequest when using a graph call to create a user in azure active directory
When I pass the content into the req.Body, since there are required fields that must be filled out (accountEnabled, displayName, onPremisesImmutableId, password, etc.), it will not be created cause it does not specify the required field (ex: In the content of jsonString, password is set to null. Password would need to have a value).
The source link of the graph call is found here: https://learn.microsoft.com/en-us/graph/api/user-post-users?view=graph-rest-1.0&tabs=http
Is there a way to pass in my jsonString and also specify some of the user properties within the req.Body? If not, is there a workaround?
var createUser = await httpClient.PostAsync(link, "Token", jsonString);
It's important that you cannot retrieve the password for any user in Azure AD in any way.
So, you need to set the value of the password in your code.
The other properties(displayName, MailNickname, UserPrincipalName, etc.) could be set directly, seeļ¼š
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
User user = await graphClient.Users["{user-id}"].Request().GetAsync();
var newUser = new User
{
AccountEnabled = true,
DisplayName = user.DisplayName,
MailNickname = user.MailNickname,
UserPrincipalName = user.UserPrincipalName,
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "password-value"
}
};
await graphClient.Users.Request().AddAsync(newUser);
I refer to the code with C# in the link.

Microsoft Graph API - user extension data in C#

I have an Azure AD B2C directory with some users in it. I have been using the Microsoft Graph API and through both https://developer.microsoft.com/en-us/graph/graph-explorer and PostMan I have been able to create and modify users along with including an extension attribute (eg: extension_[guid in our tenant]_ContactMethod) - details passed in json in the body of the request in PostMan.
That is fine, however I need to be albe to do the same in C#. I can successfully create the user without specifying any extensions:
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var user = new User
{
AccountEnabled = true,
DisplayName = "John Smith",
MailNickname = "JohnSimth",
UserPrincipalName = "JohnSmith#[tenant].onmicrosoft.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "[Randomly Generated Password]"
}
//[Extension attributes to add here]
};
await graphClient.Users.Request().AddAsync(user);
However I need to be able to specify some extension attributes when creating / modifying the user in C#. How do I do this?
You cannot directly add extensions at the time of creation according to this limitations document.
After creating the user, you need to create a separate request that hits the extensions endpoint as shown in the below code and this adds these extension details to the user.
var extension = new OpenTypeExtension
{
ExtensionName = "{ExtensionName}",
AdditionalData = new Dictionary<string, object>
{
{"FirstEmail", "abc#yahoo.com"},
{"SecondEmail" , "xyz#yahoo.com"}
}
};
await graphClient.Users["{UserId}"].Extensions
.Request()
.AddAsync(extension);
So just after user creation, get that userid and use it to hit extensions endpoint as shown in the above code.

Xamarin, Azure, customauth and passing parameters

I am in the process of rewritting our app using Xamarin.Forms with a C# backend and I'm trying to use customauth on login. I've got it working to a point but am struggling to pass back to the Xamarin app everything I want from the backend. I'm getting the token and user id but want a bit more.
The backend code on succesfull login seems relatively straightforward:
return Ok(GetLoginResult(body));
where GetLoginResult() is:
private object GetLoginResult(IUser body)
{
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, body.username)
};
JwtSecurityToken token = AppServiceLoginHandler.CreateToken(
claims, signingKey, audience, issuer, TimeSpan.FromDays(30));
accounts account = db.accounts.Single(u => u.username.Equals(body.username));
return new LoginResult(account)
{
authenticationToken = token.RawData,
};
}
and the LoginResult class is
public class LoginResult
{
public LoginResult(accounts account)
{
Response = 200;
CustomerId = account.CustomerId;
Modules = account.Modules;
User = new LoginResultUser
{
userId = account.id,
UserName = account.UserName,
EmployeeId = account.EmployeeId
};
}
[JsonProperty(PropertyName = "Response")]
public int Response { get; set; }
etc
In the app, I'm calling the customauth as follows:
MobileServiceUser azureUser = await _client.LoginAsync("custom", JObject.FromObject(account));
The result has the token and the correct userid but how can I fill the result with the additional properties passed back by the backend? I've got the backend working and tested using postman and the results I get there are what I want but I've been unable to find out how to get it deserialized in the app.
As I known, for custom auth , MobileServiceClient.LoginAsync would invoke https://{your-app-name}.azurewebsites.net/.auth/login/custom. When using ILSPy you could find that this method would only retrieve the user.userId and authenticationToken from the response to construct the CurrentUser of your MobileServiceClient. Per my understanding, you could leverage MobileServiceClient.InvokeApiAsync to retrieve the additional user info after the user has logged in successfully. Additionally, you could try to follow this toturial for other possible approaches.
UPDATE
You could use InvokeApiAsync instead of LoginAsync to invoke the custom login endpoint directly, then retrieve the response and get the additional parameters as follows:
When logged successfully, I added a new property userName and response the client as follows:
For the client, I added a custom extension method for logging and retrieve the additional parameters as follows:
Here are the code snippet, you could refer to them:
MobileServiceLoginExtend.cs
public static class MobileServiceLoginExtend
{
public static async Task CustomLoginAsync(this MobileServiceClient client, LoginAccount account)
{
var jsonResponse = await client.InvokeApiAsync("/.auth/login/custom", JObject.FromObject(account), HttpMethod.Post, null);
//after successfully logined, construct the MobileServiceUser object with MobileServiceAuthenticationToken
client.CurrentUser = new MobileServiceUser(jsonResponse["user"]["userId"].ToString());
client.CurrentUser.MobileServiceAuthenticationToken = jsonResponse.Value<string>("authenticationToken");
//retrieve custom response parameters
string customUserName = jsonResponse["user"]["userName"].ToString();
}
}
Login processing
MobileServiceClient client = new MobileServiceClient("https://bruce-chen-002-staging.azurewebsites.net/");
var loginAccount = new LoginAccount()
{
username = "brucechen",
password = "123456"
};
await client.CustomLoginAsync(loginAccount);

How can I get the picture of a Facebook event using server side code?

I'm writing a web app that pulls events data from Facebook, and I can get a lot of the information using an app token, but not the picture, which requires a client token, as documented here: https://developers.facebook.com/docs/graph-api/reference/v2.2/event/picture
I want the code that grabs the event data to run automatically on a server at regular intervals, without requiring a user to log in to their Facebook account.
Is there a way I can get a client token without user intervention? If not, is there another way I can get the event picture?
This is the code I am using to get the event data, using C# and JSON.Net (This gets a list of events created by the specified user - ResortStudios):
var fb = new FacebookClient();
dynamic result = fb.Get( "oauth/access_token", new
{
client_id = "XXXXXXXXXXX",
client_secret = "XXXXXXXXXXXXXXXXXXXXXXXXX",
grant_type = "client_credentials"
} );
var apptoken = result.access_token;
fb = new FacebookClient(apptoken);
result = fb.Get("ResortStudios/events");
JObject events = JObject.Parse(result.ToString());
JArray aEvents = (JArray)events["data"];
string s = aEvents.ToString();
List<fbEvent> lEvents = JsonConvert.DeserializeObject<List<fbEvent>>(s);
I've not tried this but something occurred to me that might work for you. Have you considered something like storing it a non-persistent data store like session state? Then, using the Facebook SDK for .NET, you create an ActionResult for UserInfo, like below. (I know this isn't directly applicable but I hoped it might get you thinking.)
//http://facebooksdk.net/docs/web/ajax-requests/
public ActionResult UserInfo()
{
var accessToken = Session["AccessToken"].ToString();
var client = new FacebookClient(accessToken);
dynamic result = client.Get("me", new { fields = "name,id" });
return Json(new
{
id = result.id,
name = result.name,
});
}

Categories

Resources