I am trying to implement two factor authentication in my project. For SMS service i use twilio. But when the SendSmsMessage() is called always it says:
core.cs not found error
I have made a lot of search on the internet. But I could not find a solution. Any suggestions.
Twilio developer evangelist here.
I think you're trying to copy the source directly into your code and hence having issues with the dependencies. My suggestion would be to install the Nuget package from Package Manager Console.
Then just run:
Install-Package Twilio
After installing it you should be able to get it going in any file by just doing the following:
using System;
using Twilio;
class Example
{
static void Main(string[] args)
{
// Find your Account Sid and Auth Token at twilio.com/user/account
string AccountSid = "{{ account_sid }}";
string AuthToken = "{{ auth_token }}";
var twilio = new TwilioRestClient(AccountSid, AuthToken);
var sms = twilio.SendSmsMessage(from, to, message);
Console.WriteLine(sms.Sid);
}
}
Also, because you mentioned you're trying to do 2FA, it may be worth mentioning another one of our products called Authy. Authy takes away al the complexity in two factor authentication and is obviously powered by Twilio. Here's a link to a tutorial showing how to implement it in .NET MVC.
Let me know if I can help you further.
Related
In my application, we presently are using ServiceClientCredentials from Microsoft.Rest. We are migrating parts of our application over to start using Azure.ResourceManager's ArmClient.
Basically all of our previous application integrations into Azure were using Microsoft.Azure.ResourceManager, which exposed agents like BlobClient or SecretClient, and these all accepted ServiceClientCredentials as a valid token type.
Now, with ArmClient I need to authenticate using DefaultAzureCredential which derives from Azure.Core's TokenCredential.
Surprisingly I haven't been able to find any examples yet of how to create this TokenCredential.
DefaultAzureCredential just works on my local PC since I'm signed into Visual Studio, but not on my build pipeline where I use Certificate based auth exposed as a ServiceClientCredential.
This was easier than I thought. The fix ended up being adding a new ServiceCollection extension method and passing in IWebHostEnvironment.
I use that to determine whether running in local debug, in which case we can use DefaultAzureCredential, or whether running in prod mode, in which case we should use Certificate Based auth.
It looks somewhat like this and works like a charm.
public static IServiceCollection AddDefaultAzureToken (this IServiceCollection services, IWebHostEnvironment environment)
{
if (environment.IsDevelopment())
{
var l = new DefaultAzureCredential();
services.AddSingleton<TokenCredential, l>;
}
else
{
var certCredential= new ClientCertificateCredential(null, null, "Abc");
services.AddSingleton<TokenCredential, certCredential>;
}
return services;
}
This works since DefaultAzureCredential and ClientCertficateCredential all have a common ancestor of TokenCredential, and the L in SOLID, the Liskov Substitution principle tells us that any implementation of a class can be substituted for any other instance of that class without breaking the application.
Note: the above sample was pseudocode and may need slight changing to work in your environment and should be cleaned to match your teams coding standards.
I'm able to call RegisterForRemoteNotifications(); from the AppDelegate to get the Token. I'm then using an APN server I built to update Apple Passes. I'm sending a message with the correct payload, headers etc..., but nothing ever happens.
I'm assuming that something needs to be added to MauiProgram.cs in order to get this to work.
Seeing as I have my own APN server, I really don't want to use Firebase or Azure Notification Hub at this time. A Firebase method is provided in the following link.
[https://cedricgabrang.medium.com/firebase-push-notifications-in-net-maui-ios-2f4388bf1ac][1]
Seeing as Local Notifications and Remote Notifications use the same methods, I modeled my code after this example.
https://github.com/xamarin/xamarin-forms-samples/tree/main/LocalNotifications
Here is my code with some decorations.
// Called if app is in the foreground.
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
SentrySdk.CaptureMessage("WillPresentNotification = " + "yes");
ProcessNotification(notification);
completionHandler(UNNotificationPresentationOptions.Alert);
}
// Called if app is in the background, or killed state.
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
SentrySdk.CaptureMessage("DidReceiveNotificationResponse = " + "yes");
if (response.IsDefaultAction)
{
ProcessNotification(response.Notification);
}
completionHandler();
}
NOTE: I'm compiling my iOS app using an Azure DevOps Pipeline. I've added both the Development cert and the Push Notification cert to the Keychain. I don't see the Push Notification cert included in the DotNetCoreCLI#2 Task. Push Notifications are enabled and configured in the Provision Profile. Perhaps there is a problem with the build process and how the Keychain installs/uses the all the certs.
Does anyone know how to make this work? Seems like this should be pretty easy to do.
I finally got this working using the Firebase.plugin for .Net Maui. My APN server works. The Firebase console works too.
I used these directions.
https://cedricgabrang.medium.com/firebase-push-notifications-in-net-maui-ios-2f4388bf1ac
If you are having issues getting Firebase.plugin to build on iOS, take a look at this issue. https://github.com/TobiasBuchholz/Plugin.Firebase/issues/51
Here is the code I used in my Azure Pipeline to combine the two Apple Certs. https://stackoverflow.com/a/74105887/5360237
We use the Microsoft.SharePoint.Client library to automate SharePoint work from our workflow engine but yesterday, one of our client informed us they wanted to disable the Legacy Authentication (LegacyAuthProtocolsEnabled to false).
Once I tried it on our end, I ended up getting an Unauthorised exception.
All in good wanting to disable the Legacy Authentication for obvious security reason, but the problem with the Modern Authentication is that it requires user interaction which is clearly not a solution since we are running tasks in the background.
I've been googling this for quite some time but I haven't found a solution as of yet on how to handle automatic authentication for background work.
Is there a way to "authenticate" to SharePoint without any user interaction while LegacyAuthProtocolsEnabled is set to false?
I found an article that suggested using the App Authentication but after reading more about it, I believe this is considered an old method to authenticate and is likely to be deprecated as well over time, but I thought I'd still give it a go just in case but it did not work. When I got to
https://tenant.sharepoint.com/_layouts/15/appregnew.aspx
Where tenant is our company domain name, and I click on the "Create" button after filling in all the relevant fields, I get the following error, which is completely useless:
Sorry, something went wrong
An unexpected error has occurred.
TECHNICAL DETAILS
According to this article HOW TO HARDEN YOUR SHAREPOINT ONLINE ENVIRONMENT BY DISABLING LEGACY AUTHENTICATION, Legacy Authentication was no longer be an option as of the 13/10/2020, yet here we are, and the option is still available in SharePoint 365 and while the article is interesting explain why Legacy Authentication should be switched off, etc... it does not get into any details as to how automated solutions should be handled.
Also found an old thread "LegacyAuthProtocolsEnabled" and Scripted Logons to SharePoint Online? where #DeanWang suggests leaving it turned on as:
All custom CSOM, PowerShell code will stop working
This may also prevent third-party apps from accessing SharePoint
Online resources.
I'm going to stop here as I could keep going and the question is already too long for my liking and bottom line is, does anyone know if there is a way, and what is the best way, to authenticate to SharePoint while running automated "scripts/code" from a background task without requiring any user interaction while the Legacy Authentication is switch off?
Thanks
Update-1
After reading articles after articles, I've yet to connect to SharePoint 365.
I also spend more time on the PnP Framework as recommended by numerous articles. I created a dummy app with the following sample code which is used again in various articles, including this one:
Secure Authentication of SharePoint with PnP Framework with C#(Code)
My code is identical as you can see:
var clientContext = new AuthenticationManager().GetACSAppOnlyContext(
"https://mycompany.sharepoint.com/sites",
"MyClientid",
"MySecretId");
using (clientContext)
{
//Get Lists
var web = clientContext.Web;
var lists = web.Lists;
clientContext.Load(lists);
clientContext.ExecuteQuery();
foreach (var list in lists)
{
}
}
And even though I've granted full control in Azure for the specific test app that's using the specific ClientId and SecretId
I'm still getting the following error (401 - unauthorized):
System.Exception
HResult=0x80131500
Message=Token request failed.
Source=PnP.Framework
StackTrace:
at SharePointPnP.IdentityModel.Extensions.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue(String securityTokenServiceUrl, OAuth2AccessTokenRequest oauth2Request) in /_/src/lib/PnP.Framework/Utilities/OAuth/OAuth2S2SClient.cs:line 18
at PnP.Framework.Utilities.TokenHelper.GetAppOnlyAccessToken(String targetPrincipalName, String targetHost, String targetRealm) in /_/src/lib/PnP.Framework/Utilities/TokenHelper.cs:line 116
at PnP.Framework.Utilities.ACSTokenGenerator.GetToken(Uri siteUrl) in /_/src/lib/PnP.Framework/Utilities/ACSTokenGenerator.cs:line 37
at PnP.Framework.AuthenticationManager.<GetContextAsync>b__59_0(String site) in /_/src/lib/PnP.Framework/AuthenticationManager.cs:line 971
at PnP.Framework.AuthenticationManager.<>c__DisplayClass75_0.<GetAccessTokenContext>b__0(Object sender, WebRequestEventArgs args) in /_/src/lib/PnP.Framework/AuthenticationManager.cs:line 1336
at Microsoft.SharePoint.Client.ClientRuntimeContext.OnExecutingWebRequest(WebRequestEventArgs args)
at Microsoft.SharePoint.Client.ClientContext.FireExecutingWebRequestEventInternal(WebRequestEventArgs args)
at Microsoft.SharePoint.Client.ClientContext.GetWebRequestExecutor()
at Microsoft.SharePoint.Client.ClientContext.GetFormDigestInfoPrivate()
at Microsoft.SharePoint.Client.ClientContext.EnsureFormDigest()
at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
at ConsoleApp5.Program.Main(String[] args) in C:\Users\myuser\source\repos\ConsoleApp5\ConsoleApp5\Program.cs:line 23
This exception was originally thrown at this call stack:
[External Code]
SharePointPnP.IdentityModel.Extensions.S2S.Protocols.OAuth2.OAuth2WebRequest.GetResponse() in OAuth2WebRequest.cs
SharePointPnP.IdentityModel.Extensions.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue(string, SharePointPnP.IdentityModel.Extensions.S2S.Protocols.OAuth2.OAuth2AccessTokenRequest) in OAuth2S2SClient.cs
Inner Exception 1:
WebException: The remote server returned an error: (401) Unauthorized.
Is there another section I should be looking at (and change) in the App Registration in Azure
Since it's the SharePoint Online that we are talking about, one easy way to connect to different SharePoint Sites is by using the Azure AD App-Only approach and since you are talking about a Deamon Service you can easily use Application Permissions when registering the App Registration.
You can, and you should, read more about it from the linked Microsoft Docs article.
You can also loggin via certificate or app registration secret as it is discribed in the Log in to Microsoft 365 in order to create automated CI CD SPFx pipelines, for example.
Hope the above helps, if not feel free to ask :)
Update: Please read below in order to have a better understanding.
Firstly, in your code segment you are using a wrong method from the PnP.Framework package.
AuthenticationManager().GetACSAppOnlyContext()
The above method refers to a completely different method of obtaining an authentication token, more specifically the Sharepoint App-Only model, which... well.... more or less is not being used nowadays quite so ofte. I think I read somewhere that MS is thinking of retiring this kind of Authentication and going onwards on the path of Azure Active Directory authentication, but, unfotunately, I cannot seem to find the link.
Furthermore, I have collected three projects and uploaded them to github for you to see. You can simply clone the repo and run the projects as-is from HERE.
As you will be able to see for yourself, there are three projects in the solution, which you can run each one individually from VSCode or Vs.
More in detail:
ConsoleApp1
(sorry for the name but forgot to switch it :) )
This is a Deamon Console Project that references the PnP.Framework namespace and tries to utilize all of the goodies that the good folks form the PnP Community have contributed.
The procedure is straight forward and is the same for all three projects ->
Read the AppConfiguration
Request the Access Token with appropriate scopes (Depending the service that i am referencing)
Declare the Token to be used by our Client Context.
In the PnP.Framework-related project the above cycle can be seen as below
AuthenticationConfiguration config = AuthenticationConfiguration.ReadFromJsonFile("appsettings.json");
var authManager = new PnP.Framework.AuthenticationManager(config.ClientId, config.Certificate.CertificateDiskPath, config.Certificate.CertificatePassword, config.Tenant);
using (var cc = authManager.GetAccessTokenContext("https://<REPLACE:name of tenant>.sharepoint.com/sites/testsite2", (string siteURL) => authManager.GetAccessToken(siteURL)))
ConsoleAppMSGraph
As the name suggests this Deamon Console App utilizes GraphServiceClient graphClient in order to get all the information that you request through the graph endpoint.
Subsequntly, you will notice that for this porject the scope name changes to
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
In addition, we request a collection of all the lists that currently reside in our SharePoint Root Site with the below segment:
var lists = await graphClient.Sites["root"].Lists
.Request()
.GetAsync();
ConsoleAppSPClient
This app is the default and most simple way of accessing data on Sharepoint.
The projects utilizes MSAL.Net and Microsoft.Sharepoint.Client namespaces in order to fetch an access token and, subsequently, embed that token in all our next requests.
In order to keep the answer a bit short, please refer to here in order to see how we initiate a Confidential App Client, request for a token and, later on, embedd it in our ClientContext object.
Notes
I have listed in the Readme.md of the repo, which permissions you should give to your app registration. You can view them Here.
I am using the Sites.FullControl.All but you can narrow down the list of sites that the app registration will have access by using the Sites.Selected.
All of the above projects, reference a common class library that serves as a strongly typed configuration object.
IMPORTANT you should always use a certificate to authenticate the client app as it is mentioned here. The previous link also describes the way you can create a certificate and upload it to the store of the app registration.
Amazing! Thank you very much #Jimas13. For the last 2 weeks I was struggling to find solution to my problem!! You saved me!! If you ever been in Greece let me buy you a drink!
I want to send emails from my .NET 4.6.1 application using one of our organisation's O365 email accounts. I'm wondering if there's a Nuget package which can help me.
Microsoft.Office365.OutlookServices looks a bit out-of-date, and the comments on the project page don't inspire confidence.
Microsoft.Graph seems more recent, but its code samples use the pre-release Microsoft Authentication Library (MSAL), which it says isn't suitable for production. Maybe I can use Active Directory Authentication Library .NET (ADAL) instead in conjunction with Graph?
The graph library is the official SDK. It is linked from the official Samles and SDKs page.
Even though the MSAL is described as pre-release on the NuGet page, the Github project page describes the Nuget as being from the stable branch.
Your mileage with it may vary, however in my projects I haven't had any issues with the 1.0.304142221-alpha NuGet.
Someone from Microsoft could probably shed some light on it, perhaps come with an indication of a release date of a non-preview NuGet?
For just sending mails, you can use System.Net.Mail like this:
var mailMessage = new MailMessage();
mailMessage.To.Add(new MailAddress(RECEIVER_MAIL_ADDRESS));
mailMessage.From = new MailAddress(SENDER_MAIL_ADDRESS, SENDER_NAME);
mailMessage.Subject = SUBJECT;
mailMessage.Body = BODY;
mailMessage.IsBodyHtml = true;
using (var smtp = new SmtpClient("smtp.office365.com", 587))
{
var credential = new NetworkCredential
{
UserName = USERNAME,
Password = PASSWORD,
Domain = DOMAIN_OPTIONAL
};
smtp.Credentials = credential;
smtp.EnableSsl = true;
smtp.TargetName = "";
await smtp.SendMailAsync(mailMessage);
}
I am trying to use SuiteTalk to retrieve customer records.
I downloaded the v2016.1 WSDL from here: http://www.netsuite.com/portal/developers/resources/suitetalk-documentation.shtml
I used mv package to build the WSDL and generated the jar file.
I create a project in Eclipse and added the jar file. I am using Java.
Here's a snippet of my code. I am stuck here and don't know how to proceed. It looks like I am missing another jar file? like the NetSuiteService?
RecordRef role = new RecordRef();
role.setInternalId("3");
role.setType(RecordType.contact);
Passport passport = new Passport();
passport.setEmail("me#test.com");
passport.setPassword("mypassword");
passport.setRole(role);
passport.setAccount("123456");
Please help me. What do I need to do?
I'm not familiar with the Java bindings, but it looks like you are missing the data center URL configuration.
I'd recommend using the ruby bindings. They are community supported and there's some decent example code demonstrating various common functions.
I work with .net, I think you need to initialize the service to indicate the datacenter that corresponds to you, it is more or less like this:
// Instantiate the NetSuite web services
Service = new Aggregates.DataCenterAwareNetSuiteService(_account);
Service.Timeout = 1000 * 60 * 60;
var appInfo = new ApplicationInfo();
//App info from application netsuite
appInfo.applicationId = cuenta.ApplicationInfo;
// Prepare login credentials for request level login
Service.passport = new Passport()
{
email = _email,
password = _password,
account = _account
};
Service.applicationInfo = appInfo;