I am using Facebook client to access my MVC4 application through DotNetOpenAuth.AspNet. But after successfull login i am not able to fetch any data Such as ProviderName, UserName and UserId from VerifyAuthentication. i am able to get the data for Linkedin, Google, Yahoo and Microsoft but not for facebook. Below is my code for the same.
OAuth2ConfigurationSection section = _proxy.GetOAuthConfigurationFacebook();
FacebookClient client = new FacebookClient(section.AppID, section.AppSecret);
Uri uri = new Uri(section.ReturnUrl);
var auth =client.VerifyAuthentication(filterContext.HttpContext,uri);
GetOAuthConfigurationFacebook Method fetches AppId and SecretId from config file.
I am getting null in
var auth =client.VerifyAuthentication(filterContext.HttpContext,uri);
i am not sure what i am missing?
Related
SUMMARY UPDATE:
I got a sample working today thanks to the many good replies. Thanks all. My primary goal was to get current user information (ME) without using secret key. First I just used the secret key from the App Reg and this will authenticate the App and not the user. This does of course not work when calling ME. My next finding was if you want the users token, you still need the App Reg token, and then you request the users token. This requires less permissions on the App Reg, but requires to request two tokens. I ended up skipping ME and just requesting information for a specified user (through the APp Reg permissions):
$"https://graph.microsoft.com/v1.0/users/{email}/$select=companyName"
Both both approaches should be viable. I updated code below with working sample.
I am trying to do a very simple call to graph API to get companyName from current user. Found some samples but they seemed to be very complicated. The MVC app is authenticated trough an Application Registration in AAD.
I guess the application registration needs to be authorized to access Graph API. Or is more needed here? Getting company name should be fairly simple:
https://graph.microsoft.com/v1.0/me?$select=companyName
Does anyone have a snippet for calling the graph API, my best bet would be you need to extract a bearer token from the controller? ALl help is appreciated.
Working snippet:
public async Task<ActionResult> Index()
{
string clientId = "xxx";
string clientSecret = "xxx";
var email = User.Identity.Name;
AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/xxx.onmicrosoft.com/oauth2/token");
ClientCredential creds = new ClientCredential(clientId, clientSecret);
AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com/", creds);
HttpClient http = new HttpClient();
string url = $"https://graph.microsoft.com/v1.0/users/{email}/$select=companyName";
//url = "https://graph.windows.net/xxx.onmicrosoft.com/users?api-version=1.6";
// Append the access token for the Graph API to the Authorization header of the request by using the Bearer scheme.
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
HttpResponseMessage response = await http.SendAsync(request);
var json = response.Content.ReadAsStringAsync();
return View();
}
To add one last item, here is a link to an MVC sample on Git that uses an MVC application to send email. It illustrates how to call the MS Graph API to get various pieces of information. Keep in mind, if you are using an application only scenario, ME will not work, the sample illustrates how to obtain a delegated token for a user and use that toke to do work:
https://github.com/microsoftgraph/aspnet-connect-rest-sample
If I am reading this code snippet correctly, You are requesting a application only token for the Graph.Microsoft.Com resource, then attempting to use that toke with this URI:
url = "https://graph.windows.net/thomaseg.onmicrosoft.com/users?api-version=1.6"
This will not work because you are mixing resources, AAD Graph and MS Graph. The ME endpoint does not make since in this scenario because you are using the application only flow. This flow does not support the ME endpoint. ME is designed for use with a delegated token. the ME endpoint represents the signed in user, since and application is not a user, ME is meaningless.
You will need to target the user specifically:
https://graph.microsoft.com/v1.0/Users/[UPN or ID of user]?$select=companyName
Should work if your application has been granted the appropriate permission scopes.
My windows service is collect instagram datas from instagram api. I was using client_id but this uses format is removed.
Instagram api is want to access_token but Oauth 2.0 is web-based. or not?
I using .NET and my application type is windows service and web request don't work because this call url: "https://www.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code" is have one more contain redirect. so web response haven't contain my web application link also auto redirect is open..
what should I do?
Thanks..
Steps to get instagram access token
register ur application in instagram account.
get a client id and client secret.
Step 1: HIT the below url.
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
step 2: after hitting above url you will be taken to login page. enter the login credentials and take the code from address bar.
it will be live for only 20 seconds i guess.
step 3: The code which you got put it in CODE parameter in the below source code, then run the below code in console application n hit breakpoint at response. you will get access token and userid.
public void GetDataInstagramToken()
{
try
{
NameValueCollection parameters = new NameValueCollection();
parameters.Add("client_id", "CLIENT-ID");
parameters.Add("client_secret", "CLIENT-Secret");
parameters.Add("grant_type", "authorization_code");
parameters.Add("redirect_uri", "REDIRECT-URI");
parameters.Add("code", "CODE");
WebClient client = new WebClient();
var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "POST", parameters);
var response = System.Text.Encoding.Default.GetString(result);
// deserializing nested JSON string to object
var jsResult = (JObject)JsonConvert.DeserializeObject(response);
string accessToken = (string)jsResult["access_token"];
}
catch (Exception)
{
//exception catch
}
}
The following scenario: I have an MVC 5 web app using Identity 2.0 and Web API 2.
Once the user authenticates in MVC 5 he should be able to call a WEB API endpoint let's call it: api/getmydetails using a bearer token.
What I need to know is how can I issue the token for that specific user in MVC 5?
I did solve this.
Here are some screenshots and I will also post the demo solution.
Just a simple mvc 5 with web api support application.
The main thing you have to register and after login. For this demo purpose I registered as admin#domain.com with password Password123*.
If you are not logged in you will not get the token. But once you loggin you will see the token:
After you get the token start Fiddler.
Make a get request to the api/service endpoint. You will get 401 Unauthorized
Here is the description of the request:
Now go to the web app, stage 1 and copy the generated token and add the following Authorization header: Authorization: Bearer token_here please notice the Bearer keyword should be before the token as in the image bellow. Make a new request now:
Now you will get a 200 Ok response. The response is actually the user id and user name that show's you are authorized as that specific user:
You can download the working solution from here:
http://www.filedropper.com/bearertoken
If for some reason the link doesn't work just let me know and I will send it to you.
P.S.
Of course in your app, you can use the generated bearer token to make ajax call to the web api endpoint and get the data, I didn't do that but should be quite easy ...
P.S. 2: To generate the token:
private string GetToken(ApplicationUser userIdentity)
{
if (userIdentity == null)
{
return "no token";
}
if (userIdentity != null)
{
ClaimsIdentity identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userIdentity.UserName));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userIdentity.Id));
AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
DateTime currentUtc = DateTime.UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
string AccessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
return AccessToken;
}
return "no token";
}
I used to be able to query the Google Analytics API with my account's login & password.
Google is now using OAuth for authentication which is great...
The only issue is that I only need ONE access token.
I don't wanna allow other users to fetch THEIR analytics data.
I just wanna be able to fetch MY data.
Is there a way I can generate an access token only for my app or my analytics account?
I know such solutions exists... For instance, Twitter provides what they call a "single-user oauth" for apps that don't require a specific user to sign in.
One again, all I'm trying to accomplish here is to fetch MY OWN analytics data via the API.
Is there a way to properly do that?
I'm adding a PHP answer - you may be able to adjust or convert it to garb / ruby code.
You should be able to use Analytics with service accounts now. You will indeed have to use a private key instead of an access token.
Create an app in the API Console
Basically, you go to the Google API Console and create an App.
Enable Google Analytics in the services tab.
In the API Access tab, create a new OAuth ID (Create another client ID... button), select service account and download your private key (Generate new key... link). You'll have to upload the key to your web server later.
On the API Access page, in the Service account section, copy the email address (#developer.gserviceaccount.com) and add a new user with this email address to your Google Analytics profile. If you do not do this, you'll get some nice errors
Code
Download the latest Google PHP Client off SVN (from the command line svn checkout http://google-api-php-client.googlecode.com/svn/trunk/ google-api-php-client-read-only).
You can now access the Analytics API in code:
require_once 'Google_Client.php';
require_once 'contrib/Google_AnalyticsService.php';
$keyfile = 'dsdfdss0sdfsdsdfsdf44923dfs9023-privatekey.p12';
// Initialise the Google Client object
$client = new Google_Client();
$client->setApplicationName('Your product name');
$client->setAssertionCredentials(
new Google_AssertionCredentials(
'11122233344#developer.gserviceaccount.com',
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents($keyfile)
)
);
// Get this from the Google Console, API Access page
$client->setClientId('11122233344.apps.googleusercontent.com');
$client->setAccessType('offline_access');
$analytics = new Google_AnalyticsService($client);
// We have finished setting up the connection,
// now get some data and output the number of visits this week.
// Your analytics profile id. (Admin -> Profile Settings -> Profile ID)
$analytics_id = 'ga:1234';
$lastWeek = date('Y-m-d', strtotime('-1 week'));
$today = date('Y-m-d');
try {
$results = $analytics->data_ga->get($analytics_id,
$lastWeek,
$today,'ga:visits');
echo '<b>Number of visits this week:</b> ';
echo $results['totalsForAllResults']['ga:visits'];
} catch(Exception $e) {
echo 'There was an error : - ' . $e->getMessage();
}
Terry Seidler answered this nicely for php. I want to add a java code example.
Api console setup
Start by doing the required steps in the google api console as Terry explained:
Basically, you go to the Google API Console and create an App. Enable
Google Analytics in the services tab. In the API Access tab, create a
new OAuth ID (Create another client ID... button), select service
account and download your private key (Generate new key... link).
You'll have to upload the key to your web server later.
On the API Access page, in the Service account section, copy the email
address (#developer.gserviceaccount.com) and add a new user with this
email address to your Google Analytics profile. If you do not do this,
you'll get some nice errors
Get the necessary libraries
Download the google analytics java client from:
https://developers.google.com/api-client-library/java/apis/analytics/v3
Or add the following maven dependencies:
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-analytics</artifactId>
<version>v3-rev94-1.18.0-rc</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson</artifactId>
<version>1.18.0-rc</version>
</dependency>
Now for the code:
public class HellowAnalyticsV3Api {
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
public void analyticsExample() {
// This is the .p12 file you got from the google api console by clicking generate new key
File analyticsKeyFile = new File(<p12FilePath>);
// This is the service account email address that you can find in the api console
String apiEmail = <something#developer.gserviceaccount.com>;
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(apiEmail)
.setServiceAccountScopes(Arrays.asList(AnalyticsScopes.ANALYTICS_READONLY))
.setServiceAccountPrivateKeyFromP12File(analyticsPrivateKeyFile).build();
Analytics analyticsService = new Analytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(<your application name>)
.build();
String startDate = "2014-01-03";
String endDate = "2014-03-03";
String mertrics = "ga:sessions,ga:timeOnPage";
// Use the analytics object build a query
Get get = analyticsService.data().ga().get(tableId, startDate, endDate, mertrics);
get.setDimensions("ga:city");
get.setFilters("ga:country==Canada");
get.setSort("-ga:sessions");
// Run the query
GaData data = get.execute();
// Do something with the data
if (data.getRows() != null) {
for (List<String> row : data.getRows()) {
System.out.println(row);
}
}
}
You can use a refresh token. Store the refresh token in a db or secure config file, then use it to show the stats.
Google API Offline Access Using OAuth 2.0 Refresh Token will give you an idea of how to capture then store your refresh token.
See also Using OAuth 2.0 for Web Server Applications - Offline Access
Hello I found a solution, it works for me
you have to change this one
immediate: true
to
immediate: false
and it looks like
function checkAuth() {
gapi.auth.authorize({
client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
}
Google has the 'Service Account' (Calls Google APIs on behalf of your application instead of an end-user), but the way it works is a bit different as it won't use access tokens but a private key instead.
You can find more details at https://developers.google.com/accounts/docs/OAuth2ServiceAccount
I'm working with client who provided me with somewhat vague
instructions. Here's what I'm doing (using CommonsHttpOAuthConsumer as
consumer and DefaultOAuthProvider as provider)
I'm able to get response token from doing this:
String requestToken = provider.retrieveRequestToken
(OAuth.OUT_OF_BAND);
this is in form of URL with params so I'm parsing the actual token
out for example:
https://foobar.com/oauth/login_authorize?oauth_token=XRFCGPbES3M2bYZy...
Now - the instructions that I get say:
Given the request token obtained in step 1, login with the user’s
credentials (name and password) as POST parameters and sign the
request with the request token/secret
POST https://foobar.com/oauth/login_authorize
That's where I'm having difficulties. Obviously I have to input that
requestToken somewhere so I do this (post is HttpPost that contains user credentials):
consumer.setTokenWithSecret(requestToken, SECRET);
consumer.sign(post);
It doesn't work. It actually generates 200 status but what I get is a
generic error message.
retrieveRequestToken does not return a request token, it returns an authenticationUrl that you need to send your users to so they can sign in. Request token is saved in provider object.
String authenticationUrl = provider.retrieveRequestToken( call_back_url )
Note: According to the oauth standard the users sign in on the providers site with their credentials. After they have done that you (as a consumer) can get the Access Token and after that you can access their data on the providers site.
// After user has signed in
provider.retrieveAccessToken(null)
// access token is saved in provider and provider knows which consumer uses it
// so now you can sign with your consumer and connect with the request
URL url = new URL( protected_resources_url )
HttpURLConnection request = (HttpURLConnection) url.openConnection();
consumer.sign(request)
request.connect()
If you have the user credentials you can do the authorization in your script
// Using grails and functional-tests
get(authenticationUrl)
// Image the site shows a simple form with username/password and a login button
setRedirectEnabled false
form {
username = "mario"
password = "peach"
click "login"
}
And then do retrieveRequestToken and the code mentioned above
Hope this helps you
// Jonas