asp.net mvc4 linkedin integration - Access to posting shares denied - c#

I am developing social networks integration for my asp.net mvc4 application.
Twitter and Facebook were very easy for me but I am seriously stuck with LinkedIn.
Here is my code.
public ActionResult LinkedInTest(string text)
{
var client = new RestClient
{
Authority = "https://api.linkedin.com/uas/oauth",
Credentials = LinkedInSocialHelper.GetCredentials()
};
var request = new RestRequest {Path = "requestToken"};
RestResponse response = client.Request(request);
token = response.Content.Split('&')[0].Split('=')[1];
tokenSecret = response.Content.Split('&')[1].Split('=')[1];
textToPost = text;
Response.Redirect("https://api.linkedin.com/uas/oauth/authorize?oauth_token=" + token + "&scope=r_basicprofile+r_emailaddress+r_network+r_contactinfo+rw_nus");
return null;
textToPost = text;
return RedirectToAction("LinkedInCallback");
}
public ActionResult LinkedInCallback()
{
verifier = Request["oauth_verifier"];
var client = new RestClient
{
Authority = "https://api.linkedin.com/uas/oauth",
Credentials = LinkedInSocialHelper.GetCredentials(token, tokenSecret, verifier),
Method = WebMethod.Post
};
var request = new RestRequest {Path = "accessToken"};
RestResponse response = client.Request(request);
token = response.Content.Split('&')[0].Split('=')[1];
tokenSecret = response.Content.Split('&')[1].Split('=')[1];
LinkedInSocialHelper.Post(textToPost, token, tokenSecret);
return RedirectToAction("Calendar");
}
public static void Post(string text, string accessToken, string accessTokenSecret)
{
var tokenManager = new TokenManager(ApiKey, ApiSecret);
tokenManager.ExpireRequestTokenAndStoreNewAccessToken(null, null, accessToken, accessTokenSecret);
var authorization = new WebOAuthAuthorization(tokenManager, UserToken);
LinkedInService service = new LinkedInService(authorization);
//var user = service.GetCurrentUser(ProfileType.Public); - IT IS GIVING ME THE SAME ERROR - Access denied
service.CreateShare(text, VisibilityCode.ConnectionsOnly);
}
Everything works fine except last thing - posting shares - I get Access to posting shares denied exception despite the fact that I generate token using all the necessary permissions:
"https://api.linkedin.com/uas/oauth/authorize?oauth_token=" + token + "&scope=r_basicprofile+r_emailaddress+r_network+r_contactinfo+rw_nus"
Hope you good guys help me.

See the last post here - it describes how to solve it
https://developer.linkedin.com/forum/permission-scope-request-token-query-not-working?page=1

Related

Get Gmail Inbox feed Google.Apis C# .NET

I need to read the gmail inbox feed using Oauth2.0. Simulating in the postman,
Auth URL : https://accounts.google.com/o/oauth2/auth
Access Token URL : https://accounts.google.com/o/oauth2/token
Client ID : XXXXX.apps.googleusercontent.com
Client Secret : XXXXX
Scope : https://mail.google.com/mail/feed/atom
GrantType: Authorization Code
I requested the token and used it on the header
Authorization - Bearer XXXXXXXXXX.
And I made the request via GET right in my scope and got my email feeds. Works!!!
The postman generates a code in C #, but the token expires.
var client = new RestClient("https://mail.google.com/mail/feed/atom/");
var request = new RestRequest(Method.GET);
request.AddHeader("postman-token", "d48cac24-bd3e-07b5-c616-XXXXXXXX");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Bearer ya29.a0AfH6SMDZlUmw0xLHAoYIJuIfTkXXXXXXXXQSPP17GmXT26fJEfWB9w8UiwQ2YF32-nOp6zY9H_lwJEEXXXXXXXXXXXYK4e0tcZkieGbBl5Eow2M-7Gxp20kfDtXXXXXVjiXymLXyMkYEI");
IRestResponse response = client.Execute(request);
I'm trying to do it via Google.Api, using GoogleAuthorizationCodeFlow and already using token refresh.
With the code below, I got authorization from the application, but I can't read the xml atom feed
GoogleAuthorizationCodeFlow flow;
var assembly = Assembly.GetExecutingAssembly();
var clientfile = #"client_secrets.json";
using (var stream = new FileStream(clientfile, FileMode.Open, FileAccess.Read))
{
flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
DataStore = new FileDataStore("StoreTest"),
ClientSecretsStream = stream,
Scopes = new[] { "https://mail.google.com/mail/feed/atom/" }
});
}
var uri = Request.Url.ToString();
var code = Request["code"];
if (code != null)
{
var token = flow.ExchangeCodeForTokenAsync(UserId, code,
uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;
// Extract the right state.
var oauthState = AuthWebUtility.ExtracRedirectFromState(
flow.DataStore, UserId, Request["state"]).Result;
Response.Redirect(oauthState);
}
else
{
var result = new AuthorizationCodeWebApp(flow, uri, uri).AuthorizeAsync(UserId,
CancellationToken.None).Result;
if (result.RedirectUri != null)
{
// Redirect the user to the authorization server.
Response.Redirect(result.RedirectUri);
}
else
{
// The data store contains the user credential, so the user has been already authenticated.
var gmailfeed = new GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "GetFeed",
});
var inboxlistRequest = gmailfeed.Users.Messages.List("me");
inboxlistRequest.LabelIds = "Label_19780355190759038";
inboxlistRequest.IncludeSpamTrash = false;
var emailListResponse = inboxlistRequest.Execute();
foreach (var mail in emailListResponse.Messages)
{
var mailId = mail.Id;
var threadId = mail.ThreadId;
Message message = gmailfeed.Users.Messages.Get("me", mailId).Execute();
Console.WriteLine((message.Snippet));
}
}
}
I got to read the email, but I need the xml atom feed.
Could someone help me how I make this call to get the atom feed, using the granted token. If there is an easier way to do it too, it would be cool to share.
Thank you
Resolved using respsharp, restclient!!
tks

