how to create dll file of created project of send email.I am getting error for 'HttpPostedFileBase ' - dll

namespace web.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(EmailModel model, List attachments)
{
using (MailMessage mm = new MailMessage(model.Email, model.To))
{
mm.Subject = model.Subject;
mm.Body = model.Body;
foreach (HttpPostedFileBase attachment in attachments)
{
if (attachment != null)
{
string fileName = Path.GetFileName(attachment.FileName);
mm.Attachments.Add(new Attachment(attachment.InputStream, fileName));
}
}
mm.IsBodyHtml = false;
using (SmtpClient smtp = new SmtpClient())
{
smtp.Host = "smtp-mail.outlook.com";
smtp.EnableSsl = true;
NetworkCredential NetworkCred = new NetworkCredential(model.Email, model.Password);
smtp.UseDefaultCredentials = true;
smtp.Credentials = NetworkCred;
smtp.Port = 587;
smtp.Send(mm);
ViewBag.Message = "Email sent.";
}
}
return View();
}
}
}

Related

ASP.NET Core Web API - How to send Registration Notification Email without link and token

In my ASP.NET Core-6 Web API, I am sending email notification to users when his user registration account is created.
MailService:
public class MailService : IMailService
{
private readonly MailSettings _mailSettings;
private readonly ILogger _logger;
public MailService(MailSettings mailSettings, ILogger logger)
{
_logger = logger;
_mailSettings = mailSettings;
}
public async Task<bool> SendEmailAsync(MailRequest mailRequest)
{
var email = new MimeMessage { Sender = MailboxAddress.Parse(_mailSettings.Mail) };
email.To.Add(MailboxAddress.Parse(mailRequest.ToEmail));
email.Subject = mailRequest.Subject;
var builder = new BodyBuilder();
if (mailRequest.Attachments != null)
{
foreach (var file in mailRequest.Attachments.Where(file => file.Length > 0))
{
byte[] fileBytes;
await using (var ms = new MemoryStream())
{
file.CopyTo(ms);
fileBytes = ms.ToArray();
}
builder.Attachments.Add((file.FileName + Guid.NewGuid().ToString()), fileBytes, ContentType.Parse(file.ContentType));
}
}
builder.HtmlBody = mailRequest.Body;
email.Body = builder.ToMessageBody();
try
{
using var smtp = new SmtpClient();
smtp.Connect(_mailSettings.Host, _mailSettings.Port, SecureSocketOptions.StartTls);
smtp.Authenticate(_mailSettings.Mail, _mailSettings.Password);
await smtp.SendAsync(email);
smtp.Disconnect(true);
return true;
}
catch (Exception e)
{
_logger.Error(e, e.Source, e.InnerException, e.Message, e.ToString());
return false;
}
}
}
MailRequest:
public class MailRequest
{
public string ToEmail { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public List<IFormFile> Attachments { get; set; }
}
GetEmailBody:
public static async Task<string> GetEmailBody(string emailTempPath, string token, string email)
{
var link = $"https://myapp.com/Manager/RegisterManager?email={email}&token={token}";
var temp = await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), emailTempPath));
var emailBody = temp.Replace("**link**", link);
return emailBody;
}
Register:
public async Task<Response<string>> Register(RegisterUserDto model)
{
var user = _mapper.Map<AppUser>(model);
user.IsActive = true;
var response = new Response<string>();
using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _userManager.AddToRoleAsync(user, UserRoles.Customer);
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var encodedToken = TokenConverter.EncodeToken(token);
var userRole = await _userManager.GetRolesAsync(user);
var mailBody = await EmailBodyBuilder.GetEmailBody(user, userRole.ToList(), emailTempPath: "StaticFiles/Html/ConfirmEmail.html", linkName: "ConfirmEmail", encodedToken, controllerName: "Authentication");
var mailRequest = new MailRequest()
{
Subject = "Registration Notification",
Body = mailBody,
ToEmail = model.Email
};
bool emailResult = await _mailService.SendEmailAsync(mailRequest);
if (emailResult)
{
_logger.Information("Mail sent successfully");
var customer = new Customer
{
AppUser = user
};
await _unitOfWork.Customers.InsertAsync(customer);
await _unitOfWork.Save();
response.StatusCode = (int)HttpStatusCode.Created;
response.Succeeded = true;
response.Data = user.Id;
response.Message = "User created successfully! Please check your mail to verify your account.";
transaction.Complete();
return response;
}
_logger.Information("Mail service failed");
transaction.Dispose();
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.Succeeded = false;
response.Message = "Registration failed. Please try again";
return response;
}
response.Message = GetErrors(result);
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.Succeeded = false;
transaction.Complete();
return response;
};
}
I want to send the Username and Password to the user as Email notification. This will not include link and token. And the will not confirm, but just to know his Username and password.
How do I modify the code above to achieve this?
Thanks
It seems you are using Microsoft.AspNetCore.Identity for the functionality.
You can disable email verification as you intend to not require the user functionality.
services.AddIdentity<ApplicationUser, IdentityRole>(config =>
{
config.SignIn.RequireConfirmedEmail = false;
})
And you can have your Username information from var user = _mapper.Map<AppUser>(model); and password from RegisterUserDto model, just construct the email body with these value and put it in mailBody variable.

