I'm trying authenticate a user on WordPress using a REST API Route configured with POST method. I have already done this with it configured with the GET method but this isn't exactly safe for user authentication. So I need to send a POST request to this endpoint with the email and password I get from the login form. The code I currently have does get to the endpoint which uses the function and returns a string if I put echo "It works". However if I try to echo or return the values of my POST it returns nothing.
Xamarin Code:
var password = Wachtwoord.Text;
var email = Email.Text;
var client = new HttpClient();
var content = new StringContent(
JsonConvert.SerializeObject(new { email = email, password = password }));
var result = await client.PostAsync("https://staging.myopinion.be/wp-json/app-endpoint/auth", content).ConfigureAwait(false);
if (result.IsSuccessStatusCode)
{
var tokenJson = await result.Content.ReadAsStringAsync();
var test = tokenJson;
}
WordPress Functions code:
function authenticate_user(WP_REST_Request $request) {
$login = $_POST;
$email = $_POST['email'];
$password = $login['password'];
echo $email;
}
Related
I have a web server on which I'm hosting my own api for one of my projects.
This is the php-code of the api-website:
$user = $_POST['username'];
$password = $_POST['password'];
if(strcmp($user, "username") == 0 && strcmp($password, "password") == 0) {
...
} else {
die("No Permissions");
}
I want to send the two variables username and password with a HttpClient and the postAsync-method to this website and if the right log in data is detected, it returns the data I want.
For this I have the following code in C#:
Task<HttpResponseMessage> response;
var url = "www.url.de"; //not the url I'm actually calling!
var vars = "[{\"username\":\"username\", \"password\":\"password\"}]";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
response = client.PostAsync(url, new StringContent(vars, Encoding.UTF8));
Console.WriteLine(response.Result.Content.ReadAsStringAsync().Result);
if (response.IsCompleted)
{
Console.WriteLine(response.Result.Content.ReadAsStringAsync().Result);
}
}
But the problem is that no matter what I have tried the output from this code is, that i have no permissions. And I have changed the php-code, so that I can see which data is stored in $username and $password, but they are empty and I don't know why. I hope somebody can help me with this.
Your PHP code is expecting the data sent as application/x-www-form-urlencoded, but your C# code is sending it as JSON.
As mentioned in the comment by M. Eriksson, you either need to change your PHP to accept JSON, or change your C# to send as form data.
This answer shows how to use HTTPClient to send data like that.
Here's my modification of your code based on the above code (I did test it):
public static async Task DoSomething()
{
string url = "http://httpbin.org/post"; //not the url I'm actually calling!
Dictionary<string, string> postData = new();
postData["username"] = "username";
postData["password"] = "password";
using HttpClient client = new();
client.DefaultRequestHeaders.Accept.Add(new("application/json"));
HttpRequestMessage request = new(HttpMethod.Post, url);
request.Content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = await client.SendAsync(request);
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}
I'm trying to get a list of reports from SSRS Rest API. I can see them when I navigate to the URL http://someaddress/reports/api/V2.0/reports in chrome
When I navigate there in the browser an input box shows up and asks for a username and password.
So I've tried this:
var client = new HttpClient(){BaseAddress= new Uri("Http://someaddress/reports/api/V2.0");
client.DefaultRequestHeaders.Add("Username",#"someuser");
client.DefaultRequestHeaders.Add("Password",#"some password");
var response= await _client.GetAsync("reports");
It's returning 401 unauthorized.
Can someone please explain how I can pass the username and password in so I get the correct response?
If you are using username and password, you need to use NTLM cretendials to authenticate the request. You can achieve it using HttpClientHandler and CredentialCache, like this:
var uri = new Uri("Http://someaddress/reports/api/V2.0");
var networkCredential = new NetworkCredential(#"someuser", #"some password", "");
var credentialsCache = new CredentialCache { { uri, "NTLM", networkCredential } };
var handler = new HttpClientHandler { Credentials = credentialsCache };
var client = new HttpClient(handler) { BaseAddress = uri };
var response= await client.GetAsync("reports");
I have tried to get access token for PowerBI API with the following method and proper inputs for clientId, clientSecret, username and password but I get Bad Request saying required parameter 'grant_type' is missing.
public static async Task<string> GetToken()
{
var client = new RestClient();
var url = "https://login.microsoftonline.com/common/oauth2/token"
var request = new RestRequest(url, Method.POST, DataFormat.Json);
var body = new
{
grant_type = "password",
client_id = "clientId",
client_secret = "clientSecret",
username = "user",
password = "password",
resource = "https://analysis.windows.net/powerbi/api"
};
request.AddJsonBody(body);
var response = await client.ExecutePostAsync(request);
return response.Content;
}
Something wrong with by JSON body or something completely different?
Your request body needs to be form url encoded - not json
If you're using C# I'd recommend using the Identity model library to reduce mistakes.
Here is some sample code
I am trying to delete an Azure function from my Function App through C#.
But while deleting it programmatically, the function is not seen on the User Interface, but when I check it through Advanced tools (Kudu), I can still see my Azure function.
So basically while deleting the Azure function, what I do is, I delete it's function.json, and by doing so the Azure function isn't visible in Functions App list (see image below)
But when I go to Advanced Kudu to check whether it has been deleted, I can still see it, but without the function.json file. I had done this before (around 6 months back) and back then it was working properly. I don't know if I am doing it wrong or has anything changed.
Any help with the code would be appreciated.
Thanks
Edit:
The details that I have with me is the Function App's username, password, url, name (https://my-function-app.scm.azurewebsites.net/api/vfs/site/wwwroot), and azure function's name.
A little sample code of what I did which worked 6 months back
private WebClient _webClient = new WebClient
{
Headers = { ["ContentType"] = "application/json" },
Credentials = new NetworkCredential(username, password),
BaseAddress = functionsSiteRoot,
};
var functionJson =
JsonConvert.DeserializeObject<FunctionSettings>(_webClient.DownloadString("MyFunctionName/function.json"));
_webClient.Headers["If-Match"] = "*";
_webClient.UploadString("MyFunctionName/function.json", "DELETE", JsonConvert.SerializeObject(functionJson));
You could use REST API to perform this operation.
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/functions/{functionName}?api-version=2016-08-01
Method: DELETE
Code Snippet:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, string.Format("https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/functions/{functionName}?api-version=2016-08-01", "Pass All Param In {}")));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
HttpResponseMessage response = await _client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
dynamic objApiResponse = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());
}
else
{
return req.CreateResponse(HttpStatusCode.OK, "Sorry Invalid Request");
}
For details please have a look on official docs
Note: For token request your resource/Scope should be https://management.azure.com. Pass your token while send request.
Update:
You can request for token using client_credentials authentication flow. Try below format:
Azure Portal Credentials For App Id and Tenant Id:
Application Secret from Portal:
Token Endpoint Or URL:
https://login.microsoftonline.com/YourTenantName.onmicrosoft.com/oauth2/token
Request Param:
grant_type:client_credentials
client_id:b603c7be_Your_App_ID_e6921e61f925
client_secret:Vxf1Sl_Your_App_Secret_2XDSeZ8wL/Yp8ns4sc=
resource:https://graph.microsoft.com
PostMan Sample:
Token On Response:
Code Snippet For Token:
//Token Request End Point
string tokenUrl = $"https://login.microsoftonline.com/YourTenant/oauth2/token";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
//I am Using client_credentials as It is mostly recomended
tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "client_credentials",
["client_id"] = "20e08e95-_Your_App_ID_e9c711b0d19e",
["client_secret"] = "+trl[ZFl7l_Your_App_Secret__ghon9",
["resource"] = "https://management.azure.com/"
});
dynamic json;
AccessTokenClass results = new AccessTokenClass();
HttpClient client = new HttpClient();
var tokenResponse = await client.SendAsync(tokenRequest);
json = await tokenResponse.Content.ReadAsStringAsync();
results = JsonConvert.DeserializeObject<AccessTokenClass>(json);
//New Block For Accessing Data from API
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, string.Format("https://management.azure.com/subscriptions/YOurSubscription/resourceGroups/YourResourceGroup/providers/Microsoft.Web/sites/DeleteTestFuncAppName/functions/DeleteFunctionNameThatYouWantToDelete?api-version=2016-08-01"));
//Passing Token For this Request
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
HttpResponseMessage response = await client.SendAsync(request);
//Read Server Response
dynamic objServerResponse = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());
Class I Have Used:
public class AccessTokenClass
{
public string token_type { get; set; }
public string expires_in { get; set; }
public string resource { get; set; }
public string scope { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
}
Point To Remember:
If you got this error
InvalidAuthenticationToken: The received access token is not valid: at
least one of the claims 'puid' or 'altsecid' or 'oid' should be
present. If you are accessing as application please make sure service
principal is properly created in the tenant
You have to assign role to your application like below:
I'm trying to use RestSharp to access Etsy's API. Here's the code I'm using attempting to get an OAuth access token:
var authenticator = OAuth1Authenticator.ForRequestToken(
ConfigurationManager.AppSettings["ApiKey"],
ConfigurationManager.AppSettings["ApiSecret"]);
// same result with or without this next line:
// authenticator.ParameterHandling = OAuthParameterHandling.UrlOrPostParameters;
this.Client.Authenticator = authenticator;
var request = new RestRequest("oauth/request_token")
.AddParameter("scope", "listings_r");
var response = this.Client.Execute(request);
Etsy tells me that the signature is invalid. Interestingly enough, when I enter the timestamp and nonce values generated by the request into this OAuth signature validation tool, the signatures don't match. Moreover, the URL generated by the tool works with Etsy where the one generated by RestSharp doesn't. Is there something I'm doing wrong or something else I need to configure with RestSharp?
Note: I'm using the version of RestSharp provided by their Nuget package, which at the time of this posting is 102.5.
I finally was able to connect to the Etsy API with RestSharp using OAuth. Here is my code -- I hope it works for you...
RestClient mRestClient = new RestClient();
//mRestClient.BaseUrl = API_PRODUCTION_URL;
mRestClient.BaseUrl = API_SANDBOX_URL;
mRestClient.Authenticator = OAuth1Authenticator.ForRequestToken(API_KEY,
API_SHAREDSECRET,
"oob");
RestRequest request = new RestRequest("oauth/request_token", Method.POST);
request.AddParameter("scope",
"shops_rw transactions_r transactions_w listings_r listings_w listings_d");
RestResponse response = mRestClient.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
return false;
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(response.Content);
string oauth_token_secret = queryString["oauth_token_secret"];
string oauth_token = queryString["oauth_token"];
string url = queryString["login_url"];
System.Diagnostics.Process.Start(url);
// BREAKPOINT HERE
string oauth_token_verifier = String.Empty; // get from URL
request = new RestRequest("oauth/access_token");
mRestClient.Authenticator = OAuth1Authenticator.ForAccessToken(API_KEY,
API_SHAREDSECRET,
oauth_token,
oauth_token_secret,
oauth_token_verifier);
response = mRestClient.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
return false;
queryString = System.Web.HttpUtility.ParseQueryString(response.Content);
string user_oauth_token = queryString["oauth_token"];
string user_oauth_token_secret = queryString["oauth_token_secret"];
The user_oauth_token and user_oauth_token_secret are the user's access token and access token secret -- these are valid for the user until the user revokes access.
I hope this code helps!