I have two ASP.NET vNext Web Applications running with CoreCLR on Azure WebSites, published by the lates Visual Studio 2015 CTP.
When I'm trying to make a call from one application to the second with standard HttpClient code:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_webUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpContent contentPost = new StringContent(request.ToJson(), Encoding.UTF8, "application/json");
var response = await client.PostAsync(uri, contentPost);//.PostAsJsonAsync("api/products", request);
if (response.IsSuccessStatusCode)
{
...
}
}
I get following exception:
WinHttpException: An attempt was made to access a socket in a way forbidden by its access permissions.
System.Net.Http.WinInetProxyHelper.GetProxyForUrl(SafeInternetHandle sessionHandle, Uri uri, WINHTTP_PROXY_INFO& proxyInfo)
HttpRequestException: An error occurred while sending the request.
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
my web.config on the azure websites ftp:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="kpm-package-path" value="..\approot\packages" />
<add key="bootstrapper-version" value="1.0.0-beta2" />
<add key="kre-package-path" value="..\approot\packages" />
<add key="kre-version" value="1.0.0-beta2" />
<add key="kre-clr" value="CoreCLR" />
<add key="kre-app-base" value="..\approot\src\Ingrid.Web" />
</appSettings>
</configuration>
Solution which I found on: https://github.com/sendgrid/sendgrid-csharp/issues/18
it's better to go with RestSharp than HttpClient, and it is indeed working: http://restsharp.org/
Related
I am trying to learn ASP.Net with Azure AD B2C Login / Register flow. I am running the demo here:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-web-api-dotnet?tabs=app-reg-ga
The C# code for the demo can be downloaded from https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi/archive/master.zip
I have gone all the way through the demo from the beginning and have completed all of the pre-requisites.
I am at the point now where I have signed in successfully and when I click the To-Do List link while debugging the application, I get a User Not Authorized (404) error.
I apologize in advance if I am not explaining what I think I am seeing very well, as I am very new to Azure and web programming. I am most comfortable with Windows Desktop applications interfacing with SQL Server, but I am trying to expand my knowledge, so please bear with me.
As I stated before, I can successfully log-in to the application, which I believe happens in the TaskWebApp project.
Here is the code where the error is happening, which is in the TasksController.cs in the TaskWebApp project:
namespace TaskWebApp.Controllers
{
[Authorize]
public class TasksController : Controller
{
private readonly string apiEndpoint = Globals.ServiceUrl + "/api/tasks/";
// GET: Makes a call to the API and retrieves the list of tasks
public async Task<ActionResult> Index()
{
try
{
// Retrieve the token with the specified scopes
var scope = new string[] { Globals.ReadTasksScope };
IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var accounts = await cca.GetAccountsAsync();
AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync();
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiEndpoint);
// Add token to the Authorization header and make the request
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
// Handle the response
switch (response.StatusCode)
{
case HttpStatusCode.OK:
string responseString = await response.Content.ReadAsStringAsync();
JArray tasks = JArray.Parse(responseString);
ViewBag.Tasks = tasks;
return View();
case HttpStatusCode.Unauthorized:
return ErrorAction("Please sign in again. " + response.ReasonPhrase);
default:
return ErrorAction("Error. Status code = " + response.StatusCode + ": " + response.ReasonPhrase);
}
}
catch (MsalUiRequiredException ex)
{
/*
If the tokens have expired or become invalid for any reason, ask the user to sign in again.
Another cause of this exception is when you restart the app using InMemory cache.
It will get wiped out while the user will be authenticated still because of their cookies, requiring the TokenCache to be initialized again
through the sign in flow.
*/
return new RedirectResult("/Account/SignUpSignIn?redirectUrl=/Tasks");
}
catch (Exception ex)
{
return ErrorAction("Error reading to do list: " + ex.Message);
}
}
The response status code in the Switch statement is 404.
When I debug, here is what I see:
var scope returns https://ShoppingCartB2C.onmicrosoft.com/tasks/demo.read
cca returns (I am questioning the format of the Authority property):
accounts returns nothing. A count of 0.
I believe 0 accounts is the problem.
When I try to get result, it goes to the catch block.
Here is the Web.config for the TaskWebApp project:
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:Tenant" value="ShoppingCartB2C.onmicrosoft.com" />
<!--MSAL cache needsĀ a tenantId along with the user's objectId to function. It retrieves these two from the claims returned in the id_token.
As tenantId is not guaranteed to be present in id_tokens issued by B2C unless the steps listed in this
document (https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/AAD-B2C-specifics#caching-with-b2c-in-msalnet).
If you are following the workarounds listed in the doc and tenantId claim (tid) is available in the user's token, then please change the
code in <ClaimsPrincipalsExtension.cs GetB2CMsalAccountId()> to let MSAL pick this from the claims instead -->
<add key="ida:TenantId" value="db1b052a-415c-4604-887c-e27b59860001" />
<add key="ida:ClientId" value="975f1457-e3e2-4cb8-b069-6b0b6b46611d" />
<add key="ida:ClientSecret" value="Gw4.3o-DRDr.j_828H-JMfsk_Jd1d-jQ5p" />
<add key="ida:AadInstance" value="https://ShoppingCartB2C.b2clogin.com/tfp/{0}/{1}" />
<add key="ida:RedirectUri" value="https://localhost:44316/" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<add key="ida:EditProfilePolicyId" value="b2c_1_profileediting1" />
<add key="ida:ResetPasswordPolicyId" value="b2c_1_passwordreset1" />
<add key="api:TaskServiceUrl" value="https://localhost:44332/" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ApiIdentifier" value="https://ShoppingCartB2C.onmicrosoft.com/tasks/" />
<add key="api:ReadScope" value="demo.read" />
<add key="api:WriteScope" value="demo.write" />
</appSettings>
And for the TaskService project:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:AadInstance" value="https://ShoppingCartB2C.b2clogin.com/{0}/{1}/v2.0/.well-known/openid-configuration" />
<add key="ida:Tenant" value="ShoppingCartB2C.onmicrosoft.com" />
<add key="ida:ClientId" value="975f1457-e3e2-4cb8-b069-6b0b6b46611d" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ReadScope" value="demo.read" />
<add key="api:WriteScope" value="demo.write" />
</appSettings>
If you would like screen shots from Azure, or have questions about how that is configured, feel free to ask.
I am not concerned about exposing client secrets or AppId's because I am just following a demo. This is never going to be a production app.
I have not made any code modifications to the demo. Thanks for your help.
Edit: Showing API Permissions
I'm trying to connect to AWS DynamoDb by creating an AmazonDynamoDBClient.
I'm getting the following exception:
Amazon.Runtime.AmazonClientException: No RegionEndpoint or ServiceURL configured
at Amazon.Runtime.ClientConfig.Validate()
at Amazon.Runtime.AmazonServiceClient..ctor(AWSCredentials credentials, ClientConfig config)
I have the following lines in my App.Config file (the actual keys are in my code):
<appSettings>
<add key="AWSProfileName" value="development" />
<add key="AWSAccessKey" value="XXXXXXXXXX" />
<add key="AWSSecretKey" value="YYYYYYYYYY" />
<add key="AWSRegion" value="us-east-2" />
</appSettings>
I also have a credentials file under the AWS folder. Includes the following:
[development]
aws_access_key_id = XXXXXXXX
aws_secret_access_key = YYYYYYYYYY
In my code, I'm simply calling to:
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
I'm working in visual-studio 2019. This used to work when I was working in a simple console application environment. Now I am working under Azure-Functions template project.
Why am I getting error?
Not sure why it is not working since you have added AWSRegion to the config. I suggest to add the below to your credentials file
[development]
aws_access_key_id = XXXXXXXX
aws_secret_access_key = YYYYYYYYYY
region = us-east-2
I am trying a pretty simple GET request for a domain in a .NET Core 2.0 console application:
static void Main(string[] args)
{
MainAsync().Wait();
}
static async Task MainAsync()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://www.staples.com");
}
This times out every time, throwing a web exception.
I can visit the website https://www.staples.com in my web browser or execute a GET request in postman without a problem, returning in < 1s.
I can even do a simple curl request on the domain and it works fine:
curl https://www.staples.com
Another domain I found the same problem on is https://www.safeco.com/
I have even tried adding some headers to make it seem like this a Chrome browser request, but made no difference:
message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36");
message.Headers.Add("Accept-Language", "en-US,en;q=0.8");
message.Headers.Add("Cache-Control", "no-cache");
message.Headers.Add("Pragma", "no-cache");
message.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;" +
"q=0.9,image/webp,image/apng,*/*;q=0.8");
Any other URL that I tried not on those domains seems to work fine. Why are these two domains timing out with HttpClient requests?
It's almost certainly some sort of connection filtering on their end to prevent scraping but only their IT department would ever be able to confirm that. You can get it working by mimicking a browser and sending the correct headers. It seems this site requires a minimum of:
Connection: keep-alive
Accept-Encoding: gzip
Accept-Language: xxx
For example:
static async Task<string> MainAsync()
{
//Added this to decompress the gzip encoded response
HttpClientHandler handler = new HttpClientHandler();
handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip;
var client = new HttpClient(handler);
var request = new HttpRequestMessage()
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://www.staples.com"),
Version = new Version(1, 1)
};
request.Headers.Connection.Add("keep-alive");
request.Headers.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("en-GB"));
var response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
Not an answer, but not appropriate for comment either - Maybe you can glean something from the network trace by adding this to your config. Just change the value of initializeData to a writable location, make a request, then look at the output. It ain't pretty but there may be a clue.
<system.diagnostics>
<sources>
<source name="System.Net" maxdatasize="102400" tracemode="includehex">
<listeners>
<add name="System.Net" />
</listeners>
</source>
</sources>
<switches>
<add name="System.Net" value="Verbose" />
</switches>
<sharedListeners>
<add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\somewhere...\networkErr.log" />
</sharedListeners>
</system.diagnostics>
According to this. I need to enable local network traffic in the manifest file of c# application. Can anyone paste a sample code to enable it in application manifest file?
I tried to use fiddler proxy in httpclient however its not going to fiddler proxy. I stumbled upon this post and they says enable local network traffic in the manifest file https://social.msdn.microsoft.com/Forums/en-US/ce2563d1-cd96-4380-ad41-6b0257164130/winrt-using-httpclient-with-systems-proxy?forum=winappswithcsharp any help appreciated.
Current my application manifest are the following
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<system.net>
<connectionManagement>
<add address="*" maxconnection="6500" />
</connectionManagement>
<settings>
<servicePointManager expect100Continue="false" />
</settings>
</system.net>
</configuration>
httpclient code this request is not going through fiddler.
string url_get_string = "http://localhost/php/tmp/test.php?Get_C="+ ID;
HttpClientHandler handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.CookieContainer = cookieJar;
handler.Proxy = new WebProxy("http://127.0.0.1:8888", false);
handler.UseProxy = true;
handler.UseDefaultCredentials = false;
var client = new HttpClient(handler);
I have an application in C# which uses a service reference to send SMS through a web service. The user's internet connection needs to pass through a proxy server in order to reach the world.
So my question is how to tell .NET to call web service through the proxy? Or how to set proxy settings for internet connection of my application just like what you can do in YMahoo Messenger?
Also I want to let user to choose proxy settings.
I believe what you are looking for is defaultProxy in your config file.
Here's an example from the link:
<configuration>
<system.net>
<defaultProxy>
<proxy
usesystemdefault="true"
proxyaddress="http://192.168.1.10:3128"
bypassonlocal="true"
/>
<bypasslist>
<add address="[a-z]+\.contoso\.com" />
</bypasslist>
</defaultProxy>
</system.net>
</configuration>
Please try below code hope this will help you
tring targetUrl = "http://www.google.com";
string proxyUrlFormat = "http://zend2.com/bro.php?u={0}&b=12&f=norefer";
string actualUrl = string.Format(proxyUrlFormat, HttpUtility.UrlEncode(targetUrl));
// Do something with the proxy-ed url
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(actualUrl));
HttpWebResponse resp = req.GetResponse();
string content = null;
using(StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
content = sr.ReadToEnd();
}
Console.WriteLine(content);