Sharepoint 2013 REST api from desktop application - Authentication - authentication

I am trying to consume SharePoint 2013 REST services from a Desktop application ( cross-platform, cross-os ). Application is basically a HTML page in application view.
Is there a simple way I can authenticate my calls using HTTP methods ?

Yes, you can get authenticated and receive a digest via a REST call.
string url = "http://Your.SP.Site";
HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
string cmd = "_api/contextinfo";
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("ContentType", "application/json");
client.DefaultRequestHeaders.Add("ContentLength", "0");
StringContent httpContent = new StringContent("");
var response = client.PostAsync(cmd, httpContent).Result;
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
JsonObject val = JsonValue.Parse(content).GetObject();
JsonObject d = val.GetNamedObject("d");
JsonObject wi = d.GetNamedObject("GetContextWebInformation");
retVal = wi.GetNamedString("FormDigestValue");
}
The above example shows how to retrieve the digest in C# with the HttpClient. This string needs to be passed as a header to all of the other rest calls you make to carry forward the authentication. You can create a credential by passing in a username and password if needed.
I have more examples here:
https://arcandotnet.wordpress.com/2015/04/01/sharepoint-2013-rest-services-using-c-and-the-httpclient-for-windows-store-apps/
You can do these calls in JavaScript as well and Microsoft has a lot of documentation on that. There is also .NET library, Microsoft.SharePoint.Client.DLL (CSOM) that simplifies this type of coding but you must have the library installed on the client.

Related

Api calling in .net core razor pages

I am working on (built-in web apis) provided by whatsapp business api. As a newbie in .net core razor pages and web apis. I want to know how can I get access to the body of the post request api. Take an example below for sending a message
Post: {URL}/v1/messages
Request Body:
"to": "",
"message_type:"
"message_text:"
"recipient_type: "individual | group""
How can I make a call to the builtin api and access the body parts of it?
Ofcourse, we as a developer can use postman for checking the working of api. But take this as a client and for the client we have some fields like
To:
Message:
How can take these fields and put it into the api call body and then when the user click on the send, the api call works and shows whatever we want to show the user for example a model with send successfully etc.
You can call the API using HttpClient.
Add the URL in await client.PostAsync() function. If you have authorization use client.DefaultRequestHeaders.Authorization otherwise omit it
string myContent = "";
string myJson = <JsonQuery>;
using (HttpClient client = new HttpClient())
{
// If any authorization available
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenLabel.Text.Trim());
using (HttpResponseMessage response = await client.PostAsync("https:url", new StringContent(myJson, Encoding.UTF8, "application/json")))
{
using (HttpContent content = response.Content)
{
myContent = await content.ReadAsStringAsync();
}
}
}
Update
Content
string myJson = "{\"subject\": }";
URL
using (HttpResponseMessage response = await client.PostAsync("{{URL}}/v1/groups", new StringContent(myJson, Encoding.UTF8, "application/json")))
Header
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "");

.NET Core 2 programmatically authentcation on Keycloak example

