I use this tutorial Microsoft Email Configuration for .net Core,
Everything works correctly, something I wonder. In the traditional smtp setup we were specifying the password along with the email, why doesn't the SendGrid system require a password for email?
Traditional smtp setup we enter password with email as below.
var smtpClient = new SmtpClient
{
Host = "smtp.gmail.com", // set your SMTP server name here
Port = 587, // Port
EnableSsl = true,
Credentials = new NetworkCredential("from#gmail.com", "password")
};
But I didn't understand this tutorial SendGrid does not want password just only want mail adress.
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage()
{
From = new EmailAddress("Joe#contoso.com", "Joe Smith"),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
msg.AddTo(new EmailAddress(email));
Another question,
If I changed email name ("Joe#contoso.com") and send email, The message sends by Joe. If I change the email address to microsoft, it sends email on behalf of microsoft why ?.
From = new EmailAddress("Joe#contoso.com", "Joe Smith"),
or
From = new EmailAddress("Joe#microsoft.com", "Microsoft"),
Okay I know SendGridKey stores SendGrid Api key but what does "SendGridUser" do ?
public class AuthMessageSenderOptions
{
public string SendGridUser { get; set; }
public string SendGridKey { get; set; }
}
Thanks.
The API key that you're using to connect is unique to you. This is why it should be kept secret. Sendgrid identifies you through the API key instead of an email/password combination.
Related
I am working on a requirement where I need to validate user with active directory account.
For this I have used LdapConnection with NetworkCredential and PrincipalContext and in all cases I am able to validate user without SSL.
But I need to use validate user with SSL. I have also used the correct port i.e 636/TCP LDAP SSL
Following is the code I did with PrincipalContext
using (principalContext = new PrincipalContext(ContextType.Domain, ldapServerIp, null, ContextOptions.Negotiate | ContextOptions.SecureSocketLayer, userName, password))
{ bool isCredentialValid = principalContext.ValidateCredentials(userName, password);}
Following is code I did with
using (ldapConnection = new LdapConnection(ldapServerIp))
{
var networkCredential = new NetworkCredential(_username, _password, ldapServerIp);
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.AuthType = AuthType.Negotiate;
ldapConnection.Bind(networkCredential);
}
Does anyone have did this earlier successfully. If there is any solution that will be very helpful.
Both of those should work just fine, as long as you specify the LDAPS port (usually 636). So your ldapServerIp variable should be set to something like example.com:636.
We have been using Amplify and Cognito to register our users for an Angular6 application deployed to Lambda. The client wanted to transition from email to username as primary user identification. So we created a new user pool / client. I don't have visibility into the configuration settings, I was simply given new user pool, identity pool, and client id's. Then I changed the code for application signup to look like this:
return from(Auth.signUp({
'username': username, // was email
'password': password,
attributes: { // added these
'email': email,
'phone_number': phone_number,
'family_name': name,
'birthdate': DOB,
'custom:last_4_ssn': SSN // custom attribute
}}));
The response I'm getting with no other changes made is: Unable to verify secret hash for client. Google claims the problem is that secretAccess is currently an unsupported configuration, but the guy who has access to these services swears to me that nowhere is secretAccess configured in our setup.
I apologize for not having access to the configuration, but is there any other possible reason to receive this error?
That error is probably originating from the fact that the app client you are connected to has an associated secret key. When you create a user pool app client, it generates a secret by default:
Right now, with React-Native Amplify you have to use an app client that does not have a secret key generated. So when you create a new app client with your desired attributes, make sure the "Generate client secret" box is unchecked.
The solution is to pass secret_hash along with the adminAuthInitiate Request. And to calculate the secret hash you can use the following method:
public static String calculateSecretHash(String userPoolClientId, String userPoolClientSecret, String userName) {
final String HMAC_SHA256_ALGORITHM = "HmacSHA256";
SecretKeySpec signingKey = new SecretKeySpec(
userPoolClientSecret.getBytes(StandardCharsets.UTF_8),
HMAC_SHA256_ALGORITHM);
try {
Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
mac.init(signingKey);
mac.update(userName.getBytes(StandardCharsets.UTF_8));
byte[] rawHmac = mac.doFinal(userPoolClientId.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(rawHmac);
} catch (Exception e) {
throw new RuntimeException("Error while calculating ");
}
}
How to Pass Secret_Hash
Map<String, String> authParams = new HashMap<>(2);
authParams.put("USERNAME", <username>);
authParams.put("PASSWORD", <password>);
authParams.put("SECRET_HASH", calculateSecretHash(cognitoClientId, cognitoClientSecret, <username>));
AdminInitiateAuthRequest authRequest = new AdminInitiateAuthRequest()
.withClientId(userPool.getClientId()).withUserPoolId(userPool.getUserPoolId())
.withAuthFlow(AuthFlowType.ADMIN_NO_SRP_AUTH).withAuthParameters(authParams);
AdminInitiateAuthResult result = cognito.adminInitiateAuth(authRequest);
auth = result.getAuthenticationResult();
I'm looking for a method to validate the email address before sending. On email dns server.
I do NOT need regex or form email validation.
If user inputs test#google.com I want to know if there is an address like this on google server. I know there are some products that do the email validation. But we do not have money for that.
I'm using .netCore mailkit as smptClient. I've saw that there is a verify method but it somehow does the call but never returns.
Can you help please?
The only way to validate an email address is to send an email to that address with a link the user must click. That link should have a token uniquely generated for the user. Your site, then, looks up the token from the user when the user visits your site with that link and marks the associated user's email as verified.
If you're using Identity, support for this is baked in. There's a tutorial in the Microsoft docs. Essentially, it involves just adding a line in your AddIdentity config in Startup.cs:
config.SignIn.RequireConfirmedEmail = true;
Then, in your register action, you'd use the following to generate the URL for the link in the confirmation email:
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
Next, just send the email to the user in any way you like. In your email confirmation action, the following confirms the email based on the code in the URL:
var result = await _userManager.ConfirmEmailAsync(user, code);
EDIT
The Url.EmailConfirmationLink method actually comes from an extension added in the generated code when you add individual auth to a new project. Here's the code for that, for reference:
public static string EmailConfirmationLink(this IUrlHelper urlHelper, string userId, string code, string scheme)
{
return urlHelper.Action(
action: nameof(AccountController.ConfirmEmail),
controller: "Account",
values: new { userId, code },
protocol: scheme);
}
I'm trying to load data from Office365 email without need for user interaction. I've created Azure App and I have Client ID and Client secret.
I also have user information (email + password).
I need to call Office365 API to download emails from mailbox. But I need application to download them in background without user interaction (redirecting to MS/Office365 login page) to get authenticated/logged into mailbox.
Is there any way how to do this only through Office API, without need of redirection?
Thanks for any info.
Yes, you are able to create a daemon service app using the Client Credential flow to authenticate the app.
Here is a code sample to retrieve the mails using Microsoft Graph SDK with this flow:
string clientId = "";
string clientsecret = "";
string tenant = "";
string resourceURL = "https://graph.microsoft.com";
string authority = "https://login.microsoftonline.com/" + tenant + "/oauth2/token";
string userMail = "user1#yourdomain.onmicrosoft.com";
var credential = new ClientCredential(clientId, clientsecret);
AuthenticationContext authContext =new AuthenticationContext(authority);
var authResult = await authContext.AcquireTokenAsync(resourceURL, credential);
var graphserviceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
(requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authResult.AccessToken);
return Task.FromResult(0);
}));
var items = await graphserviceClient.Users[userMail].Messages.Request().OrderBy("receivedDateTime desc").GetAsync();
foreach (var item in items)
{
Console.WriteLine(item.Subject);
}
And we need to register the app on the Azure AD portal and grant the app Mail.Read scope like figure below:
Refer to here for more detail about calling Microsoft Graph in a service or daemon app
I'm writing an Add-in for Office365/Outlook. The Add-in runs on a web-server that presents information from a third-party system. I need to make sure it only presents information related to the username (or email address) logged in. I've successfully sent and validated the Exchange identity token on my server, using the PHP example code provided by Microsoft:
https://dev.office.com/docs/add-ins/outlook/use-php-to-validate-an-identity-token
My problem is that the identity token does not contain any username or email adress, the closest I get is "msexchuid", but I can't make any sense out of that numeric user identifier in the third-party system.
On the client side the Add-in javascript can get a username and email via "Office.context.mailbox.userProfile", however I don't just want to forward that to my web server as it could be faked.
Is there a way to make the Identity token contain the username/email (that would be great!), or is it possible from my web server's server side PHP script lookup further user details based on the identity token?
The id token is used to intend to integrate with third-party application for SSO. As you mentioned that it only include a unique id of Exchange.
As a workaround, we can get from the callback token via the getCallbackTokenAsync method which include the SMTP address directly. And to validate the callback token, we can verify whether we can get the item info with EWS.
For example, there is an ‘parentItemId’ in the callback token. It is same that retrieve the claims from the callback token as id token since there are is JWT token. You can refer to here for more detail.
Then we can use the code below to get the item information from EWS:
public bool Post([FromBody]EWSRequest request)
{
ExchangeService service = new ExchangeService();
service.Credentials = new OAuthCredentials(request.token);
service.Url = new Uri(request.ewsURL);
//get item id from callback token
var itemId = "";
Item item = Item.Bind(service, itemId);
var subject = item.Subject;
return subject.Length>0;
}
public class EWSRequest
{
public string token;
public string ewsURL;
}
JavarScript :
Office.context.mailbox.getCallbackTokenAsync(getCallbackTokenCallback)
function getCallbackTokenCallback(asyncResult) {
var _token = asyncResult.value;
var _ewsURL = Office.context.mailbox.ewsUrl;
var serviceEndpoint = "https://localhost:44300/API/token/"
var postData={ token: _token, ewsURL: _ewsURL }
$.ajax({
url: serviceEndpoint,
type: "post",
contentType: "application/json",
data: JSON.stringify(postData),
success: function (result) {
var ret = result;
}
})
}