I am using azure Access Control Service (ACS). I am trying to get the list of Identity providers which i was selected for my application. For this i am using the following code From Here:
public ActionResult IdentityProviders(string serviceNamespace, string appId)
{
string idpsJsonEndpoint = string.Format(IdentityProviderJsonEndpoint, serviceNamespace, appId);
var client = new WebClient();
var data = client.DownloadData(idpsJsonEndpoint);
return Content(Encoding.UTF8.GetString(data), "application/json");
}
Can anybody please tell me what is appId and where do i get it?
As per the link you provided you need to get that from here.
https://portal.appfabriclabs.com
Also check for the below line in the link
{ serviceNamespace = "YourServiceNamespace", appId = "https://localhost/<YourWebApp>/" }))',
The appId will be the one you will get after registration
Related
I am developing a web API to handle realtime updates (Lead information) from Facebook to integrate with my CRM.
In the WEB API POST request, I am able to capture the leadID but the problem comes when I get leadinfo by invoking FB.Get(LeadID). To make a Graph API GET request(for lead information) I need to have a user access token and this is where i have been struggling for quite sometime. I have looked up several posts online but havent got any solution for my problem.
In my sample implementation, GetLoginUrl(parameters) returns a uri and when when I request the uri in a browser, I see that the access token gets generated in the redirected Uri. But how to do this programatically ? I have tried the following
string FBAccessUrl = "https://graph.facebook.com/oauth/authorize?client_id=XXXXXXXXXXXX&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html";
var accessTokenRequest = System.Net.HttpWebRequest.Create(FBAccessUrl);
HttpWebResponse response = (HttpWebResponse)accessTokenRequest.GetResponse();
but then i get this ResponseUri = {https://www.facebook.com/unsupportedbrowser} which is not what I want.
Can someone help me with how the user access token can be generated using C# in the Web API (without the facebook login dialog)
[HttpPost]
[ActionName("Complex")]
public void PostComplex(RootObject root)
{
FacebookClient fb = new FacebookClient();
// Get leadID from the inital HTTP POST request
long leadgen_id = root.entry[0].changes[0].value.leadgen_id;
string leadID = leadgen_id.ToString();
// to get user access token
dynamic parameters = new ExpandoObject();
parameters.client_id = "XXXXXXXXXXXXXXX";
parameters.redirect_uri = "https://www.facebook.com/connect/login_success.html";
parameters.response_type = "token";
// generate the login url
Uri uri = fb.GetLoginUrl(parameters);
// reuest the uri in browser and uri2 is the redirected uri
Uri uri2 = "****************"
string accesstoken = "";
FacebookOAuthResult oauthResult;
if (fb.TryParseOAuthCallbackUrl(uri, out oauthResult))
{
if (oauthResult.IsSuccess)
{
accesstoken = oauthResult.AccessToken;
}
else
{
var errorDescription = oauthResult.ErrorDescription;
var errorReason = oauthResult.ErrorReason;
}
}
fb.AccessToken = accesstoken;
string me = fb.Get(leadID).ToString();
// Then fetch required lead information
}
I am in the process of rewritting our app using Xamarin.Forms with a C# backend and I'm trying to use customauth on login. I've got it working to a point but am struggling to pass back to the Xamarin app everything I want from the backend. I'm getting the token and user id but want a bit more.
The backend code on succesfull login seems relatively straightforward:
return Ok(GetLoginResult(body));
where GetLoginResult() is:
private object GetLoginResult(IUser body)
{
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, body.username)
};
JwtSecurityToken token = AppServiceLoginHandler.CreateToken(
claims, signingKey, audience, issuer, TimeSpan.FromDays(30));
accounts account = db.accounts.Single(u => u.username.Equals(body.username));
return new LoginResult(account)
{
authenticationToken = token.RawData,
};
}
and the LoginResult class is
public class LoginResult
{
public LoginResult(accounts account)
{
Response = 200;
CustomerId = account.CustomerId;
Modules = account.Modules;
User = new LoginResultUser
{
userId = account.id,
UserName = account.UserName,
EmployeeId = account.EmployeeId
};
}
[JsonProperty(PropertyName = "Response")]
public int Response { get; set; }
etc
In the app, I'm calling the customauth as follows:
MobileServiceUser azureUser = await _client.LoginAsync("custom", JObject.FromObject(account));
The result has the token and the correct userid but how can I fill the result with the additional properties passed back by the backend? I've got the backend working and tested using postman and the results I get there are what I want but I've been unable to find out how to get it deserialized in the app.
As I known, for custom auth , MobileServiceClient.LoginAsync would invoke https://{your-app-name}.azurewebsites.net/.auth/login/custom. When using ILSPy you could find that this method would only retrieve the user.userId and authenticationToken from the response to construct the CurrentUser of your MobileServiceClient. Per my understanding, you could leverage MobileServiceClient.InvokeApiAsync to retrieve the additional user info after the user has logged in successfully. Additionally, you could try to follow this toturial for other possible approaches.
UPDATE
You could use InvokeApiAsync instead of LoginAsync to invoke the custom login endpoint directly, then retrieve the response and get the additional parameters as follows:
When logged successfully, I added a new property userName and response the client as follows:
For the client, I added a custom extension method for logging and retrieve the additional parameters as follows:
Here are the code snippet, you could refer to them:
MobileServiceLoginExtend.cs
public static class MobileServiceLoginExtend
{
public static async Task CustomLoginAsync(this MobileServiceClient client, LoginAccount account)
{
var jsonResponse = await client.InvokeApiAsync("/.auth/login/custom", JObject.FromObject(account), HttpMethod.Post, null);
//after successfully logined, construct the MobileServiceUser object with MobileServiceAuthenticationToken
client.CurrentUser = new MobileServiceUser(jsonResponse["user"]["userId"].ToString());
client.CurrentUser.MobileServiceAuthenticationToken = jsonResponse.Value<string>("authenticationToken");
//retrieve custom response parameters
string customUserName = jsonResponse["user"]["userName"].ToString();
}
}
Login processing
MobileServiceClient client = new MobileServiceClient("https://bruce-chen-002-staging.azurewebsites.net/");
var loginAccount = new LoginAccount()
{
username = "brucechen",
password = "123456"
};
await client.CustomLoginAsync(loginAccount);
We have set the Azure AD as a identity provider in our application. We want to display profile picture that should come from Azure AD, in the application.
In order to test, I have added one Windows Live Id account (which has a profile picture) in the Azure AD. We then tried it using Graph Explorer, but no luck.
How do we get the profile picture from Azure AD?
You can use Azure Active Directory Graph Client to get user thumbnail photo
var servicePoint = new Uri("https://graph.windows.net");
var serviceRoot = new Uri(servicePoint, "<your tenant>"); //e.g. xxx.onmicrosoft.com
const string clientId = "<clientId>";
const string secretKey = "<secretKey>";// ClientID and SecretKey are defined when you register application with Azure AD
var authContext = new AuthenticationContext("https://login.windows.net/<tenant>/oauth2/token");
var credential = new ClientCredential(clientId, secretKey);
ActiveDirectoryClient directoryClient = new ActiveDirectoryClient(serviceRoot, async () =>
{
var result = await authContext.AcquireTokenAsync("https://graph.windows.net/", credential);
return result.AccessToken;
});
var user = await directoryClient.Users.Where(x => x.UserPrincipalName == "<username>").ExecuteSingleAsync();
DataServiceStreamResponse photo = await user.ThumbnailPhoto.DownloadAsync();
using (MemoryStream s = new MemoryStream())
{
photo.Stream.CopyTo(s);
var encodedImage = Convert.ToBase64String(s.ToArray());
}
Azure AD returns user's photo in binary format, you need to convert to Base64 string
Getting photos through Graph Explorer is not supported. Assuming that "signedInUser" already contains the signed in user entity, then this code snippet using the client library should work for you...
#region get signed in user's photo
if (signedInUser.ObjectId != null)
{
IUser sUser = (IUser)signedInUser;
IStreamFetcher photo = (IStreamFetcher)sUser.ThumbnailPhoto;
try
{
DataServiceStreamResponse response =
photo.DownloadAsync().Result;
Console.WriteLine("\nUser {0} GOT thumbnailphoto", signedInUser.DisplayName);
}
catch (Exception e)
{
Console.WriteLine("\nError getting the user's photo - may not exist {0} {1}", e.Message,
e.InnerException != null ? e.InnerException.Message : "");
}
}
#endregion
Alternatively you can do this through REST and it should look like this:
GET https://graph.windows.net/myorganization/users//thumbnailPhoto?api-version=1.5
Hope this helps,
According to the Azure AD Graph API Docs, Microsoft recommends transitioning to Microsoft Graph, as the Azure AD Graph API is being phased out.
However, to easily grab the photo via Azure AD, for now, use this URL template:
https://graph.windows.net/myorganization/users/{user_id}/thumbnailPhoto?api-version={version}
For example (this is a fake user id):
https://graph.windows.net/myorganization/users/abc1d234-01ab-1a23-12ab-abc0d123e456/thumbnailPhoto?api-version=1.6
The code below assumes you already have an authenticated user, with a token. This is a simplistic example; you'll want to change the return value to suit your needs, add error checking, etc.
const string ThumbUrl = "https://graph.windows.net/myorganization/users/{0}/thumbnailPhoto?api-version=1.6";
// Attempts to retrieve the thumbnail image for the specified user, with fallback.
// Returns: Fully formatted string for supplying as the src attribute value of an img tag.
private string GetUserThumbnail(string userId)
{
string thumbnail = "some base64 encoded fallback image";
string mediaType = "image/jpg"; // whatever your fallback image type is
string requestUrl = string.Format(ThumbUrl, userId);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", GetToken());
HttpResponseMessage response = client.GetAsync(requestUrl).Result;
if (response.IsSuccessStatusCode)
{
// Read the response as a byte array
var responseBody = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
// The headers will contain information on the image type returned
mediaType = response.Content.Headers.ContentType.MediaType;
// Encode the image string
thumbnail = Convert.ToBase64String(responseBody);
}
return $"data:{mediaType};base64,{thumbnail}";
}
// Factored out for use with other calls which may need the token
private string GetToken()
{
return HttpContext.Current.Session["Token"] == null ? string.Empty : HttpContext.Current.Session["Token"].ToString();
}
I'm writing a web app that pulls events data from Facebook, and I can get a lot of the information using an app token, but not the picture, which requires a client token, as documented here: https://developers.facebook.com/docs/graph-api/reference/v2.2/event/picture
I want the code that grabs the event data to run automatically on a server at regular intervals, without requiring a user to log in to their Facebook account.
Is there a way I can get a client token without user intervention? If not, is there another way I can get the event picture?
This is the code I am using to get the event data, using C# and JSON.Net (This gets a list of events created by the specified user - ResortStudios):
var fb = new FacebookClient();
dynamic result = fb.Get( "oauth/access_token", new
{
client_id = "XXXXXXXXXXX",
client_secret = "XXXXXXXXXXXXXXXXXXXXXXXXX",
grant_type = "client_credentials"
} );
var apptoken = result.access_token;
fb = new FacebookClient(apptoken);
result = fb.Get("ResortStudios/events");
JObject events = JObject.Parse(result.ToString());
JArray aEvents = (JArray)events["data"];
string s = aEvents.ToString();
List<fbEvent> lEvents = JsonConvert.DeserializeObject<List<fbEvent>>(s);
I've not tried this but something occurred to me that might work for you. Have you considered something like storing it a non-persistent data store like session state? Then, using the Facebook SDK for .NET, you create an ActionResult for UserInfo, like below. (I know this isn't directly applicable but I hoped it might get you thinking.)
//http://facebooksdk.net/docs/web/ajax-requests/
public ActionResult UserInfo()
{
var accessToken = Session["AccessToken"].ToString();
var client = new FacebookClient(accessToken);
dynamic result = client.Get("me", new { fields = "name,id" });
return Json(new
{
id = result.id,
name = result.name,
});
}
I am using Google Contacts Api. I am not sure whether I can send an Auth Token as a parameter.
string _token = _google.Token;
RequestSettings requestSettings = new RequestSettings("AppName",_token);
ContactsRequest contactsRequest = new ContactsRequest(requestSettings);
// Get the feed
Feed<Contact> feed = contactsRequest.GetContacts();
I get 401 Unauthorised as a response for this code, but if I send the username and password as parameters, I am able to get a response.
Whoops, sorry, I didn't quite get it right the first time. I'm using this code in a real app, I just do things a bit different in my code because I'm constantly refreshing tokens.
In any case, here's the proper logic:
// get this information from Google's API Console after registering your app
var parameters = new OAuth2Parameters
{
ClientId = #"",
ClientSecret = #"",
RedirectUri = #"",
Scope = #"https://www.google.com/m8/feeds/",
};
// generate the authorization url
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
// now use the url to authorize the app in the browser and get the access code
(...)
// get this information from Google's API Console after registering your app
parameters.AccessCode = #"<from previous step>";
// get an access token
OAuthUtil.GetAccessToken(parameters);
// setup connection to contacts service
var contacts = new ContactsRequest(new RequestSettings("<appname>", parameters));
// get each contact
foreach (var contact in contacts.GetContacts().Entries)
{
System.Diagnostics.Debug.WriteLine(contact.ContactEntry.Name.FullName);
}
FYI, after you call GetAccessToken() against your access code, your parameters data structure will include the AccessToken and RefreshToken fields. If you STORE these two values, you can set them in the parameters structure in subsequent calls (allowing you to skip asking for authorization in the future) and instead of calling GetAccessToken() simply call RefreshAccessToken(parameters) and you'll always have access to the contacts. Make sense? Here, take a look:
// get this information from Google's API Console after registering your app
var parameters = new OAuth2Parameters
{
ClientId = #"",
ClientSecret = #"",
RedirectUri = #"",
Scope = #"https://www.google.com/m8/feeds/",
AccessCode = "",
AccessToken = "", /* use the value returned from the old call to GetAccessToken here */
RefreshToken = "", /* use the value returned from the old call to GetAccessToken here */
};
// get an access token
OAuthUtil.RefreshAccessToken(parameters);
// setup connection to contacts service
var contacts = new ContactsRequest(new RequestSettings("<appname>", parameters));
// get each contact
foreach (var contact in contacts.GetContacts().Entries)
{
System.Diagnostics.Debug.WriteLine(contact.ContactEntry.Name.FullName);
}
Edit:
// generate the authorization url
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
// now use the url to authorize the app in the browser and get the access code
(...)
// get this information from Google's API Console after registering your app
var parameters = new OAuth2Parameters
{
ClientId = #"",
ClientSecret = #"",
RedirectUri = #"",
Scope = #"https://www.google.com/m8/feeds/",
AccessCode = #"<from previous step>",
};
// get an access token
OAuthUtil.GetAccessToken(parameters);
// setup connection to contacts service
var contacts = new ContactsRequest(new RequestSettings("<appname>", parameters));
// get each contact
foreach (var contact in contacts.GetContacts().Entries)
{
System.Diagnostics.Debug.WriteLine(contact.ContactEntry.Name.FullName);
}