Problems with Mailkit IMAP - Authentication with string is not possible - imap

I have a strange problem with my IMAP authentication here.
I cannot authenticate if I´m trying to use string variables. I really need to type in my account and my password which does really make no sense to me.
THIS DOES NOT WORK!
using (var client = new ImapClient(new ProtocolLogger("imap.log")))
{
using (var cancel = new CancellationTokenSource())
{
//LogIn
client.Connect("imap.gmail.com", 993, MailKit.Security.SecureSocketOptions.SslOnConnect);
var credentials = new NetworkCredential(username, password);
client.Authenticate(credentials, cancel.Token);
var personal = client.GetFolder(client.PersonalNamespaces[0]);
f1.tbl_folderTableAdapter1.Insert(ID, PARENTID, username);
client.Disconnect(true);
}
}
BUT THIS WORK
using (var client = new ImapClient(new ProtocolLogger("imap.log")))
{
using (var cancel = new CancellationTokenSource())
{
//LogIn
client.Connect("imap.gmail.com", 993, MailKit.Security.SecureSocketOptions.SslOnConnect);
client.Authenticate("funnyemailhere", "anothernicepasswordhere");
var personal = client.GetFolder(client.PersonalNamespaces[0]);
f1.tbl_folderTableAdapter1.Insert(ID, PARENTID, username);
client.Disconnect(true);
}
}
Can you see any problems here ?
Thank you in advance

Related

Xamarin set Cookies in Multiplatform iOS app using (Hybrid)WebView