How to configure MailKit without password

In ASP.NET Core 6 Web API, I am using MailKit for Email configuration. I am using the SMTP server of my company which doesn't need a password.
I have this:
public class MailSettings
{
public string SmtpServer { get; set; }
public string SenderName { get; set; }
public string SenderEmail { get; set; }
public int SmtpPort { get; set; }
}
Since I am using my company SMTP configuration that needs no password, I use this method to send mails:
public async Task<bool> SendEmailAsync(MailRequest mailRequest)
{
var email = new MimeMessage { Sender = MailboxAddress.Parse(_mailSettings.SenderEmail) };
email.To.Add(MailboxAddress.Parse(mailRequest.ToEmail));
email.Subject = mailRequest.Subject;
var builder = new BodyBuilder();
if (mailRequest.Attachments != null)
{
foreach (var file in mailRequest.Attachments.Where(file => file.Length > 0))
{
byte[] fileBytes;
await using (var ms = new MemoryStream())
{
file.CopyTo(ms);
fileBytes = ms.ToArray();
}
builder.Attachments.Add((file.FileName + Guid.NewGuid().ToString()), fileBytes, ContentType.Parse(file.ContentType));
}
}
builder.HtmlBody = mailRequest.Body;
email.Body = builder.ToMessageBody();
try
{
using var smtp = new SmtpClient();
smtp.Connect(_mailSettings.SmtpServer, _mailSettings.SmtpPort, SecureSocketOptions.StartTls);
smtp.Authenticate(_mailSettings.SenderEmail);
await smtp.SendAsync(email);
smtp.Disconnect(true);
return true;
}
catch (Exception e)
{
_logger.Error(e, e.Source, e.InnerException, e.Message, e.ToString());
return false;
}
}
I got this error:
Argument 1: cannot convert from 'string' to 'MailKit.Security.SaslMechanism'
and it highlights this line of code:
smtp.Authenticate(_mailSettings.SenderEmail);
Expecting me to do it this way:
smtp.Authenticate(_mailSettings.SenderEmail, _mailSettings.Password);
How do I resolve this without password?
Thanks

Asp.net Core Object reference not set to an instance of an object

ASP.NET CORE API
The logged in user gives an error in the code below while adding a photo. Can anybody help?
var currentUserId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value)
This code gives an error. Help me
Object reference not set to an instance of an object
PhotosController.cs
[HttpPost]
public ActionResult AddPhotoForCity(int cityId,[FromForm]PhotoForCreationDto photoForCreationDto)
{
var city = _appRepository.GetCityById(cityId);
if (city == null)
{
return BadRequest("Could not find the city.");
}
var currentUserId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
karşılaştırmak gibi
if (currentUserId != city.UserId)
{
return Unauthorized();
}
var file = photoForCreationDto.File;
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using (var steam = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams()
{
File = new FileDescription(file.Name,steam)
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
photoForCreationDto.Url = uploadResult.Url.ToString();
photoForCreationDto.PublicId = uploadResult.PublicId;
var photo = _mapper.Map<Photo>(photoForCreationDto);
photo.City = city;
if (!city.Photos.Any(p => p.IsMain))
{
photo.IsMain = true;
}
city.Photos.Add(photo);
if (_appRepository.SaveAll())
{
//eklenen fotoğrafı döndürüyoruz
var photoToRetun = _mapper.Map<Photo>(photoForCreationDto);
return CreatedAtRoute("GetPhoto", new {id = photo.Id}, photoToRetun);
}
return BadRequest("Cloud not add the photo");
}
AuthController.cs
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private IAuthRepository _authRepository;
private IConfiguration _configuration;
public AuthController(IAuthRepository authRepository, IConfiguration configuration)
{
_authRepository = authRepository;
_configuration = configuration;
}
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] UserForRegisterDto userForRegisterDto)
{
if (await _authRepository.UserExists(userForRegisterDto.UserName))
{
ModelState.AddModelError("UserName", "Username already exists");
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var userToCreate = new User
{
UserName = userForRegisterDto.UserName
};
var createdUser = await _authRepository.Register(userToCreate, userForRegisterDto.Password);
return StatusCode(201);
}
[HttpPost("login")]
public async Task<ActionResult> Login([FromBody] UserForLoginDto userForLoginDto)
{
var user = await _authRepository.Login(userForLoginDto.UserName, userForLoginDto.Password);
if (user == null)
{
return Unauthorized();
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_configuration.GetSection("AppSettings:Token").Value);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.UserName)
}),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key)
, SecurityAlgorithms.HmacSha512Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return Ok(tokenString);
}
}
From the above code snippet you have shared, they mostly likely reason you are getting this error is because the user is not logged in, and hence this line of code
User.FindFirst(ClaimTypes.NameIdentifier).Value
is throwing an exception.
You could either do it like this.
User.FindFirst(ClaimTypes.NameIdentifier)?.Value
Or
[HttpPost]
[Authorize] // make sure you authorize your action method by adding this attribute and
// only allow logged in user to access it.
public ActionResult AddPhotoForCity(int cityId,[FromForm]PhotoForCreationDto photoForCreationDto)
{
}
try this one:
var currentUserId = int.Parse(User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value);