I'm trying to authenticate through a device (it's a barcode reader) that use .NET Core. I'm a newbie on .NET Core.
Now I need to write some program that gives me the possibility that given a username/password I make authentication on a Keycloak server with openidconnect. Is there some sample that shows how from a username/password string I can make the authentication programmatically?
I find a lot of examples that use .NET Core as a server that has Controllers that exposes rest API for user that have to be authenticated. But I need some example/hint to follow where the .NET Core makes the request.
Update
I could figure out (with curl) what exactly I have to do. Two calls to the Keycloak server.
call:
http://keycloakserver/auth/realms/realmName/protocol/openid-connect/token?grant_type=password&client_id=demo-app&username=username&password=password
This gives me back an object containing the access_token.
invoke the secured service adding in the header
"Authorization: bearer +access_token"
I try to develop this two calls with .NET Core.
I found this way to resolve it. But I'm sure is not the best way. I think there is a lot of improvement of security:
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");
var values = new Dictionary<string, string>
{
{ "client_id", "myClientId" },
{ "grant_type", "password" },
{ "username", "usernaName" },
{ "password", "password" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://domain/auth/realms/realmName/protocol/openid-connect/token", content);
var responseString = await response.Content.ReadAsStringAsync();
var responseToken = JsonConvert.DeserializeObject<ResponseToken>(responseString);
Console.WriteLine("accessToken: " + responseToken.AccessToken);
var client2 = new HttpClient();
client2.DefaultRequestHeaders.Accept.Clear();
client2.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
client2.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");
client2.DefaultRequestHeaders.Add("Authorization", "bearer "+ responseToken.AccessToken);
var dataResponse = client2.GetStreamAsync("http://serviceDomain/api/SampleData/WeatherForecasts");
var serializer = new DataContractJsonSerializer(typeof(List<Weather>));
var tempData = serializer.ReadObject(await dataResponse) as List<Weather>;
Console.WriteLine(tempData);
If you have a better solution then don't hesitate to post it.

How to connect to Onedrive using MSAL?

I'm trying to connect to OneDrive using MSAL token but it's returning error="invalid_token", error_description="Auth error"
This is my code:
public static string[] Scopes = { "User.Read", "Files.Read", "Sites.Read.All" };
AuthenticationResult ar = await App.ClientApplication.AcquireTokenSilentAsync(Scopes);
WelcomeText.Text = $"Welcome {ar.User.Name}"; //Login OK here
//get data from API
HttpClient client = new HttpClient();
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, "https://api.onedrive.com/v1.0/drives");
message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", ar.Token);
HttpResponseMessage response = await client.SendAsync(message);
string responseString = await response.Content.ReadAsStringAsync();
Anyone know what I'm doing wrong ?
The direct API endpoint (api.onedrive.com) doesn't support access tokens generated from MSAL, only tokens generated from MSA. If you are using MSAL, you should use the Microsoft Graph API (graph.microsoft.com) to access OneDrive files for both personal and business users.
You already got your answer long time back but I hope this link will be helpful for someone else in future.
https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/onedrive

How to delegate Identity from Web-Application to WebAPI

I am trying to build a website, where the user logs in at the and can use an backend web-API.
Calls to the backend web-API will always be proxied by the frontend website, since the backend is not publicly available.
Back- and frontend are MVC 6 (or MVC Core?) projects based on ASP.net Core.
The frontend currently authenticates (successfully) by using OpenId-Connect.
The backend should use JwtBearerToken.
The authentication so far requests the response type is id_token code and the scope is openid profile.
After the roundtrip to the Auth-Server (ADFS 2016), I will end up in the AuthorizationCodeReceived-Event from ASP.NET, but I have no luck in exchanging the code for authorization token. I tried the following using ADAL:
public override async Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
await base.AuthorizationCodeReceived(context);
var clientCredential = new ClientCredential(context.Options.ClientId, context.Options.ClientSecret);
var oAuthContext = new AuthenticationContext(context.Options.Authority, false);
var oAuthResult = await oAuthContext.AcquireTokenByAuthorizationCodeAsync(context.Code, new Uri(context.RedirectUri), clientCredential);
}
I had to disable the authority validation (which I do not like) and I do not get results other than Http-Status 400.
I'd be happy for any advice how to move on.
Update
Further Investigation Shows, that the OpenIdConnect-Configuration allows to save auth and refresh Tokens into the Claims. Nevertheless I don't see the possibility to convert it in the first place.
I also tried exchanging the code by hand (PS: Invoke-WebRequest ...) but had no success. Perhaps this is a problem of ADFS TP4...
I've managed to get this scenario to work with TP4.
AuthorizationCodeReceived = async n =>
{
string code = n.Code;
AuthenticationContext ac = new AuthenticationContext(BaseAddress, false);
ClientCredential client = new ClientCredential("clientid", "secret");
string resourceId = "https://myservices/myapi";
AuthenticationResult ar = await ac.AcquireTokenByAuthorizationCodeAsync(code, new Uri("https://localhost:44300/"), client, resourceId);
}
You can then use the access token from a controller method like this:
AuthenticationContext ac = new AuthenticationContext(Startup.BaseAddress, false);
ClientCredential cred = new ClientCredential("clientid", "secret");
string resourceId = "https://myservices/myapi";
AuthenticationResult ar = ac.AcquireTokenSilent(resourceId, cred, UserIdentifier.AnyUser);
var client = new HttpClient();
client.SetBearerToken(ar.AccessToken);
var result = await client.GetStringAsync("http://localhost:2727/identity");

How to call API URL windows 8 C#

I am new to windows 8. I want to call api url and the response will be return in terms of json. My Question is how to call below api url in my windows 8 code with c#.
API URL: http://scwin8dashboard.cloudapp.net/shell/~/analytics/reports/reports.ashx?fff=0&report=CampaignCategoriesOverview&languages=&sites=&startDate=20080101&endDate=20121114&addLastModified=true
please help
var uri = "http://scwin8dashboard.cloudapp.net/shell/~/analytics/reports/reports.ashx?fff=0&report=CampaignCategoriesOverview&languages=&sites=&startDate=20080101&endDate=20121114&addLastModified=true";
var client = new HttpClient();
var response = await client.GetStringAsync(uri);
var parser = JsonObject.Parse(response);
For more informations about Http requests see this page.
For JSON related classes see the Windows.Data.Json namespace.