I am using this UWP sample: https://github.com/microsoftgraph/msgraph-training-uwp
It demonstrates Microsoft Graph, A service for allowing useres to login to apps with their microsoft account so that the app can access the users granted data. By default, the sample requests the calandar's scope, to veiw calandar data, but I would like to edit the sample to access the scope of the user. This is because my app uses in app purchases, and is on a public machine, and I want what users do to be tied to their accounts.
However whenever I try to change the scope of the sample, the app doesnt work correctly, or it crashes. Is there something I'm missing? or is there some way to change the scope?
You can add User.Read scope to your application in the app registration in portal.azure.com. Next time you run the app and sign in , it should ask you to consent this new permission.
Then in your code you can change it to call /me rather than /me/events. It will return the users profile data like shown in Graph Explorer here https://developer.microsoft.com/en-us/graph/graph-explorer?request=me/&method=GET&version=v1.0&GraphUrl=https://graph.microsoft.com
The tutorial is also easier to follow here https://learn.microsoft.com/en-us/graph/tutorials/uwp
Related
I'm updating an Excel complement I made 2-3 years ago with C#. The goal is to get some files that are stored on a SharePoint site, copy them locally and then open them. I have permission to access the SharePoint site, but I have no admin right over the setting of the SharePoint (it is run by our IT service and the company Security is tight regarding data protection). We use MFA to log in to our Windows session and after that we can access the SharePoint and other services without need to input our password again. Until now I have used the code below, and it still work perfectly:
using Microsoft.SharePoint.Client;
using OfficeDevPnP.Core;
string tempFileName = System.IO.Path.GetTempPath() + "filename.xlsx";
AuthenticationManager mgr = new AuthenticationManager();
ClientContext context = mgr.GetWebLoginClientContext("https://xxx.sharepoint.com/teams/mypage");
FileInformation fileinfo = File.OpenBinaryDirect(context, "ServerRealtivePath");
context.ExecuteQuery();
System.IO.FileStream fStream = new System.IO.FileStream(tempFileName, System.IO.FileMode.Create);
await fileinfo.Stream.CopyToAsync(fStream);
fStream.Close();
fileinfo.Stream.Close();
So why try to fix something that is not broken… yet? The NuGet package SharePointPnPCoreOnline containing the OfficeDevPnP NameSpace is now marked as being retired and it is recommended to use PnPFramework instead. But the PnPFramework do not contained the AuthenticationManager.GetWebLoginClientContext() method. With the ever-growing need for data protection and new technology, I’m expecting the current method will stop working at some point. Do you have an equivalent method to connect to a sharepoint using a more modern way?
I don’t have any permission to register the app with Azure and I’m guessing it will be a big No from our IT service. I don’t mind asking the user to input his login at some point if needed. I never used REST or GRAPH API but if it can help, I can look into it. I want the right to access the files base on the current user permission. If the user doesn’t have permission to access the specified file, I don’t want the app to be able to download it.
I’m open to suggestions, Thanks
For my tool, I've just reworked the code from the GetWebLoginClientContext, it's neither big nor complicated. Here is also a newer version of it. So, what's inside: a simple form with a web browser control (that is based on Internet Explorer). When the browser control authenticates the user, the code gets the authentication cookies from the browser control using the platform web browser API, and uses that in the subsequent calls to SharePoint.
What can break here: Internet Explorer (and thus, the browser control) is deprecated, and the support for it ended last year. If the authentication window stops working when opened from a browser control, that would be a problem.
I've "fixed" that for myself by using the WebView2 instead of the browser control, and since it's evergreen, it should be fine. It also provides API to get cookies that we need to call the SharePoint.
I don't think the approach with cookie authentication is a problem by itself, but they may change cookies some day and then the app may need to be updated correspondingly then if that happens.
A more "robust" approach would be to register an application anyway in Azure AD (actually you don't absolutely have to ask your admins to register the app, you can register one for yourself without asking anyone, in your own "organization").
With this approach, the user must consent to use the app (to allow the app to access the data in the organization). The admin consent may be required, but it depends on organization settings (by default it's not required, user consent is good enough).
Please note that connecting using an "app" is actually more secure because when you grant access to an app, you only give it specific permissions (i.e. you get an intersection of the user permissions and the permissions that were granted to the app). When connecting as a user (i.e. using the "cookies" approach above), you get full access (i.e. you can do anything the user can).
Another point, for the app you don't really have to build anything on the web (no website is actually needed); the "callback url" to get the access token can be hosted in the application itself (localhost), or the app can be configured to use device code.
I am using office 365 credentials to login to windows 10 machine. I have written a desktop winform application in c# where I just want to get email address and ad group assigned to that login user.
I don't want to relaunch login from desktop app. Just want to use existing user info to get email address and user groups. I am only able to get local groups assigned to that user but required AD groups too.
You must throw login challenge from your desktop app at least once to get the auth token to be able to query graph api (details in the next para) and keep the token cache so that it does not prompt the user again next time onwards. There is no other way I am aware of. You need to create a native client app in AD (or if you want to reuse some existing one, that will do too) and grant Graph API user.read permission to it. Here is an end-to-end guide for that. https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-windows-desktop (well, the example is for WPF, but Winforms would be very similar except the XAML part). If you follow this example, the login screen which will show for the first time will automatically have O365 Windows logged-in user populated (because of .WithPrompt(Prompt.SelectAccount) part in the bootstrapping) if that gives a bit of relief to you app users.
Once you get the access token, you need to query Graph API for that. Here is the programmatic way (C# based on your tag in the question) to get the user details for a logged in user (me) and to get the user groups for the user (me).
I need to programmatically create an app in Azure AD and programmatically assign it permissions for Graph APIs. Somehow I am unable to find any good info on this. Please let me know if there is any good example of this.
I am able to create a basic app but not sure how to assign permissions to it.
I have a few basic queries:
Can we create an app and assign permissions at the same time? Or we need to first create app and then assign permissions?
How can I get a repository of all the possible permissions? Is there any way I can get a readable form of permissions and also its GUID representation?
Any C# example of this would be much appreciated.
PFB answer to your queries :
Can we create an app and assign permissions at the same time? Or we need to first create app and then assign permissions?
--> Yes you can create an app and assign permissions are the same time.
How can I get a repository of all the possible permissions? Is there any way I can get a readable form of permissions and also its GUID representation?
--> Here is the link for all the possible permissions :https://learn.microsoft.com/en-us/graph/permissions-reference
You can use Microsoft Graph explorer to execute queries and get the GUID representation.
Here is the link : https://developer.microsoft.com/en-us/graph/graph-explorer
You must first register an application in the Azure portal (or you must have an application first), and then grant the application permission or delegate permission to call MS graph api to create other applications, here is a detailed explanation Description.
Next, you can create other applications based on this application using C# code + MS graph api, and grant permissions to other applications (this is a separate operation, of course, you can also create an application and assign permissions at the same time).
At first you have to register your application in the Azure Active Directory.
Go to Azure Portal and navigate to the Azure AD -> App Registrations and create a new App.
In the Apps administration view, go to API-Permissions and click on "Add a permission". Now you can see all the available permissions you can grant to you application.
For some permissions (indicated by an orange warning sign) you have to grant admin consent afterwards.
After you have done those steps and you configured the redirect URLs (also in the Azure portal), you can access the data you have permissions from your application.
Note: You will also have to implement an authorization flow to make use of Microsoft Graph. You can find additional information here Microsoft Graph Authentication
I am using https://learn.microsoft.com/en-us/samples/azure-samples/active-directory-dotnet-iwa-v2/active-directory-dotnet-iwa-v2/#step-2-register-the-sample-with-your-azure-active-directory-tenant https://learn.microsoft.com/en-us/samples/azure-samples/active-directory-dotnet-iwa-v2/active-directory-dotnet-iwa-v2/#step-2-register-the-sample-with-your-azure-active-directory-tenant to generate token and I have followed the procedure as mentioned in the above link. I have provided clientID in appsetting.json file and it keeps keeping
Failed to get user name error.
I have used the admin account to generated the app.
screenshot of error:
Based on our discussion, this issue should have been resolved. I will summarize the solution here.
As the sample overview says:
This sample demonstrates how to use MSAL.NET from apps that run on a
domain joined or AAD joined Windows machine.
So you need to use an AAD joined Windows machine to test this sample.
Firstly, you need to add your Windows machine into your AAD domain.
Then when you run this sample, you may encounter the following error: The user or administrator has not consented to use the application with ID '{appId}' named '{appName}'.
This is because you haven't got user consent for this app in your AAD. You need to call AcquireTokenInteractive instead of AcquireTokenByIntegratedWindowsAuth in line 93 in PublicAppUsingIntegratedWindowsAuthentication.cs file. And then call AcquireTokenByIntegratedWindowsAuth again.
Now you can get the user signed-in on the Windows machine successfully.
Update:
Based on Constraints, IWA supports federated users only, meaning users created in Active Directory and backed by Azure AD. Users created directly in Azure AD, without Active Directory backing (managed users) can't use this authentication flow.
So if you want to use IWA(Integrated Windows Authentication), you need a federated account to test it.
I have a Windows Store App that references a package that performs OAuth authorization to make working with a particular REST API easier. The problem is, they don't give you access to the access token generated by the session, or a way to provide the login details to the component via a method call or properties either. You call their component and it does the rest. The component puts up a simple form with with the login elements and the rest of the details are maintained internal to the component.
I'm guessing that through reflection or some other "meta" technique I should be able to get access to the login form elements (user name, password, etc.)? If I can do that during testing, then I can auto-enter the login details when I detect the presence of the component's login form from an async loop running in the background. As it is right now, every time I modify and run the program I have to laboriously enter the login details and a couple other fields of information.
Is there a way to get access to the referenced component's form elements so I can push text into them at run-time?
AFAIK that is not possible, if the dev has access to the TextBox it would allow for the dev to steal the user's login info.
I know it's a bit inconvenient to have to login every time, but why aren't you storing the OAuth creds so the user stays logged in? The app will maintain LocalFolder and RomaingFolder info across deployments from Visual Studio.
Check out this sample (updated for Windows 8.1 in April 2014). You'll see several uses of the broker, as well as how to keep someone logged in and let the user manage this via the Settings Charm