ASP.NET MVC Facebook - asp.net-mvc

I am trying to do a seemingly simple thing, but having trouble accomplishing it. I am trying to automate the posting on my Facebook wall. Basically I have a ASP.NET MVC website that I post updates on, and I want to automatically submit the post to my wall.
I see a lot of stuff on FB Connect and getting data, I just want to post.
Thanks for any help or guidance.
UPDATE: Just trying to resurrect and be a little more clear in my description as I am not getting anywhere.
I have a page that I want with a text box and a button. When I submit the form I want the message to post to my Facebook wall. I thought it was Facebook Connect, but I am getting no where as to how to automatically authenticate myself and post to my wall.
I would like to use C# rather than JavaScript.
private const string ApplicationKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
private const string SecretKey = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
private Facebook.Rest.Api _facebookAPI;
private Facebook.Session.ConnectSession _connectSession;
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection form)
{
_connectSession = new Facebook.Session.ConnectSession(ApplicationKey, SecretKey);
if (_connectSession.IsConnected())
{
_facebookAPI = new Facebook.Rest.Api(_connectSession);
string response = _facebookAPI.Stream.Publish("This is a generated test");
}
return View();
}
}
The IsConnected() is returning false.
Any help is appreciated.

This code was right, the problem was that I had not added my application to my profile. Dumb miss, but my thought is that the whole thing is poorly documented. I have another issue with offline access, but that is for a different post.
string apiKey = "XXXXXXXXX";
string apiSecret = "XXXXXXXXXXXX";
Facebook.Session.ConnectSession._connectSession = new Facebook.Session.ConnectSession(apiKey, apiSecret);
if (_connectSession.IsConnected)
{
Facebook.Rest.Api api = new Facebook.Rest.Api(_connectSession);
string response = api.Stream.Publish("Test", null, null, null, api.Users.Session.UserId);
}

It could be that you tested your Website on your localhost. The Facebook Cookie is not written out, when you test your Website on localhost. See this link http://forum.developers.facebook.net/viewtopic.php?pid=247332
This might solve your problem:
Add "127.0.0.1 localhost.local" to your file
Update your FB application Connect settings to use "http://localhost.local/" URL and "localhost.local" domain.
Create an IIS Web site on port 80 with the name "localhost.local". I had to stop my default web site, which is also on port 80
Update my Visual Studio 2010 web application to use IIS with the "http://localhost.local/" url.
To see cookies, make sure to install FireCookies, along with FireBug.

Related

Sustainsys SAML2 Sample for ASP.NET Core WebAPI without Identity

