Last post Aug 06, 2017 06:12 PM by JSWilsonX
Jul 26, 2017 02:02 PM|JSWilsonX|LINK
I am trying to implement external Authentication in my MVC project. The document:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/microsoft-logins gives a good overview of the process.
I have Google, Twitter & Facebook working. Just need to pin down Microsoft. This is what the relevant section of startup.Auth.cs looks like:
ClientId = Configuration["Authentication:Microsoft:ClientId"],
ClientSecret = Configuration["Authentication:Microsoft:ClientSecret"]
This allows me to authenticate the user.
The research I have done shows that others have added the scopes wl.signin, wl.emails and wl.contacts_emails to their MicrosoftAccountAuthenticationOptions. Those posts were written between 2012-2015.
I have tried adding the scopes wl.signin, wl.emails and wl.contacts_emails. However, they cause the Microsoft login page to report the following error: AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope wl.signin, wl.emails,
wl.contacts_emails is not valid. The scope combination of openid and email seems to work, that is, it does not cause an error because it is invalid. However, the scope openid is overkill for what I am trying to do. That is, I think it is too much to ask from
the user. It is also rejected by Microsoft authentication. The scope email all by itself doesn't work.
This is particularly weird because the template that Visual Studio sets up assumes that the external authentication provider will supply an email address.
How do I get only the user's email?
Jul 27, 2017 07:33 AM|Jean Sun|LINK
How do I get only the user's email?
Based on my understanding, the Scope property of the MicrosoftAccountOptions is read only now and the value is set to
https://graph.microsoft.com/user.read in the
MicrosoftAccountOptions()'s default constructor. You can't modify the Scope property to set the permissions of the application.
AuthenticationScheme = MicrosoftAccountDefaults.AuthenticationScheme;
DisplayName = AuthenticationScheme;
CallbackPath = new PathString("/signin-microsoft");
AuthorizationEndpoint = MicrosoftAccountDefaults.AuthorizationEndpoint;
TokenEndpoint = MicrosoftAccountDefaults.TokenEndpoint;
UserInformationEndpoint = MicrosoftAccountDefaults.UserInformationEndpoint;
More about the source code of MicrosoftAccountOptions :
Jul 27, 2017 01:41 PM|JSWilsonX|LINK
Jean, What you are saying sounds like you think it cannot be done. However, when I logged on to this site it used the Microsoft Authentication and it
only authorized the release of my email. This is exactly the effect I would like to have. So I know it can be done.
Jul 28, 2017 01:45 AM|Jean Sun|LINK
Because the default value set to the scope is user.read, it will has the permission to Sign-in and read user profile. Allows users to sign-in to the app, and allows the app to read the profile of signed-in users. It also allows
the app to read basic company information of signed-in users. The email should be included in the profile of the user.
What you are saying sounds like you think it cannot be done.
I just found a way that can be used to set the scope. Sorry about my mistake.
var options = new MicrosoftAccountOptions();
options.ClientId = Configuration["Authentication:Microsoft:ClientId"];
options.ClientSecret = Configuration["Authentication:Microsoft:ClientSecret"];
//If you don't want the default scope settings, you can clear it
You can find more about the Microsoft Graph permissions in the following link.
Jul 28, 2017 04:59 PM|JSWilsonX|LINK
Thanks for your help. It does not look like the email is part of the user profile notwithstanding the statement in the document: Important The Microsoft
Authentication Library (MSAL) currently specifies offline_access, openid, profile, and email by default in authorization and token requests. If I don't specify these items in the
scope the user is not asked to aprove them. I think it has to be specifically requested. mail.read allows me to
read the users email. Which is not what I want. email -
view users' email address, is what I want. However, it is not accepted without
openid - Sign users in. I don't think I want that. In either case While a user can approve both, they still don't get authenticated. AuthenticationManager.GetExternalLoginInfoAsync() returns a null in ExternalLoginCallback.
Jul 31, 2017 02:13 AM|Jean Sun|LINK
However, it is not accepted without openid
Based on my understanding, the openid is used to verify the identity of the user, if you don't have the openid, how can you tell the server that the current user is authenticated?
So i think the openid is required.
Aug 01, 2017 01:35 PM|JSWilsonX|LINK
Ok, I'll use openid and email in the scope. However, I still don't get the email address! loginInfo does not contain it as is the case with Facebook and Google. Where am I suposed to find it?
Aug 02, 2017 08:49 AM|Jean Sun|LINK
Please try use the following code to get the email of the MS login user.
var info = await _signInManager.GetExternalLoginInfoAsync();
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
Aug 06, 2017 06:12 PM|JSWilsonX|LINK
The problem turns out that I was using ASP.Net Web Application(.Net Framework) instead of ASP.Net Core Web Application (.Net
Framework). While they are similar they behave differently. Now I can get the email just as you suggested.