Adding Windows Live ID to the credential store - c#

I have written an application that maps a user's SkyDrive to a network drive.
However when opening word documents directly from the network drive, Microsoft Office 2010 tries to load the document using WebDav and prompts for the user to login in again.
When you login it works fine, and if you click "Remember Me" it stores the credentials in the credential store, accessible via rundll32.exe keymgr.dll, KRShowKeyMgr
This only lasts until the session is closed.
I want to incorporate the automatic storing of the user's credentials into my program so that the user doesn't get prompted at all.
I have tried using the CredWrite API however that only allows me to store generic credentials. I need to store a (.Net Passport) credential.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa375187(v=vs.85).aspx
I have only been able to achieve this using the CredUIPromptForCredentials API with the flags set to CREDUI_FLAGS_SERVER_CREDENTIAL
http://msdn.microsoft.com/en-us/library/windows/desktop/aa375177(v=vs.85).aspx
I have inspected the API call that word makes to credui.dll and it is identical to the one I am calling (aside from some captions).
But it produces different results.
My code produces this credential to be saved
The word api call/subsequent code produces this credential
However I cannot figure out how to get the credential target to save correctly so that office will load it without prompting. I'd prefer to even have the prompt load if there is no option as I can pre fill the username and password so that the user just has to click OK but I'd like to do it silently.
Additionally if there is anyway to disable word's WebDav support/force it to use the network drive as an actual network drive that would also work. I have been unable to find any answer. If anyone has any idea I would greatly appreciate it.

Related

What is the best way to access SharePoint in C#

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.

C# desktop application - how to save default admin username and password

I've been tasked with setting up default admin credentials for a .NET desktop application. As of right now, the application uses Windows admin credentials to access the manager page and I would like to add a local default admin account.
I imagine the user will go through the following process:
(1) Clean install of application
(2) User launches application
(3) App is in "logged out" state
(4) User logs in as manager with the provided default credentials (provided in user guide)
(5) Once logged in for the first time, prompt user to update local default credentials to a more secure password
After doing some research on google and stack overflow, I read that I definitely should not hard code the user credentials in the source code. I'm thinking of storing the default username/password in the app.config file. Then, in the manager page, the user can update the current username/password to something more secure. There will only be ONE local admin account so the username/password from the app.config file will need to be updated?
In other words, the default user credentials will be stored in app config. Then, modified whenever the user updates the local credentials. Does this approach work for the situation I described above? If not, I would appreciate any ideas. I've looked into DPApi as well but would prefer a simpler approach.
If you don't want use Active directory, AZMan or other popular solutions, you can store credentials in multiple ways:
In binary file with your own coding pattern.
In embedded databases such as SQlite.
Save credentials in windows registry.
Storing sensitive data in app.config is bad way.

Append or Inject domain into Username when logging into sharepoint 2013

I have set up SharePoint 2013 for my organization but the users have to always enter a domain (User1#domain.com) after their username.
I have searched but i cant find any solution or even where the file for this is located. I'm wondering if i can get some help either finding where that file is or an alternate solution for this issue. Thanks!
Switching my authentication type is not really an option either, and yes I want the user to be promoted for the password every time.
On the SharePoint server I went to IIS, clicked on the local host tree then in the center console under IIS I opened up Authentication. Click basic authentication then under actions click edit. Once there I entered a default domain name and voila, like magic it now works!
So if i understand correctly here your SharePoint farm domain (e.g. sharepoint.com) and users domain (user#companyXYZ) don't have a "trust relationship?.
When you access a office document from a library as an Untrusted Client (even though your login credentials are already authenticated by the browser session cookie) when an Office Application opens, IE does not pass authentication/trust/token to the next application to gain the same access that is already trusted with IE. The additional log-in prompts is because the documents opened with Office are trying to re-establish a trust per application, because the client machine is not trusted from a public web and a new authentication is requested.
May want to review : Authentication prompts when opening Microsoft Office documents
If you can provide a fiddler trace of an authentication and identify if you are using "classic" or "claims" i can help more.

Implement Single Signon in Windows without Azure

I am working in C# on a web application that requires a login username and password. This application is made to be compatible with Windows and is being written in VS 2013. In this company's network, all computers require user credentials, and in all cases the user's credentials for the app will be the same as their Windows logon credentials. Therefore we are trying to implement a system where, instead of signing onto Windows and then entering the same credentials again in the app, the app can access the Windows credentials that were given by the current user and attempt to sign in automatically with those. I know there is a way to do this using active directory with Azure, but for the time being we are trying to avoid using Azure. I have tried using WindowsIdentity.GetCurrent() and Environment.UserName so far, but both of those only supply the username, not the password, and we need the full credentials. It wouldn't shock me if this cannot be done in this way for security purposes, but if there is a way it would be incredibly helpful. Does anyone know of a way to access the current user's credentials? Thanks
You don't need Azure to accomplish this. Your application pool simply needs to have Windows Authentication enabled. You will not have access to the password, however.
After that, you will need to most likely write a HttpHandler which will get the HttpContext.Current.User.Identity value and check it against a database or collection of authorized users. You don't need to "re-authenticate".

Upload files on cloud using email address

So I am not sure if it is possible and if it is making sense at all. I am trying to learn and use cloud space in my application. So as a sample I was trying to create an application to upload files in Google Drive. I registered my application and used some references given by Google. And I am able to upload files now.
I registered my app using myname#gmail.com and used Client_Id and Client_Secret given in my account to create the app. When I upload the files, files get uploaded to my myname#gmail.com account. But what I want is, my app should give an option to user to login into there gmail accounts. Whoever logs in (say with email your#gmail.com), my app should be able to upload files to there account. I believe offline Google Drive app for desktop works the same way. Enter your username and password and files will sync to that account. Can anyone point me to a sample code please?
I want to upload files, read them, delete them, share them through my app. I am not giving any code sample, but if its needed let me know. Thanks.
You can do it. You will need to navigate user to a specific URL, where he will input his email and password. After that Google will give you authorization code and refresh token. Refresh token can be used to retrieve authorization code whenever it is expired.
This authorization code is used to work with user drive.
If your application is a web application you may navigate user to google and set callback to your custom URL.
If it is a windows forms application, then you have 2 options
Create custom browser window and parse DocumentTitle property
Navigate user's browser and ask him to copy-paste code from title (or do it automatically)
You may download an example from here
Just fill CLIENT_ID and CLIENT_SECRET constants.

Categories

Resources