Does anyone have a working sample for Sustainsys Saml2 library for ASP.NET Core WebAPI only project (no Mvc) and what's more important without ASP Identity? The sample provided on github strongly relies on MVC and SignInManager which I do not need nor want to use.
I added Saml2 authentication and at first it worked fine with my IdP (I also checked the StubIdP provided by Sustainsys) for first few steps so:
IdP metadata get properly loaded
My API properly redirects to sign-in page
Sign-in page redirects to /Saml2/Acs page, and I see in the logs that it parses the result successfully
However I don't know how to move forward from there and extract user login and additional claims (my IdP provided also an e-mail, and it is included in SAML response which I confirmed in the logs).
Following some samples found on the web and modyfing a little bit the MVC Sample from GitHub I did the following:
In Startup.cs:
...
.AddSaml2(Saml2Defaults.Scheme,
options =>
{
options.SPOptions.EntityId = new EntityId("...");
options.SPOptions.ServiceCertificates.Add(...));
options.SPOptions.Logger = new SerilogSaml2Adapter();
options.SPOptions.ReturnUrl = new Uri(Culture.Invariant($"https://localhost:44364/Account/Callback?returnUrl=%2F"));
var idp =
new IdentityProvider(new EntityId("..."), options.SPOptions)
{
LoadMetadata = true,
AllowUnsolicitedAuthnResponse = true, // At first /Saml2/Acs page throwed an exception that response was unsolicited so I set it to true
MetadataLocation = "...",
SingleSignOnServiceUrl = new Uri("...") // I need to set it explicitly because my IdP returns different url in the metadata
};
options.IdentityProviders.Add(idp);
});
In AccountContoller.cs (I tried to follow a somewhat similar situation described at how to implement google login in .net core without an entityframework provider):
[Route("[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
private readonly ILog _log;
public AccountController(ILog log)
{
_log = log;
}
[HttpGet("Login")]
[AllowAnonymous]
public IActionResult Login(string returnUrl)
{
return new ChallengeResult(
Saml2Defaults.Scheme,
new AuthenticationProperties
{
// It looks like this parameter is ignored, so I set ReturnUrl in Startup.cs
RedirectUri = Url.Action(nameof(LoginCallback), new { returnUrl })
});
}
[HttpGet("Callback")]
[AllowAnonymous]
public async Task<IActionResult> LoginCallback(string returnUrl)
{
var authenticateResult = await HttpContext.AuthenticateAsync(Constants.Auth.Schema.External);
_log.Information("Authenticate result: {#authenticateResult}", authenticateResult);
// I get false here and no information on claims etc.
if (!authenticateResult.Succeeded)
{
return Unauthorized();
}
// HttpContext.User does not contain any data either
// code below is not executed
var claimsIdentity = new ClaimsIdentity(Constants.Auth.Schema.Application);
claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier));
_log.Information("Logged in user with following claims: {#Claims}", authenticateResult.Principal.Claims);
await HttpContext.SignInAsync(Constants.Auth.Schema.Application, new ClaimsPrincipal(claimsIdentity));
return LocalRedirect(returnUrl);
}
TLDR: Configuration for SAML in my ASP.NET Core WebApi project looks fine, and I get success response with proper claims which I checked in the logs. I do not know how to extract this data (either return url is wrong or my callback method should work differently). Also, it is puzzling why successfuly redirect from SSO Sign-In page is treated as "unsolicited", maybe this is the problem?
Thanks for any assistance
For anyone who still needs assistance on this issue, I pushed a full working example to github which uses a .Net Core WebAPI for backend and an Angular client using the WebAPI. you can find the example from here:
https://github.com/hmacat/Saml2WebAPIAndAngularSpaExample
As it turned out, the various errors I've been getting were due to my solution being hosted inside docker container. This caused a little malfunction in internal aspnet keychain. More details can be found here (docker is mentioned almost at the end of the article):
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?tabs=aspnetcore2x&view=aspnetcore-2.2
Long story short, for the code to be working I had to add only these lines:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo("/some/volume/outside/docker")); // it needs to be outside container, even better if it's in redis or other common resource
It fixed everything, which includes:
Sign-in action to external cookie
Unsolicited SSO calls
Exceptions with data protection key chain
So it was very difficult to find, since exceptions thrown by the code didn't point out what's going on (and the unsolicited SSO calls made me think that the SSO provider was wrongly configured). It was only when I disassembled the Saml2 package and tried various code pieces one by one I finally encoutered proper exception (about the key chain) which in turned led me to an article about aspnet data protection.
I provide this answer so that maybe it will help someone, and I added docker tag for proper audience.

Using OpenAM OAuth2 with MVC4 and OAuthWebSecurity

