I need to parse a website but this one has Windows authentication (kerberos), I authenticated with HttpRequester but How can I pass the authentication to AngleSharp?
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Credentials = new NetworkCredential("user", "pass");
req.CookieContainer = session;
After that, I don't know how to continue to pass the session to AngleSharp connection:
var configuration = Configuration.Default.WithDefaultLoader().WithCookies();
var context = BrowsingContext.New(configuration);
await context.OpenAsync(WebsiteUrl);
You need to NuGet the AngleSharp.Io package, that will enable the "WithRequesters"
And then:
var credentials = new NetworkCredential("user", "pass", "domain");
var handler = new HttpClientHandler { Credentials = credentials };
var config = Configuration.Default.WithRequesters(handler).WithCookies();
var context = BrowsingContext.New(config);
var document = await context.OpenAsync(url)
Related
How do I change response_type to token in Startup.cs in "OAuth client"?
The server only recognizes the request with the response_type equal to token.
services.AddOAuth("OurServer", config => {
config.ClientId = "client_id";
config.ClientSecret = "client_secret";
config.CallbackPath = "/oauth/callback";
config.AuthorizationEndpoint = "https://localhost:44382/oauth/authorize";
config.TokenEndpoint = "https://localhost:44382/oauth/token";
config.SaveTokens = true;
config.Events = new OAuthEvents()
{
OnCreatingTicket = context =>
{
var accessToken = context.AccessToken;
var base64payload = accessToken.Split('.')[1];
var bytes = Convert.FromBase64String(base64payload);
var jsonPayload = Encoding.UTF8.GetString(bytes);
var claims = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonPayload);
foreach (var claim in claims)
{
context.Identity.AddClaim(new Claim(claim.Key, claim.Value));
}
return Task.CompletedTask;
}
};
});
By default the OAuth authentication handler uses response_type='code' internally and does not let you change that- reference here.
If you wish to change that you have to create a custom OAuth authentication handler and override BuildChallengeUrl() where you can set your response_type.
You can see how you can use your custom handler here: link
I have written some integration tests using Microsoft.AspNetCore.TestHost, But when I try to get a message as Invalid URI.
I can create TestServer successfully and able to create a client. But when I call an API using the client it says invalid URI. The URL created by TestHost is http://localhost/ and there is nothing look wrong in that URL.
I am not able to understand how could this URL be wrong. There is no other localhost website running in my machine also.
When I run my web API it's run on this URL Http:\localhost:5000 and set that as base address in my test project but it still throws the same error.
This my code to build Test Server
public MongoDbFixture()
{
var builder = new WebHostBuilder()
.UseContentRoot(GetContentRootPath())
.UseEnvironment("Test")
.UseConfiguration(new ConfigurationBuilder()
.SetBasePath(GetContentRootPath())
.AddJsonFile("appsettings.Test.json")
.Build())
.UseStartup<Startup>(); // Uses Start up class from your API Host project to configure the test server
_testServer = new TestServer(builder);
Client = _testServer.CreateClient();
//Client.BaseAddress = new Uri("http://localhost:5000/");
AuthClient = _testServer.CreateClient();
//AuthenticateClient();
//AddPromptQuestions();
//SetupGoogleTranslationService();
}
This is a code to make a request.
public async Task<string> GetToken()
{
try
{
if (string.IsNullOrEmpty(token))
{
//var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("email", "kunal.ahmedabad#gmail.com"), new KeyValuePair<string, string>("password", "Password123!") });
var content = new StringContent("{email:'test#test.com',password:'Integration#85'}", Encoding.UTF8, "application/json");
var response = await Client.PostAsync(new Uri("api/Accounts/Login"), content).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
//var token = await response.Content.ReadAsAsync<OkResult>();
var newToken = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var tokenResponse = JsonConvert.DeserializeAnonymousType(newToken, new { Token = "", IsPhoneNumberConfirmed = "" });
token = tokenResponse.Token;
//token = newToken.Split(":")[1].Replace("\"", "").Replace("}", "");//todo:add better logic to read token.
return token;
}
}
catch (Exception)
{
}
return "";
}
I am not sure what is a valid URL, but this setup was working earlier.
Try changing:
new Uri("api/Accounts/Login")
To:
new Uri("api/Accounts/Login", UriKind.Relative)
I have a Aspnet Core API thats trying to connect to a Microsoft Dynamics 365 instance. The goal is to push data to the CRM Instance using an API.
In order to do this, I have a CRM User and a Pass and my understanding is I will need an OAuth token to actually complete my request.
How can I go about getting that OAuth token from an API ?
My current (non working) code looks like this:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(CrmFInanceCCNotifyDto.Instance.CrmBaseUri);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{CrmFInanceCCNotifyDto.Instance.CrmUser}:" +
$"{CrmFInanceCCNotifyDto.Instance.CrmPass}")));
client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
client.DefaultRequestHeaders.Add("OData-Version", "4.0");
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("If-Match", "*");
var method = "PATCH";
var httpVerb = new HttpMethod(method);
string path = client.BaseAddress + CrmFInanceCCNotifyDto.Instance.CrmLocationUpdateUri;
string jsonPayload = "{\"entity.dfnd_financingused\": 1}";
var stringContent = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
var httpRequestMessage =
new HttpRequestMessage(httpVerb, path)
{
Content = stringContent
};
try
{
var response = await client.SendAsync(httpRequestMessage);
Any pointers in solving this will be much appreciated.
Thanks
This question already has an answer here:
Azure AD B2C error - IDX10501: Signature validation failed
(1 answer)
Closed 5 years ago.
Doesn't seem Azure documentation can give a clear example hot to do it right.
There are Angular4 (WebApp) and WebAPI Core 2.0 back-end.Two application configured in Azure B2C. WebApp has WebAPI app in its API access.
Web app gets redirected to https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize. There, credentials provided and then AAD B2C calls back WebApp page with access_token, token_type, expires_in, id_token url parameters.
Then, WebApp makes a request to a protected endpoint of the back-end with access_token in Authorization header. MessageReceivedAsync is called when request hits the back-end and goes all the way through validating the token.
However, when process exits the method next step it goes into is AuthenticationFailed with error.
"IDX10501: Signature validation failed. Unable to match 'kid': 'Base64_kid',
token: '{"alg":"RS256","typ":"JWT","kid":"Base64_kid"}.{"iss":"number of claims"}'."
My understanding that Audience is the WebAPI application id. I have only a SingIn/Up policy.
What am I missing here to complete jwt manual validation w/o errors? Another question, when claimsPrincipal is created when token validated, how does it go into request context to be able to access protected endpoint?
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.Authority = string.Format("https://login.microsoftonline.com/{0}/v2.0/",
Configuration["Authentication:AzureAd:ida:Tenant"], Configuration["Authentication:AzureAd:ida:Policy"]);
options.Audience = Configuration["Authentication:AzureAd:ida:ClientId"];
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = AuthenticationFailed,
OnMessageReceived = MessageReceivedAsync,
OnChallenge = Challenge,
OnTokenValidated = TokenValidated
};
});
...
}
private Task MessageReceivedAsync(MessageReceivedContext arg)
{
string jwtToken = null;
var aadInstance = Configuration["Authentication:AzureAd:ida:AADInstance"];
var tenant = Configuration["Authentication:AzureAd:ida:Tenant"];
var audience = Configuration["Authentication:AzureAd:ida:Audience"];
var policy = Configuration["Authentication:AzureAd:ida:Policy"];
var authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
string _issuer = string.Empty;
List<SecurityKey> _signingTokens = null;
var authHeader = arg.HttpContext.Request.Headers["Authorization"];
// 7 = (Bearer + " ").Length
var token = authHeader.ToString().Substring(7);
try
{
string stsDiscoveryEndpoint = string.Format("{0}/v2.0/.well-known/openid-configuration?p={1}", authority, policy);
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint,
new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration config = null;
var openIdConfigTask = Task.Run(async () => {
config = await configManager.GetConfigurationAsync();
});
openIdConfigTask.Wait();
_issuer = config.Issuer;
_signingTokens = config.SigningKeys.ToList();
}
catch(Exception ex)
{
...
}
var tokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters
{
ValidAudience = audience,
ValidIssuer = _issuer,
IssuerSigningKeys = _signingTokens
};
var claimsPrincipal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
//Thread.CurrentPrincipal = claimsPrincipal; ?
//var ticket = new AuthenticationTicket(claimsPrincipal, arg.Scheme.Name); ?
//arg.HttpContext.User = claimsPrincipal; ?
return Task.FromResult(0);
}
The options.Audience property is correct (i.e. the application identifier for the Web API application) but the JWT bearer authentication middleware is downloading the wrong signing keys because you don't seem to be setting the options.Authority property to the right value.
It must include the Azure AD B2C policy.
You should be setting it to:
https://login.microsoftonline.com/tfp/{tenant}/{policy}/v2.0/'
such as:
https://login.microsoftonline.com/tfp/{Configuration["Authentication:AzureAd:ida:Tenant"]}/{Configuration["Authentication:AzureAd:ida:Policy"]}/v2.0/.
As result of the token validation, the HttpContext.User object contains the claims from the token, so you can control access for example via scopes.
I want get Location in Response Header but i can't see this in Response. How to get this. Please help me.
var client = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
FormUrlEncodedContent postData = new FormUrlEncodedContent(new[] {
new KeyValuePair<string,string>("background","1"),
new KeyValuePair<string,string>("line1","Content1"),
new KeyValuePair<string,string>("line2","Content2")
});
HttpResponseMessage response = await client.PostAsync("URL", postData);
string rp = await response.Content.ReadAsStringAsync();