keep your login creadianls works after close of the app and the system in universal apps - win-universal-app

I have developped a windows store app with C#,and I want to make my application keeps the login crediantials after the close of the application (like the Groove app after connexion and the close of the App,when I reopen it in an other time I get the application interface without putting login crediantials every time)
any explication in how to do that in universal apps please
thanks for help

Here's the solution to all your problems: https://msdn.microsoft.com/library/windows/apps/br227081
PasswordVault is the perfect place and the secure way to store your user credentials. It use the Windows Credential Manager and it allows you also to roam the credentials across devices, if this is the behavior you want to achieve.
Sample code:
// Create a new credentials set
var passwordCredential = new PasswordCredential("MyAppName", "username", "password");
// Stores the PasswordCredential in the PasswordVault
var passwordVault = new PasswordVault();
passwordVault.Add(passwordCredential);
// To later retrieve the credentials
var credentials = passwordVault.Retrieve("MyAppName", "username");
// To populate the Password property in the PasswordCredential
credentials.RetrievePassword();

it's a very common scenario.
You must use Storage folder to save all the data.
I recommend you save your file in json, serialize and Deserialize the data.
with this approach you can save the credentials of the user and when the user will open the app again you will need to check if there is a previous saved data( the login credentials) if yes you can skip the login page and navigate to the main page
https://msdn.microsoft.com/en-us/windows/uwp/files/quickstart-reading-and-writing-files

Related

Setting up an Application with Azure for use with Graph API outlook calendars

I'm aware that Graph API has a nice nuget package and I am confident on the code side of things, but my understanding is that I need to have the application set up in Azure and while there is a lot of documentation about this in general, I find it quite dense and I'm not confident I have the specifics down for how I need to set this portion up.
What I need my application to do is access an outlook calendar of a specific user that I own, read, search, add, delete and update calendar items. The integration assistant seems to suggest I need to configure a URI redirect and configure api permission. The default persmission is User.Read on graph API and if I try to add a permission, office 365 management seems like it might be the one I need except it specifically says just retrieving user information and nothing mentions outlook anywhere.
I need to know more or less the minimum steps in setting up the application in Azure to write a C# application that can make changes to outlook for a user.
need my application to do is access an outlook calendar of a specific user
Does it mean you need your app to have the abiltity to modify the callendar of any user you owned? If not, then it means you need your application to provide a sign in module and let users sign in, then the users can get authentication to call graph api and manage their own calendar, since this scenario, users give the delegate api permission, so they can't manage other users' calendar, so I don't think this is what you want.
If so, then you should use client credential flow to generate access token to call graph api. I think you know that when you want to call graph api, you have to get an access token which has correct permission first.
Ok, then let's come to the api permission, when you go to api document of the Calendar. You will see permissions like screenshot below:
Application permission type is suitable for client credential flow. And after viewing all the apis, you will find that they all need Calendars.ReadWrite except those not supporting Application type.
Then let's go to azure portal and reach Azure Active Directory. You need to create an Azure ad application and give the app Calendars.ReadWrite permission, then give the Admin consent.
Then you also need to create a client secret, pls go to Certificates & Secrets and add a new client secret, don't forget to copy the secret after you create it.
Now you've done all the steps. No need to set a redirect url, because you don't need to let the user to sign in your application. Let's see client credential flow document, it only require client_id, client_secret to generate access token.
Or in the code, you may use SDK like this :
using Azure.Identity;
using Microsoft.Graph;
public async Task<IActionResult> Index()
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "your_tenant_name.onmicrosoft.com";
var clientId = "azure_ad_app_id";
var clientSecret = "client_secret";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var calendar = new Calendar{ Name = "Volunteer" };
var events = await graphClient.Users["user_id_which_is_needed_to_list_calendar_events"].Events.Request()
.Header("Prefer","outlook.timezone=\"Pacific Standard Time\"")
.Select("subject,body,bodyPreview,organizer,attendees,start,end,location")
.GetAsync();
return View();
}