Before trying MVC5, I had a go at using OpenAM with MVC4, with slightly better results. I need to authenticate from an asp.net application using OpenAM, and don't fancy the Fedlet route - I can see anybody else who has ever tried that
So, this was my starting point. This shows how to use Google and Facebook, and it works a treat. This goes on to show how to use other providers. I'm using OpenAM with OAuth2, so created "OpenAMClient", inheriting from DotNetOpenAuth.AspNet.Clients.OAuth2Client, and registered this in AuthConfig.RegisterAuth:
OAuthWebSecurity.RegisterClient(new OpenAMClient("consumerKey", "consumerSecret"));
This is great, because it now appears automatically on the login page, and pretty much worked perfectly until I started to use it for authentication. In the GetServiceLoginUrl override, I constructed a path to my OpenAM server, appending the returnURL that had been generated by the application and passed in as a parameter:
protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
var response =
string.Format(
"http://localopenam.hibu.com:9080/openam_10.1.0/oauth2/authorize?client_id={0}&response_type=code&scope=email&redirect_uri={1}",
_consumerKey, returnUrl);
return new Uri(response);
}
This got me to my OpenAM server login page, but after authenticating, I got an error saying that the redirection URI wasn't acceptable. Debugging the code, I can see that the ReturnURL starts off in the ExternalLoginResult as "/Account/ExternalLoginCallback", but by the time it reaches GetServiceLoginUrl, it has become:
http://localhost:60448/Account/ExternalLoginCallback?__provider__=OpenAM&__sid__=12e299cbac474b60a935f946f69d04a8
OpenAM isn't having any of that, as the "sid" parameter is dynamic, and it doesn't seem to acccept wildcards - it won't allow the returnURL provided by OAuthWebSecurity.
As a workaround, I intercept the ReturnURL, and switch to a new AccountController method:
protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
var workingUrl = "http://localhost:60448/Account/OpenAMCallback";
var response =
string.Format(
"http://localopenam.hibu.com:9080/openam_10.1.0/oauth2/authorize?client_id={0}&response_type=code&scope=email&redirect_uri={1}",
_consumerKey, workingUrl);
return new Uri(response);
}
I add http://localhost:60448/Account/OpenAMCallback as a redirectURL in OpenAM, then added AccountController OpenAMCallback:
public ActionResult OpenAMCallback(string code)
{
Console.WriteLine(code );
//use the code to get the token, then user details etc
return RedirectToLocal(null);
}
This is great, because from here I get the access code, so I can make more requests for the token, get all the allowed user details, all of that kind of thing, but ... I'm jealous of the original ExternalLoginCallback method I've subverted away from, that all the other cool authentication servers use. I want to use OAuthWebSecurity.VerifyAuthentication and OAuthWebSecurity.GetOAuthClientData, but VerifyAuthentication is coming back as null, so that stops that party
I can use http://dotnetopenauth.net/ and do it by hand, but I'd rather use a framework so there's less to maintain. Am I missing something obvious, or is OAuthWebSecurity not really up to this so I should stick with dotnetopenauth?
thanks

Login with Twitter account in Asp.net MVC

I am trying to let users login with their twitter acount for my web site. I am using Tweetsharp library.
Now the problem is: after i enter twitter user name and password, the twitter page shows me a number like "7825362101" and says to enter this number into the concern web site.
I have no clue what shall my website do with that number!! I already have 'consumer key' and 'consumer secret' while i created the app in twitter.
I hope someone can help me!!
cheers
You don't need to do anything with that number if you are using the Tweetsharp in a web application. Just do the following in your controller, this will return a list of tweets from the public timeline:
private readonly string _consumerKey = "yourconsumerkey";
private readonly string _consumerSecret = "yourconsumersecretkey";
public ActionResult Index()
{
var service = new TwitterService(_consumerKey, _consumerSecret);
IEnumerable<TwitterStatus> model = service.ListTweetsOnPublicTimeline();
return View(model);
}
Spring.NET Twitter provides a sample for ASP.NET MVC.
http://www.springframework.net/social-twitter/
I think something is missing on redirect to Twitter authentication.Twitter API not getting all required values. So just follow the below link to authenticate your web application using Tweetsharp library
http://tutorialslink.com/Articles/Login-with-Twitter-account-in-Aspnet-MVC/24

Facebook OAuth + AppHarbor workaround on random port