How can I get ID Token from custom token via FirebaseAdmin SDK?

How can I get ID Token from custom token?
[Fact]
public void Get_ID_Token_For_Service_Account_Test()
{
using (Stream stream = new FileStream(ServiceAccountJsonKeyFilePath, FileMode.Open, FileAccess.Read))
{
ServiceAccountCredential credential = ServiceAccountCredential.FromServiceAccountData(stream);
FirebaseApp.Create(new AppOptions
{
Credential = GoogleCredential.FromServiceAccountCredential(credential),
ServiceAccountId = ServiceAccountId,
});
var uid = "Some UID";
var additionalClaims = new Dictionary<string, object>
{
{"dmitry", "pavlov"}
};
string customToken = FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid, additionalClaims).Result;
string idToken= null; // How to get this?
FirebaseToken token = FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken, CancellationToken.None).Result;
Assert.NotNull(token);
Assert.True(token.Claims.ContainsKey("dmitry"));
}
}
I see samples for some other languages/platforms but not for C# - how to get ID token via current user here - Retrieve ID tokens on clients. But for C# neither UserRecord nor FirebaseAuth provides ID Token. Any pointers are much appreciated.
I have found the way to get the ID token in FirebaseAdmin integration tests - see method SignInWithCustomTokenAsync. The only thing I have to adjust was base URL: according to Firebase Auth REST API documentation it should be
https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken
The API KEY refers to the Web API Key, which can be obtained on the project settings page in your admin console.
So the adjusted code looks like this:
private static async Task<string> SignInWithCustomTokenAsync(string customToken)
{
string apiKey = "..."; // see above where to get it.
var rb = new Google.Apis.Requests.RequestBuilder
{
Method = Google.Apis.Http.HttpConsts.Post,
BaseUri = new Uri($"https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken")
};
rb.AddParameter(RequestParameterType.Query, "key", apiKey);
var request = rb.CreateRequest();
var jsonSerializer = Google.Apis.Json.NewtonsoftJsonSerializer.Instance;
var payload = jsonSerializer.Serialize(new SignInRequest
{
CustomToken = customToken,
ReturnSecureToken = true,
});
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var parsed = jsonSerializer.Deserialize<SignInResponse>(json);
return parsed.IdToken;
}
}

Microsoft Graph ASP.NET MVC 5 Send Mail throwing unknown error