Remember last logged in users in Azure Active Directory Xamarin Forms

I am using Azure AD to authenticate the user in my Xamarin forms app and what I want to achieve in my UWP app that if one user lets says signed in the app and then signed out. On Next login flow Azure AD should show list of user who were logged in on that particular device so user can pick the user and just enter password.
In my case if I signout the user then it always start the flow from asking the email and password
Here is code snippet for signout
AuthenticationContext authContext = new AuthenticationContext($"{tenantUrl}/{tenantId}");
authContext.TokenCache.Clear();
Windows.Web.Http.Filters.HttpBaseProtocolFilter myFilter = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
var cookieManager = myFilter.CookieManager;
var cookieUri = new System.Uri(tenantUrl);
HttpCookieCollection myCookieJar = cookieManager.GetCookies(cookieUri);
foreach (HttpCookie cookie in myCookieJar)
{
cookieManager.DeleteCookie(cookie);
}
P.S: Seems to be issue for UWP ADAL package since samething is working fine on iOS
Great question!
There was a fix needed in ADAL (a new release needs to happen, so anything higher then 5.0.2-preview will have the fix) to handle this in UWP.
Add this code to your app:
var x = Windows.Security.Authentication.Web.WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
Take the value (something like this: ms-app://s-1-15-2-111638678-219698677-36916742-1909548894-372823757-39941306-27685825/) and register the value as a redirectUri in the portal for this app.
Then, back in the code,
instead of passing in the above value (x) as the redirectURI, pass in null. ADAL/MSAL will set the redirect uri to https://sso which will route through the WebAuthenticationManager, and you should now see a list of the accounts, like on iOS.
You also might be interested in this documentation as well, especially if having issues on corp net.
With ADAL package, you won't see last logged in users email id. But if you use MSAL package by default, you will be able to see the list of last logged in users email id. I tried on my local machine and with MSAL package I am able to see the user's email id list. Below is the screenshot.
I hope the above information is helpful.

Azure App Service Easy Auth

I have an Azure mobile backend set up with easy auth for facebook and google authentication and it works as expected.
Every time a user signs in with any of the supported providers, I want to be able to verify if it's a new user or not (e-mail not in database), without make an additional call from client. Is this possible?
Every time a user signs in with any of the supported providers, I want to be able to verify if it's a new user or not (e-mail not in database), without make an additional call from client. Is this possible?
As far as I know, we couldn't directly verify if it's a new user or not.
No matter you use server flow or client flow, easy auth will just return access token for the client to access the mobile backend resources, it will not check the user is new or old.
If you want to achieve this requirement, you need write your own logic.
You could write codes after the user login successfully.
For example, facebook login.
If you the use have login successfully,you could call GetAppServiceIdentityAsync extension method to get the login credentials, which include the access token needed to make requests against the Facebook Graph API.
// Get the credentials for the logged-in user.
var credentials =
await this.User
.GetAppServiceIdentityAsync<FacebookCredentials>(this.Request);
if (credentials.Provider == "Facebook")
{
// Create a query string with the Facebook access token.
var fbRequestUrl = "https://graph.facebook.com/me/feed?access_token="
+ credentials.AccessToken;
// Create an HttpClient request.
var client = new System.Net.Http.HttpClient();
// Request the current user info from Facebook.
var resp = await client.GetAsync(fbRequestUrl);
resp.EnsureSuccessStatusCode();
// Do something here with the Facebook user information.
var fbInfo = await resp.Content.ReadAsStringAsync();
}
Then you could check the database according to the user information.
More details about how to get user information in server side, you could refer to How to: Retrieve authenticated user information.

.NET Gmail OAuth2 for multiple users

We are building a solution that will need to access our customers Gmail accounts to read/send mail. On account signup, we'd have a pop-up for our customer to do Gmail auth page and then a backend process to periodically read their emails.
The documentation doesn't seem to cover this use case. For example https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth says that client tokens should be stored in client_secrets.json - what if we have 1000s of clients, what then?
Service accounts are for non-user info, but rather application data. Also, if I use the GoogleWebAuthorizationBroker and the user has deleted access or the tokens have expired, I don't want my backend server app to pop open a web brower, as this seems to do.
I would imagine I could use IMAP/SMTP accomplish this, but I don't think it's a good idea to store those credentials in my db, nor do I think Google wants this either.
Is there a reference on how this can be accomplished?
I have this same situation. We are planning a feature where the user is approving access to send email on their behalf, but the actual sending of the messages is executed by a non-interactive process (scheduled task running on an application server).
I think the ultimate answer is a customized IAuthorizationCodeFlow that only supports access with an existing token, and will not execute the authorization process. I would probably have the flow simulate the response that occurs when a user clicks the Deny button on an interactive flow. That is, any need to get an authorization token will simply return a "denied" AuthorizationResult.
My project is still in the R&D phase, and I am not even doing a proof of concept yet. I am offering this answer in the hope that it helps somebody else develop a concrete solution.
While #hurcane's answer more than likely is correct (haven't tried it out), this is what I got working over the past few days. I really didn't want to have to de/serialize data from the file to get this working, so I kinda mashed up this solution
Web app to get customer approval
Using AuthorizationCodeMvcApp from Google.Apis.Auth.OAuth2.Mvc and documentation
Store resulting access & refresh tokens in DB
Use AE.Net.Mail to do initial IMAP access with access token
Backend also uses AE.Net.Mail to access
If token has expired, then use refresh token to get new access token.
I've not done the sending part, but I presume SMTP will work similarly.
The code is based on SO & blog posts:
t = EF object containing token info
ic = new ImapClient("imap.gmail.com", t.EmailAddress, t.AccessToken, AuthMethods.SaslOAuth, 993, true);
To get an updated Access token (needs error handling) (uses the same API as step #1 above)
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["refresh_token"] = refresh;
data["client_id"] = "(Web app OAuth id)";
data["client_secret"] = "(Web app OAuth secret)";
data["grant_type"] = "refresh_token";
var response = wb.UploadValues(#"https://accounts.google.com/o/oauth2/token", "POST", data);
string Tokens = System.Text.Encoding.UTF8.GetString(response);
var token = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Tokens);
at = token.access_token;
return at;
}

Maintain secure session using PhoneGap

I have a simple jQuery mobile PhoneGap application which uses ajax call to server to authenticate a users credentials against servers db (uses CORS).
Once user is authenticated I setup some local storage variables for the session but I suspect this is not a secure method of maintaining state.
I'm wondering if there is a better & more secure way to keep track of the users session state. At the moment I'm thinking of implementing some kind of token based handshake between the app & the server for each subsequent server call post logon. I'm hoping there is a better more standard way to implement secure sessions in PhoneGap.
I think you shouldn't save origin credentials in local storage. At first, you should encrypt credentials by your encrypt algorithms and you can save it in local storage or preference(Android/iOS - best is store in preference) or anywhere you want. If another person get credentials, it have been encrypt, they not use it to authenticate with server(Only you had decrypt algorithms).
Continue, you must do something to prevent other person decompile your app. They will have your decrypt algorithms and use it to decrypt credentials-->origin credentials-->post to server success.
Have many way to secure your app, you can search and research.
Code demo in Android:
SharedPreferences sharedPref = getSharedPreferences("account", Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
user = your_encrypt(username);
pass = your_encrypt(password);
//encrypt and save account
editor.putString("username", user);
editor.putString("password", pass);
editor.commit();
//get account
String u = sharedPref.getString("username", "");
String p = sharedPref.getString("password", "");
//decrypt username/pass
username = your_decrypt(u);
password = your_decrypt(p);

Resources