I followed example from here (https://learn.microsoft.com/en-gb/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview#invoke-c-from-javascript) to setup WebView for my project and I can invoke C# code from WebView page event, that is working fine.
However, before sending a request I have to setup a Cookie and that cookie should be passed to remote server. I followed several examples from net I am getting it to work for Android but iOS its not working.
Code I got from another Stackoverflow question as follows.
Android Working
var cookieManager = CookieManager.Instance;
cookieManager.SetAcceptCookie(true);
cookieManager.RemoveAllCookie();
var cookies = UserInfo.CookieContainer.GetCookies(new System.Uri(AppInfo.URL_BASE));
for (var i = 0; i < cookies.Count; i++)
{
string cookieValue = cookies[i].Value;
string cookieDomain = cookies[i].Domain;
string cookieName = cookies[i].Name;
cookieManager.SetCookie(cookieDomain, cookieName + "=" + cookieValue);
}
iOS Not Working
// Set cookies here
var cookieUrl = new Uri(AppInfo.URL_BASE);
var cookieJar = NSHttpCookieStorage.SharedStorage;
cookieJar.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;
foreach (var aCookie in cookieJar.Cookies)
{
cookieJar.DeleteCookie(aCookie);
}
var jCookies = UserInfo.CookieContainer.GetCookies(cookieUrl);
IList<NSHttpCookie> eCookies =
(from object jCookie in jCookies
where jCookie != null
select (Cookie) jCookie
into netCookie select new NSHttpCookie(netCookie)).ToList();
cookieJar.SetCookies(eCookies.ToArray(), cookieUrl, cookieUrl);
I have tried code from WebView documentation here, Cookie section (https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/webview?tabs=macos#cookies)
I'll really appreciate if anybody can point out what I am doing wrong any hints.
Thanks.
Update
In my HybridWebViewRenderer method I am adding my custom Cookie as follows.
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
userController.RemoveAllUserScripts();
userController.RemoveScriptMessageHandler("invokeAction");
HybridWebView hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
string cookieDomain = new System.Uri(((HybridWebView)Element).Uri).Host;
foreach (var c in NSHttpCookieStorage.SharedStorage.Cookies)
{
Console.WriteLine("Cookie (Delete)" + c.Name);
NSHttpCookieStorage.SharedStorage.DeleteCookie(c);
}
var cookieDict = new NSMutableDictionary();
cookieDict.Add(NSHttpCookie.KeyDomain, new NSString("." + cookieDomain));
cookieDict.Add(NSHttpCookie.KeyName, new NSString("ABC"));
cookieDict.Add(NSHttpCookie.KeyValue, new NSString("123e4567-e89b-12d3-a456-426652340003"));
cookieDict.Add(NSHttpCookie.KeyPath, new NSString("/"));
cookieDict.Add(NSHttpCookie.KeyExpires, DateTime.Now.AddDays(1).ToNSDate());
var myCookie = new NSHttpCookie(cookieDict);
NSHttpCookieStorage.SharedStorage.SetCookie(myCookie);
string filename = $"{hybridView.Uri}";
var request = new NSMutableUrlRequest(new NSUrl(filename));
var wkNavigation = LoadRequest(request);
}
}
In AppDelegate I have added.
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
NSHttpCookieStorage.SharedStorage.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;
return base.FinishedLaunching(app, options);
}
Still no luck :( .........
You need to set the cookie in the shared storage.
Set your shared storage policy to always accept your own cookies.
In your ApplicationDelegate:
NSHttpCookieStorage.SharedStorage.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;

EWS OAuth .net core 2.1

We have a solution today where we use EWS's basic authentication (username and password) with .net Core 2.1, and it works. The problem is that basic authentication will expire in 2020. Therefore, we will transition to the OAuth solution that will work after 2020.
We have tried multiple solutions for this problem, including this: https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth, but some of the methods have been updated (AcquireToken -> AcquireTokenAsync).
It's important that the authentication against azure is not client-based, since everything will happen in backend (web api).
Does anyone have a solution to this problem?
This is our current solution:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new WebCredentials(<email>, <password>);
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
This is an example of what we have tried:
public class Program
{
public static void Run()
{
//tried this as well: string authority = "https://login.windows.net/<devAccountName>.onmicrosoft.com";
string authority = "https://login.microsoftonline.com/<tenantId>/OAuth2/Token";
string clientId = "<clientId>"; // Application ID from Azure
Uri clientAppUri = new Uri("http://localhost:55424/");
Uri resourceHostUri = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
AuthenticationResult authenticationResult = null;
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
string errorMessage = null;
try
{
Console.WriteLine("Trying to acquire token");
PlatformParameters platformParams = new PlatformParameters(PromptBehavior.Auto);
authenticationResult = authenticationContext.AcquireTokenAsync("https://outlook.office365.com/EWS/Exchange.asmx", clientId, clientAppUri, platformParams).Result;
}
catch (AdalException ex)
{
errorMessage = ex.Message;
if (ex.InnerException != null)
{
errorMessage += "\nInnerException : " + ex.InnerException.Message;
}
}
catch (ArgumentException ex)
{
errorMessage = ex.Message;
}
if (!string.IsNullOrEmpty(errorMessage))
{
Console.WriteLine("Failed: {0}" + errorMessage);
return;
}
Console.WriteLine("\nMaking the protocol call\n");
ExchangeService exchangeService = new ExchangeService(ExchangeVersion.Exchange2013);
exchangeService.Url = resourceHostUri;
exchangeService.TraceEnabled = true;
exchangeService.TraceFlags = TraceFlags.All;
exchangeService.Credentials = new OAuthCredentials(authenticationResult.AccessToken);
exchangeService.FindFolders(WellKnownFolderName.Root, new FolderView(10));
}
}
We receive this error message after we log in:
AADSTS50001: The application named
https://outlook.office365.com/EWS/Exchange.asmx was not found in the tenant named <tenantId>. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.

Linq2Twitter Bad Authentication Data Error 215

I'm getting a LinqToTwitter.TwitterQueryException "Bad Authentication Data" with innerException "The remote server returned an error: (400) Bad Request."
I'm using the latest version of LinqToTwitter (v2.1.06) and Twitter API v1.1.
The following code is used for authentication:
private XAuthAuthorizer GetAuthorizer()
{
var auth = new XAuthAuthorizer
{
Credentials = new XAuthCredentials
{
ConsumerKey = CONSUMER_KEY,
ConsumerSecret = CONSUMER_SECRET,
}
};
auth.Credentials.AccessToken = ACCESS_TOKEN;
auth.Credentials.OAuthToken = OAUTH_TOKEN;
auth.Authorize();
return auth;
}
And the error happens on the line of the foreach loop below:
XAuthAuthorizer _auth = GetAuthorizer();
_twitter = new TwitterContext(_auth);
var friendTweets = from tweet in _twitter.Status where tweet.Type == StatusType.Show && tweet.ID == tweetID select tweet;
foreach (var tweet in friendTweets)
{
AddTweetToCache(tweetID, tweet);
return tweet;
}
Any help would be greatly appreciated!
This fixed it. I was using the authentication method.
var auth = new ApplicationOnlyAuthorizer
{
Credentials = new InMemoryCredentials
{
ConsumerKey = CONSUMER_KEY,
ConsumerSecret = CONSUMER_SECRET
}
};

Example SNS subscription confirmation using AWS .NET SDK

I am trying to figure out how to use the AWS .NET SDK to confirm a subscription to a SNS Topic.
The subscription is via HTTP
The endpoint will be in a .net mvc website.
I can't find any .net examples anywhere?
A working example would be fantastic.
I'm trying something like this
Dim snsclient As New Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient(ConfigurationSettings.AppSettings("AWSAccessKey"), ConfigurationSettings.AppSettings("AWSSecretKey"))
Dim TopicArn As String = "arn:aws:sns:us-east-1:991924819628:post-delivery"
If Request.Headers("x-amz-sns-message-type") = "SubscriptionConfirmation" Then
Request.InputStream.Seek(0, 0)
Dim reader As New System.IO.StreamReader(Request.InputStream)
Dim inputString As String = reader.ReadToEnd()
Dim jsSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
Dim message As Dictionary(Of String, String) = jsSerializer.Deserialize(Of Dictionary(Of String, String))(inputString)
snsclient.ConfirmSubscription(New Amazon.SimpleNotificationService.Model.ConfirmSubscriptionRequest With {.AuthenticateOnUnsubscribe = False, .Token = message("Token"), .TopicArn = TopicArn})
End If
Here is a working example using MVC WebApi 2 and the latest AWS .NET SDK.
var jsonData = Request.Content.ReadAsStringAsync().Result;
var snsMessage = Amazon.SimpleNotificationService.Util.Message.ParseMessage(jsonData);
//verify the signaure using AWS method
if(!snsMessage.IsMessageSignatureValid())
throw new Exception("Invalid signature");
if(snsMessage.Type == Amazon.SimpleNotificationService.Util.Message.MESSAGE_TYPE_SUBSCRIPTION_CONFIRMATION)
{
var subscribeUrl = snsMessage.SubscribeURL;
var webClient = new WebClient();
webClient.DownloadString(subscribeUrl);
return "Successfully subscribed to: " + subscribeUrl;
}
Building on #Craig's answer above (which helped me greatly), the below is an ASP.NET MVC WebAPI controller for consuming and auto-subscribing to SNS topics. #WebHooksFTW
using RestSharp;
using System;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Web.Http;
using System.Web.Http.Description;
namespace sb.web.Controllers.api {
[System.Web.Mvc.HandleError]
[AllowAnonymous]
[ApiExplorerSettings(IgnoreApi = true)]
public class SnsController : ApiController {
private static string className = MethodBase.GetCurrentMethod().DeclaringType.Name;
[HttpPost]
public HttpResponseMessage Post(string id = "") {
try {
var jsonData = Request.Content.ReadAsStringAsync().Result;
var sm = Amazon.SimpleNotificationService.Util.Message.ParseMessage(jsonData);
//LogIt.D(jsonData);
//LogIt.D(sm);
if (!string.IsNullOrEmpty(sm.SubscribeURL)) {
var uri = new Uri(sm.SubscribeURL);
var baseUrl = uri.GetLeftPart(System.UriPartial.Authority);
var resource = sm.SubscribeURL.Replace(baseUrl, "");
var response = new RestClient {
BaseUrl = new Uri(baseUrl),
}.Execute(new RestRequest {
Resource = resource,
Method = Method.GET,
RequestFormat = RestSharp.DataFormat.Xml
});
if (response.StatusCode != System.Net.HttpStatusCode.OK) {
//LogIt.W(response.StatusCode);
} else {
//LogIt.I(response.Content);
}
}
//read for topic: sm.TopicArn
//read for data: dynamic json = JObject.Parse(sm.MessageText);
//extract value: var s3OrigUrlSnippet = json.input.key.Value as string;
//do stuff
return Request.CreateResponse(HttpStatusCode.OK, new { });
} catch (Exception ex) {
//LogIt.E(ex);
return Request.CreateResponse(HttpStatusCode.InternalServerError, new { status = "unexpected error" });
}
}
}
}
I don't know how recently this has changed, but I've found that AWS SNS now provides a very simply method for subscribing that doesn't involve extracting urls or building requests using RESTSharp.....Here's the simplified WebApi POST method:
[HttpPost]
public HttpResponseMessage Post(string id = "")
{
try
{
var jsonData = Request.Content.ReadAsStringAsync().Result;
var sm = Amazon.SimpleNotificationService.Util.Message.ParseMessage(jsonData);
if (sm.IsSubscriptionType)
{
sm.SubscribeToTopic(); // CONFIRM THE SUBSCRIPTION
}
if (sm.IsNotificationType) // PROCESS NOTIFICATIONS
{
//read for topic: sm.TopicArn
//read for data: dynamic json = JObject.Parse(sm.MessageText);
//extract value: var s3OrigUrlSnippet = json.input.key.Value as string;
}
//do stuff
return Request.CreateResponse(HttpStatusCode.OK, new { });
}
catch (Exception ex)
{
//LogIt.E(ex);
return Request.CreateResponse(HttpStatusCode.InternalServerError, new { status = "unexpected error" });
}
}
The following example helped me work with SNS. It goes through all the steps to work with Topics. The subscribe request in this case is an email address, however that can be changed to HTTP.
Pavel's SNS Example
Documentation
I ended up getting it working using the code shown. I was having trouble capturing the exception on the development server which turned out was telling me the server's time didn't match the timestamp in the SNS message.
Once the server's time was fixed up (an Amazon server BTW), the confirmation worked.

Can't delete Cookies that I get after Facebook Connect

I implemented Facebook-Connect successfully and I'm able to retrieve User-Information using the Facebook Toolkit. But I cant sucessfully logout.
When I press the facebook-Logout button (which automatically appears when I'm logged in, because I'm using the autologoutlink-property)
<fb:login-button autologoutlink="true"></fb:login-button>
I still have all five Facebook-Cookies:
MyApiKey
MyApiKey_ss
MyApiKey_SessionKey
MyApiKey_expires
MyApiKey_user
After I'm logged out, I'm really logged out in Facebook, because I need to login again at facebook.com but isConnected() always returns true and I can still retrieve the user Information:
var connectSession = new ConnectSession(ConfigurationManager.AppSettings["ApiKey"], ConfigurationManager.AppSettings["Secret"]);
if (connectSession.IsConnected())
{
var api = new Api(connectSession);
filterContext.Controller.ViewData["FBUser"] = api.Users.GetInfo();
}
First I don't understand why I can still retrieve User Information even though I'm not logged in any more, and secondly: How I can delete this Cookies. The Following Code didn't work:
public static void ClearFacebookCookies()
{
String[] shortNames = new String[] { "_user", "_session_key", "_expires", "_ss", "" };
HttpContext currentContext = HttpContext.Current;
if (currentContext == null)
{
return;
}
string appKey = ConfigurationManager.AppSettings["APIKey"];
if (appKey == null)
{
throw new Exception("APIKey is not defined in web.config");
}
foreach (var name in shortNames)
{
string fullName = appKey + name;
HttpCookie cookie = currentContext.Response.Cookies[fullName];
if (cookie != null)
{
cookie.Value = null;
cookie.Expires= DateTime.Now.AddDays(-1d);
}
HttpCookie cookieRequest = currentContext.Request.Cookies[fullName];
if (cookieRequest != null)
{
cookieRequest.Value = null;
cookieRequest.Expires = DateTime.Now.AddDays(-1d);
}
}
}// end Method
This may be a shot in the dark, but did you make sure the fb.init is placed just before the closing body tag?
<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US"></script>
<script type="text/javascript">FB.init('somekey');</script>
That's caused me problems before.

Resources