Been working on an ASP.NET MVC 5 application that interacts with the MS Graph API.
The controller gets a graph client for the current user and then using that client sends an email.
public class EmailController : Controller
{
// GET: Email
public async Task<ActionResult> Index()
{
var client = await MSGraphServiceClient.GetGraphServiceClientAsync();
await InvitationHelper.SendEmail(client);
return Content("");
}
}
public static async Task<GraphServiceClient> GetGraphServiceClientAsync()
{
string appId = ConfigurationManager.AppSettings["ida:ClientId"];
string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
// Get Signed in user
string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
// Get app and user id claims from Azure
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
// Specify Graph resource URL
string graphResourceID = "https://graph.microsoft.com";
// get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
ClientCredential clientcred = new ClientCredential(appId, appKey);
// initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID, new ADALTokenCache(signedInUserID));
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenSilentAsync(graphResourceID, clientcred, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
// use delegate to create auth provider using async auth result
var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);
return Task.FromResult(0);
});
// return the graph service client
return new GraphServiceClient(delegateAuthProvider);
}
public static async Task<bool> SendEmail(GraphServiceClient graphServiceClient)
{
var message = new Message()
{
Subject = "Test",
Body = new ItemBody()
{
ContentType = BodyType.Text,
Content = "This is a test"
},
ToRecipients = new List<Recipient>() { new Recipient() { EmailAddress = new EmailAddress() { Address = "jonathan.sweetland#gmail.com" } } }
};
var request = graphServiceClient.Me.SendMail(message, true).Request();
await request.PostAsync();
return true;
}
It is not a permissions error because on AAD I have granted all the permissions for this app. I have other graph calls working so I know it authenticates correctly using the same code.
Used fiddler as was suggested and the JSON response was the same as the error messages displayed.
After a lot of playing around, I found that if you try and use the SendMail on the Graph API whilst authenticated by a Azure Active Directory tenant that is not set up with an outlook account. Even if the account has an outlook account on a different tenant, then you will not be able to use the SendMail endpoint.

Authenticate user without login for web api using microsoft graph

I want to use microsoft graph in web api which is using .net core 2.0, I want to authenticate user without login prompt.
Following is the code I have used, Please correct me if my method is wrong.
string clientId = "";
string clientsecret = "";
string tenant = "";
string resourceURL = "https://graph.microsoft.com";
string userMail = "testuser3#company.com";
public async Task<string> GetMyEmailUser()
{
try
{
var result = "";
string AzureADAuthority = "https://login.microsoftonline.com/companyname.com";
AuthenticationContext authenticationContext = new AuthenticationContext(AzureADAuthority, false);
var credential = new ClientCredential(clientId, clientsecret);
var authenticationResult = authenticationContext.AcquireTokenAsync(resourceURL, credential).Result;
var token = authenticationResult.AccessToken;
using (var confClient = new HttpClient())
{
var url = "https://graph.microsoft.com/v1.0";
confClient.BaseAddress = new Uri(url);
confClient.DefaultRequestHeaders.Accept.Clear();
confClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = confClient.GetAsync(url + "/me/mailFolders/inbox/messages?$filter=isRead eq false&$top=100").Result;
var jsonString = JObject.Parse(await response.Content.ReadAsStringAsync());
IUserMessagesCollectionPage myDetails = JsonConvert.DeserializeObject<IUserMessagesCollectionPage>(jsonString["value"].ToString());
}
I am new to microsoft graph and would really appreciate your help. Thanks.

Facebook SDK .NET - (#200) The user hasn't authorized the application to perform this action

I am trying to post a message to a Facebook page from a C# web application. I am getting the following exception thrown on calling FacebookClient.Post(...):
FacebookOAuthException (OAuthException - #200) (#200) The user hasn't
authorized the application to perform this action
Code:
var facebookClient = new FacebookClient();
facebookClient.AppId = appId;
facebookClient.AppSecret = appSecret;
if (Request["code"] == null)
{
var authUrl = facebookClient.GetLoginUrl(new
{
client_id = appId,
client_secret = appSecret,
scope = "publish_stream",
redirect_uri = Request.Url.AbsoluteUri
});
Response.Redirect(authUrl.AbsoluteUri);
}
else
{
dynamic result = facebookClient.Get("oauth/access_token", new
{
client_id = appId,
client_secret = appSecret,
grant_type = "client_credentials",
redirect_uri = Request.Url.AbsoluteUri,
code = Request["code"]
});
facebookClient.AccessToken = result.access_token;
// Store access token
}
Sending a message:
protected void PublishMessage(string message)
{
FacebookClient client = new FacebookClient(AccessToken);
client.AppId = ApplicationId;
client.AppSecret = ApplicationSecret;
dynamic parameters = new ExpandoObject();
parameters.message = message;
client.Post(PageName + "/feed", parameters);
}
I accept the following Facebook prompts to ensure that the app has access:
And in my Facebook profile settings, the app looks like this:
I am using the Facebook SDK for .NET v6.4.2 (the latest).
This may seem a silly question, but aren't you missing the Request code from your access token request? Shouldn't it be like this?
dynamic result = facebookClient.Get("oauth/access_token", new
{
client_id = appId,
client_secret = appSecret,
grant_type = "authorization_code"
redirect_uri = Request.Url.AbsoluteUri,
code = Request["code"]
});
Edit Just realized, you have to use a different grant_type when using the request code :)

Categories