Login API method returning 400 Bad request in Xamarin Forms

I have a login API method in Xamarin for which I am using a .net core project.The back end login in the web application works perfectly returning the token once I am logged in,but on the client side in Xamarin I am having troubles with it as the response returns a 400 Bad request.I checked the API and everything seems to be fine.I pass the token in the headers for the request along with the credentials and I am checking for the request.
This is the client side API:
public async Task<string> Login(string email, string password)
{
var urlLogin = "http://10.0.2.2:5000/api/Token/";
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", email),
new KeyValuePair<string, string>("password", password),
new KeyValuePair<string, string>("grant_type", "password")
});
var httpClient = new HttpClient();
var authData = string.Format("{0}:{1}", email, password);
var authHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(authData));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authHeaderValue);
var json = JsonConvert.SerializeObject(formContent);
var content = new StringContent(json, Encoding.UTF8, "application/json");
try
{
CancellationTokenSource cts = new CancellationTokenSource();
httpClient.DefaultRequestHeaders.Accept.Clear();
var responseMessage = httpClient.PostAsync(urlLogin, content).Result;
if(responseMessage.IsSuccessStatusCode)
{
await App.Current.MainPage.DisplayAlert("Login succesful!", "Welcome", "ok", "cancel");
await Xamarin.Forms.Application.Current.MainPage.Navigation.PushModalAsync(new UsersPage());
}
else
{
await App.Current.MainPage.DisplayAlert("Wrong credentials", "Please try again!", "ok", "cancel");
}
}
catch (Exception ex)
{
ex.Message.ToString();
throw;
}
return "";
}
The server-side login api:
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Post(User userData)
{
if (userData != null && userData.Email != null && userData.Password != null)
{
var user = await GetUser(userData.Email, userData.Password);
if (user != null)
{
//create claims details based on the user information
var claims = new[] {
new Claim(JwtRegisteredClaimNames.Sub, config["Jwt:Subject"]),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim("Id", user.Id.ToString()),
new Claim("Name", user.Name),
new Claim("Phone", user.Phone.ToString()),
new Claim("Email", user.Email),
new Claim ("ConfPassword",user.ConfPassword)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["Jwt:Key"]));
var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(config["Jwt:Issuer"], config["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddDays(1), signingCredentials: signIn);
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}
else
{
return BadRequest("Invalid credentials");
}
}
else
{
return BadRequest();
}
}
private async Task<User> GetUser(string email, string password)
{
return await _context.User.FirstOrDefaultAsync(u => u.Email == email && u.Password == password);
}
User.cs
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Password { get; set; }
public string ConfPassword { get; set; }
}
Can someone please help me figure out what is wrong with the API?I am new in working with mobile API so please bear with me.
I have managed to make it work as #Jason suggested.This is the working method on the client side:
public async Task<string> Login(User user)
{
var urlLogin = "http://10.0.2.2:5000/api/Token/";
var httpClient = new HttpClient();
var authData = string.Format("{0}:{1}", user.Email, user.Password);
var authHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(authData));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authHeaderValue);
var json = JsonConvert.SerializeObject(user);
var content = new StringContent(json, Encoding.UTF8, "application/json");
try
{
CancellationTokenSource cts = new CancellationTokenSource();
httpClient.DefaultRequestHeaders.Accept.Clear();
var responseMessage = httpClient.PostAsync(urlLogin, content).Result;
if(responseMessage.IsSuccessStatusCode)
{
await App.Current.MainPage.DisplayAlert("Login succesful!", "Welcome", "ok", "cancel");
await Xamarin.Forms.Application.Current.MainPage.Navigation.PushModalAsync(new UsersPage());
}
else
{
await App.Current.MainPage.DisplayAlert("Wrong credentials", "Please try again!", "ok", "cancel");
}
}
catch (Exception ex)
{
ex.Message.ToString();
throw;
}
return "";
}

