I am creating a UWP app which shows certain data, depending on the logged on user.
The user is logged on in Windows Azure and the computer account is also joined to Azure.
I have enabled the "Account Information" feature in the app manifest.
I am trying to find out the user data, using the User Class, like mentioned in several examples online:
private async void GetAllUserData()
{
var users = await User.FindAllAsync();
foreach (var user in users)
{
var authenticationStatus = user.AuthenticationStatus;
var nonRoamableId = user.NonRoamableId;
var provider = await user.GetPropertyAsync(KnownUserProperties.ProviderName);
var accountName = await user.GetPropertyAsync(KnownUserProperties.AccountName);
var displayName = await user.GetPropertyAsync(KnownUserProperties.DisplayName);
var domainName = await user.GetPropertyAsync(KnownUserProperties.DomainName);
var principalName = await user.GetPropertyAsync(KnownUserProperties.PrincipalName);
var firstName = await user.GetPropertyAsync(KnownUserProperties.FirstName);
var guestHost = await user.GetPropertyAsync(KnownUserProperties.GuestHost);
var lastName = await user.GetPropertyAsync(KnownUserProperties.LastName);
var sessionInitiationProtocolUri = await user.GetPropertyAsync(KnownUserProperties.SessionInitiationProtocolUri);
var userType = user.Type;
}
}
The only properties I can get from the user object are:
DisplayName
AuthenticationStatus
NonRoamableId
UserType
All other properties remain empty. From my understanding, when I am logged in to Windows Azure, at least the principal name should have a value.
What am I doing wrong - or in other words - what do I have to do, to get account information?
After enabling "Enterprise Authentication" feature in my app manifest, the UPN is filled in the principalName variable.
I know, this does not the real authentication job for the application, but for my purpose it is sufficient to have the UPN, authenticated in Windows.
For more information about adding Azure authentication to an app I have found the following links:
https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-windows-store-dotnet-get-started-users
https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-native-uwp-v2/
Related
I'm trying to change a user's password using MS Graph API. I was checking earlier questions like this and this where the answer were always similar: register an AAD application, because changing the password requires Delegated
UserAuthenticationMethod.ReadWrite.All permissions, and you cannot set that in a B2C application as a B2C app supports only offline_access and openid for Delegated.
So the answers were always suggesting creating an AAD app, and using this app I could query the Graph API on behalf of the user. The question is, how to achieve this? If I check the documentation from Microsoft: Get access on behalf of a user, it is saying that first you need to get authorization, only then you can proceed to get your access token.
But as part of the authorization process, there is a user consent screen. If I'm calling my ASP.NET Core Web API endpoint to change my password on behalf of my user, how will it work on the server? The client won't be able to consent, if I'm doing these calls on the server, right?
Also, I'm using Microsoft.Graph and Microsoft.Graph.Auth Nuget packages and it's not clear how to perform these calls on behalf of the user. I was trying to do this:
var client = new GraphServiceClient(new SimpleAuthProvider(authToken));
await client.Users[myUserId]
.ChangePassword(currentPassword, newPassword)
.Request()
.PostAsync();
Where SimpleAuthProvider is just a dummy IAuthProvider implementation.
Any ideas how to make this work?
OK, got it:
static void ChangePasswordOfAUser()
{
var myAzureId = "65e328e8-5017-4966-93f0-b651d5261e2c"; // id of B2C user
var currentPassword = "my_old_pwd";
var newPassword = "newPassword!";
using (var client = new HttpClient())
{
var passwordTokenRequest = new PasswordTokenRequest
{
Address = $"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token",
ClientId = clientId, // client ID of AAD app - not the B2C app!
ClientSecret = clientSecret,
UserName = $"{myAzureId}#contoso.onmicrosoft.com",
Password = currentPassword,
Scope = "https://graph.microsoft.com/.default" // you need to have delegate access
};
var response = client.RequestPasswordTokenAsync(passwordTokenRequest).Result;
var userAccessToken = response.AccessToken;
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {userAccessToken}");
var json = System.Text.Json.JsonSerializer.Serialize(new
{
currentPassword = currentPassword,
newPassword = newPassword
});
var changePasswordResponse = client.PostAsync(
$"https://graph.microsoft.com/v1.0/users/{myAzureId}/changePassword",
new StringContent(json, Encoding.UTF8, "application/json"))
.Result;
changePasswordResponse.EnsureSuccessStatusCode();
}
}
My project is set up to use azure ad as login(from the dotnet core template). I have successfully managed to log in.
However, i want to use the same logged in user to retrive data from sharepoint rest api.
I have the following method:
public async Task<FileResults> Test()
{
var siteUrl = "https://xxxxx.sharepoint.com";
var username = "xx#xx.no";
var password = "xxxxxx";
var securePassword = new SecureString();
password.ToCharArray().ToList().ForEach(c => securePassword.AppendChar(c));
var credentials = new SharePointOnlineCredentials(username, securePassword);
var handler = new HttpClientHandler();
handler.Credentials = credentials;
var uri = new Uri(siteUrl);
handler.CookieContainer.SetCookies(uri, credentials.GetAuthenticationCookie(uri));
var json = string.Empty;
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
var response = await client.GetAsync(siteUrl + "/_api/Web/GetFolderByServerRelativeUrl('/Delte%20dokumenter/Test')/Files");
json = await response.Content.ReadAsStringAsync();
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(json);
var files = result.FileResults;
return files;
}
}
This is working fine and im getting documents from sharepoint.
But, this is when using hardcoded credentials. How do i use the credentials of the logged in user via azure AD? Do i retrive the accesstoken?
To use the Azure AD Authentication you need to have one of the Authentication flows.
Note: Username/Password flow is not recommended.
After that you will be getting the tokens according to the scopes that are specified and you need to hit the Microsoft Graph Api, internally you need to hit the SharePoint API endpoints according to your requirement.
You can start exploring with this sample
I have used Graph Service to get user information by email. Here is my sample code:
var user = null;
const GraphService = require('graph-service');
const ClientCredentials = require('client-credentials');
const tenant = 'my-company.com';
const clientId = '0b13aa29-ca6b-42e8-a083-89e5bccdf141';
const clientSecret = 'lsl2isRe99Flsj32elwe89234ljhasd8239jsad2sl=';
const credentials = new ClientCredentials(tenant, clientId, clientSecret);
const service = new GraphService(credentials);
service.get('/users/tnguyen482#my-company.com').then(response => {
user = response.data;
});
This would return user which has ID = 9422e847-0000-1111-2222-d39d550a4fb6
But when I use Botbuilder-teams to get fetch members, the user information return from which has different format of ID. Here is my sample code:
var user = null;
var teams = require("botbuilder-teams");
var connector = new teams.TeamsChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
let conversationId = session.message.address.conversation.id;
var userEmail = "tnguyen482#my-company.com";
connector.connector.fetchMembers(
"https://smba.trafficmanager.net/amer-client-ss.msg/",
conversationId,
(err, result) => {
if (err) {
console.log('Cannot get member of current conversation');
}
else {
if (result.length > 0){
result.forEach(function(item) {
if (item.email == userEmail){
user = item;
}
});
}
}
}
);
This would return user which has ID = 29:1zJXjlM7ifjqawGVxXx_4xxx56BFCCIJWfPbWrVDSdxsKUhi9IXyXXYNLOKCLHodN7WgEzz31lBKcZwtWvMzoUw
My question is why on the same user with different ways approach to retrieve data return different ID format?
Besides, my purpose is that I will use the user ID in address for botbuilder to send personal message to user.
User ID is not defined the same within the Graphs Service as it is within Botbuilder. The botbuilder userID is a key for that given user as connected to the conversation within the bot (and is only relevant within the context of the conversation with the bot), and the userID within Graph Service is a unique identity key for a user of Azure AD.
These are not the same API or part of a universal connector, so these IDs do not cross over to one another. Many people create some sort of dictionary of users so that the 2 can be looked up and used accordingly in their application.
Using Graph Service, I have tried to get list of groups that user belong to. Here is my sample code:
var userMemberOf = null;
var userMemberGroups = null;
const GraphService = require('graph-service');
const ClientCredentials = require('client-credentials');
const tenant = 'my-company.com';
const clientId = '0b13aa29-ca6b-42e8-a083-89e5bccdf141';
const clientSecret = 'lsl2isRe99Flsj32elwe89234ljhasd8239jsad2sl=';
const credentials = new ClientCredentials(tenant, clientId, clientSecret);
const service = new GraphService(credentials);
service.get('/users/tnguyen482#my-company.com/memberOf').then(response => {
userMemberOf = response.data;
});
var settings = {
"securityEnabledOnly": true
}
service.post('/users/tnguyen482#my-company.com/getMemberGroups', settings).then(response => {
userMemberGroups = response.data;
});
The data return from both get & post method was an empty list. I have tried another user id but the result is the same. Am I correct when using method memberOf and getMemberGroups to get list of groups that user belong to? Does my sample code correct?
When the user is in no group graph will return an empty result.
Otherwise, when an error occured (e.g. accessDenied or user not found) an corresponding http-status with an errormessage will be returned (more information in the documentation).
The operations you are using seem to be correct.
If you want to rule out that your operations/code is incorrect, you should try executing the operations in the Graph Explorer.
Its a great tool for debugging and you can even login for access to your own data.
how to Authenticate and Authorize Asp.Net Web application through QuickBooks.
I want to integrate QuickBooks Accounts System in ASP.NET web Application I have successfully make developer account on quickbooks and make an app and got consumer key, consumer Secret and App Token and all URL's
Know I need some asp.net web api code snipped to successfully authenticate and authorize my web user's and than show there accounting detail
Please help me i Google alot but have no success.
I'm Strange this form is 0% active related to quickbooks API's or etc, after alot of struggling i found an answer of above mention question,
Download Quickbooks IPP.NET SDK it will provide you different classes for CURD.
var appToken = "";
var consumerKey = "";
var consumerSecret = "";
// the above 3 fields you can get when create your app on quickbook go to My app----> select youre app--->goto KEYS
var accessToken = "";
var accessTokenSecret = "";
// this two tookens you will get from URL on the same above page
var realmId = "1400728630"; //1400728630
// this is youre company ID which can be used when you create youre //company on freshbook
var serviceType = IntuitServicesType.QBO;
var validator = new OAuthRequestValidator(accessToken, accessTokenSecret, consumerKey, consumerSecret);
var context = new ServiceContext(appToken,realmId, serviceType, validator);
var service = new DataService(context);
try
{
Customer customer = new Customer();
//Mandatory Fields
customer.GivenName = "Mary";
customer.Title = "Ms.";
customer.MiddleName = "Jayne";
customer.FamilyName = "Cooper";
service.AddAsync(customer);
//service.Add(entity);
}catch(Exception ex)
{
System.Console.WriteLine(ex);
}