I a have a sample app, hosted on AppHarbor and now want to integrate authorization through facebook. So i downloaded nugget Facebook.Web.Mvc package to implement it.
After reading tutorial, in controller i have method:
public ActionResult Login(string returnUrl)
{
var oauthClient = new FacebookOAuthClient(FacebookApplication.Current) { RedirectUri = GetFacebookRedirectUri() };
if (!string.IsNullOrWhiteSpace(returnUrl))
{
returnUrl = Url.Action("Index", "Facebook");
}
dynamic parameters = new ExpandoObject();
parameters.scope = ExtendedPermissions;
var state = new { csrf_token = CalculateMD5Hash(Guid.NewGuid().ToString()), return_url = returnUrl };
parameters.state = Base64UrlEncode(Encoding.UTF8.GetBytes(JsonSerializer.Current.SerializeObject(state)));
SetFacebookCsrfToken(state.csrf_token);
string s = oauthClient.GetLoginUrl(parameters).AbsoluteUri;
ViewBag.FacebookLoginUrl = s;
//new LogEvent(s).Raise();
return View(new AccountModel());
}
View:
<a href="#ViewBag.FacebookLoginUrl" id="lUrl">
<div class="fblogin"></div>
In localhost this works for me.
But when i upload it to appharbor, i see, that generated link indicates to address + port 16013 (as support told always random port). So clicking it shows me facebook login window, than blank page.
I manually configured my app settings in facebook to this port but it did not helped.
Also i tried to access my site through this port - nothing.
Then i changed port number through jquery to 80, its also did not help.
you have had such problems?
I'm not familiar with the Facebook api, but I've had a similar problem.
I suspect that the returnUrl value being passed in is incorrect. It probably contains a port number that AppHarbor uses internally for load balancing.
See this article on how to create a public url for AppHarbor:
http://support.appharbor.com/kb/getting-started/workaround-for-generating-absolute-urls-without-port-number
Then make sure that the value in your returnUrl is publicly available.
You can now set the aspnet:UseHostHeaderForRequestUrl appSetting to true which effectively solves this problem. This can be done by adding a Configuration Variable to your application with the corresponding key and value.
Source on AppHarbor

DotNetOpenAuth Twitter Consume StartSignIn

Trying to use the StartSignInWithTwitter method. When the method is called soon after an exception is thrown. This is using the latest version of DotNetOpenAuth. Would it have anything to do with me developing and running with locally? (VS2010) Is this how I should be doing authentication in the first place? I do see some different ways in the Samples pack that is included with the source.
{"The remote server returned an error: (401) Unauthorized."}
My code looks like below:
public void TwitAuthInit()
{
TwitterConsumer.StartSignInWithTwitter(false).Send();
}
public ActionResult TwitAuth()
{
if (TwitterConsumer.IsTwitterConsumerConfigured)
{
string screenName;
int userId;
if (TwitterConsumer.TryFinishSignInWithTwitter(out screenName, out userId))
{
FormsAuthentication.SetAuthCookie(screenName, false);
return RedirectToAction("Home", "Index");
}
}
return View();
}
To answer your question about "Is this how I should be doing authentication in the first place?":
You probably shouldn't be calling SetAuthCookie(screenName, false) with your screenName, since screen names (I believe) can be recycled. You should instead log the user in using a unique ID, either one you create in your own user database or Twitter's, and then use the screen name only as an alias that is displayed to the user (and perhaps other users if this user were to post something for public viewing). Otherwise, when Twitter recycles a username, that user will inherit all the data from the old user on your site -- not good.
Wanted to confirm that the 401 error is indeed solved by setting a non-empty callback URL on the twitter app config page.
From the Application Type block of the settings page:
To restrict your application from using callbacks, leave this field
blank.
You have to go into TwitterConsumer.cs and change the following URLs:
Request token URL https://api.twitter.com/oauth/request_token
Authorize URL https://api.twitter.com/oauth/authorize
Access token URL https://api.twitter.com/oauth/access_token
As Twitter changed their URLs. I didn't get the memo and spent way too much time debugging this.

Resources