Getting email from oauth authentication (Microsoft)

How can I get the email from microsoft account? I'm doing the following:
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
//...
string email = null;
if (result.Provider.ToLower() == "google")
{
email = result.ExtraData["email"];
}
else if (result.Provider.ToLower() == "facebook")
{
email = result.ExtraData["username"];
}
else if (result.Provider.ToLower() == "microsoft")
{
email = result.ExtraData["????"];
}
}
For google and facebook I'm able to get the email but I can't with microsoft? What kew should I use?
Solution:
public class MicrosoftScopedClient : IAuthenticationClient
{
private string clientId;
private string clientSecret;
private string scope;
private const string baseUrl = "https://login.live.com/oauth20_authorize.srf";
private const string tokenUrl = "https://login.live.com/oauth20_token.srf";
public MicrosoftScopedClient(string clientId, string clientSecret, string scope)
{
this.clientId = clientId;
this.clientSecret = clientSecret;
this.scope = scope;
}
public string ProviderName
{
get { return "Microsoft"; }
}
public void RequestAuthentication(HttpContextBase context, Uri returnUrl)
{
string url = baseUrl + "?client_id=" + clientId + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString()) + "&scope=" + HttpUtility.UrlEncode(scope) + "&response_type=code";
context.Response.Redirect(url);
}
public AuthenticationResult VerifyAuthentication(HttpContextBase context)
{
string code = context.Request.QueryString["code"];
string rawUrl = context.Request.Url.ToString();
//From this we need to remove code portion
rawUrl = Regex.Replace(rawUrl, "&code=[^&]*", "");
IDictionary<string, string> userData = GetUserData(code, rawUrl);
if (userData == null)
return new AuthenticationResult(false, ProviderName, null, null, null);
string id = userData["id"];
string username = userData["email"];
userData.Remove("id");
userData.Remove("email");
AuthenticationResult result = new AuthenticationResult(true, ProviderName, id, username, userData);
return result;
}
private IDictionary<string, string> GetUserData(string accessCode, string redirectURI)
{
string token = QueryAccessToken(redirectURI, accessCode);
if (token == null || token == "")
{
return null;
}
var userData = GetUserData(token);
return userData;
}
private IDictionary<string, string> GetUserData(string accessToken)
{
ExtendedMicrosoftClientUserData graph;
var request =
WebRequest.Create(
"https://apis.live.net/v5.0/me?access_token=" + EscapeUriDataStringRfc3986(accessToken));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(responseStream))
{
string data = sr.ReadToEnd();
graph = JsonConvert.DeserializeObject<ExtendedMicrosoftClientUserData>(data);
}
}
}
var userData = new Dictionary<string, string>();
userData.Add("id", graph.Id);
userData.Add("username", graph.Name);
userData.Add("name", graph.Name);
userData.Add("link", graph.Link == null ? null : graph.Link.AbsoluteUri);
userData.Add("gender", graph.Gender);
userData.Add("firstname", graph.FirstName);
userData.Add("lastname", graph.LastName);
userData.Add("email", graph.Emails.Preferred);
return userData;
}
private string QueryAccessToken(string returnUrl, string authorizationCode)
{
var entity =
CreateQueryString(
new Dictionary<string, string> {
{ "client_id", this.clientId },
{ "redirect_uri", returnUrl },
{ "client_secret", this.clientSecret},
{ "code", authorizationCode },
{ "grant_type", "authorization_code" },
});
WebRequest tokenRequest = WebRequest.Create(tokenUrl);
tokenRequest.ContentType = "application/x-www-form-urlencoded";
tokenRequest.ContentLength = entity.Length;
tokenRequest.Method = "POST";
using (Stream requestStream = tokenRequest.GetRequestStream())
{
var writer = new StreamWriter(requestStream);
writer.Write(entity);
writer.Flush();
}
HttpWebResponse tokenResponse = (HttpWebResponse)tokenRequest.GetResponse();
if (tokenResponse.StatusCode == HttpStatusCode.OK)
{
using (Stream responseStream = tokenResponse.GetResponseStream())
{
using (StreamReader sr = new StreamReader(responseStream))
{
string data = sr.ReadToEnd();
var tokenData = JsonConvert.DeserializeObject<OAuth2AccessTokenData>(data);
if (tokenData != null)
{
return tokenData.AccessToken;
}
}
}
}
return null;
}
private static readonly string[] UriRfc3986CharsToEscape = new[] { "!", "*", "'", "(", ")" };
private static string EscapeUriDataStringRfc3986(string value)
{
StringBuilder escaped = new StringBuilder(Uri.EscapeDataString(value));
// Upgrade the escaping to RFC 3986, if necessary.
for (int i = 0; i < UriRfc3986CharsToEscape.Length; i++)
{
escaped.Replace(UriRfc3986CharsToEscape[i], Uri.HexEscape(UriRfc3986CharsToEscape[i][0]));
}
// Return the fully-RFC3986-escaped string.
return escaped.ToString();
}
private static string CreateQueryString(IEnumerable<KeyValuePair<string, string>> args)
{
if (!args.Any())
{
return string.Empty;
}
StringBuilder sb = new StringBuilder(args.Count() * 10);
foreach (var p in args)
{
sb.Append(EscapeUriDataStringRfc3986(p.Key));
sb.Append('=');
sb.Append(EscapeUriDataStringRfc3986(p.Value));
sb.Append('&');
}
sb.Length--; // remove trailing &
return sb.ToString();
}
protected class ExtendedMicrosoftClientUserData
{
public string FirstName { get; set; }
public string Gender { get; set; }
public string Id { get; set; }
public string LastName { get; set; }
public Uri Link { get; set; }
public string Name { get; set; }
public Emails Emails { get; set; }
}
protected class Emails
{
public string Preferred { get; set; }
public string Account { get; set; }
public string Personal { get; set; }
public string Business { get; set; }
}
}
AuthConfig.cs
public static class AuthConfig
{
public static void RegisterAuth()
{
Dictionary<string, object> MicrosoftsocialData = new Dictionary<string, object>();
MicrosoftsocialData.Add("Icon", "../Content/icons/microsoft.png");
OAuthWebSecurity.RegisterClient(new MicrosoftScopedClient("XXXXXXXX", "YYYYYYYYYYYYY",
"wl.basic wl.emails"), "Microsoft", MicrosoftsocialData);
//......
}
}
Usage:
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
//...
string email = null;
if (result.Provider.ToLower() == "google")
{
email = result.ExtraData["email"];
}
else if (result.Provider.ToLower() == "facebook")
{
email = result.ExtraData["username"];
}
else if (result.Provider.ToLower() == "microsoft")
{
email = result.UserName;
}
}
Based on: How OAuthWebSecurity to obtain emails for different oauth clients, but Microsoft Client doesn’t return email, it didn’t include scope “wl.emails”
or even simpler: https://stackoverflow.com/a/22723713/1586498
var mo =
new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationOptions
{
CallbackPath = new Microsoft.Owin.PathString("/Callbacks/External"),//register at oAuth provider
ClientId = "<<yourclientid>>",
ClientSecret = "<<yourclientsecret>>",
Provider = new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationProvider
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new Claim(providerKey, context.Identity.AuthenticationType));
context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Identity.FindFirstValue(ClaimTypes.Name)));
return System.Threading.Tasks.Task.FromResult(0);
}
}
};
mo.Scope.Add("wl.basic");
mo.Scope.Add("wl.emails"); //HERE IS THE GOLD
app.UseMicrosoftAccountAuthentication(mo);
and my way of grabbing them:
var externalIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
externalIdentity.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Email));
amp's answer really helped me out.
Also want to mention that you have to check the 'Live SDK support' checkbox when you register your application (https://apps.dev.microsoft.com/) - otherwise the OAuth service complains that you don't have a client secret (even if you do).
Just wanted to add how to do this without using the AuthConfig.cs stuff in case anyone is interested (a bit more manual, but it makes it easier to understand if you're not familiar with the framework):
public ActionResult LoginWithMicrosoftAccount(CancellationToken cancellationToken)
{
var client = new MicrosoftScopedClient(appID, appsecret, "wl.basic wl.emails");
var urlNoQueryString = Request.Url.GetLeftPart(UriPartial.Path);
AuthenticationResult result = null;
if(Request.QueryString["error"]!= null)
{//Microsoft service returns error
return View();
}
if (Request.QueryString["code"] != null)
{
result = client.VerifyAuthentication(this.HttpContext);
//at this point, you should get the username from result.UserName
}
if(Request.QueryString["code"]==null || result.UserName == null)
{//will do the redirection
client.RequestAuthentication(this.HttpContext, new Uri(urlNoQueryString));
}
return View();
}