reCaptcha and SSL web site - c#

I using a reCaptcha on my web page under asp.net mvc. This web site have a SSL certificated, and I having and problem with reCaptcha.
This is my code on View:
<script type="text/javascript" src="https://api-secure.recaptcha.net/challenge?k=***Public key****"> </script>
<noscript>
<iframe src="https://api-secure.recaptcha.net/noscript?k=***Public key****" height="300" width="500" frameborder="0"></iframe><br />
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge" />
</noscript>
and this code is that I have on AccountController:
private bool PerformRecaptcha()
{
var validator = new RecaptchaValidator
{
PrivateKey = "**Private Key***",
RemoteIP = Request.UserHostAddress,
Response = Request.Form["recaptcha_response_field"],
Challenge = Request.Form["recaptcha_challenge_field"]
};
try
{
var validationResult = validator.Validate();
if (validationResult.ErrorMessage == "incorrect-captcha-sol")
ModelState.AddModelError("ReCaptcha", string.Format("Please retry the ReCaptcha portion again."));
return validationResult.IsValid;
}
catch (Exception e)
{
ModelState.AddModelError("ReCaptcha", "an error occured with ReCaptcha please consult documentation.");
return false;
}
}
and my library version is 1.0.5.0.
When I load the register form I have this alert on Opera:
The rules server certificate matches the server name. Do you want to accept?
If I accept this certificate, displays reCaptcha code, but if not, I don't view reCaptcha Code.
Can you help me with this?
If you need more information about my code, feel free to ask to me.
Regards.

I think you need to change the url you are using to include recaptcha. A number of people had the same problem in April. Recaptcha let the certificate expire for "api-secure.recaptcha.net". If you change it to use the "https://www.google.com/recaptcha/api/XXX" url instead of "https://api-secure.recaptcha.net/XXX", it should definitely fix your issue.
It looks like this one has actually been answered before: recaptcha https problem on https://api-secure.recaptcha.net/. Since you are using the .NET library, I think your answer is to upgrade your version.

Sharpening up on JasonStoltz's answer:
You are already using the latest DLL version, there's no need to update this
You can/should use RecaptchaControlMvc.GenerateCaptcha() method in your View instead of writing your own (it will use the new URL)

Related

How to read other website data using angular website with backend asp.net c#

I am trying to read other website data using angular website with backend asp.net c#, other website has following login authentication after login need to read the data.
I have following authentical pages
first page i have to enter username
https://i.stack.imgur.com/PgbLo.png
second page i have to enter password then click login
https://i.stack.imgur.com/xAr4E.png
after login it will redirect to home page which content information of person details
https://i.stack.imgur.com/2I4UX.png
I need to display third point page information Name, mobile, and address in my angular website.
Third page url will be looks like : www.xyz.com/1
the above 1 digit in the url is id of information base on id information of third page will appear
I found some code using c# but how to manage logins
System.Net.WebClient wc = new System.Net.WebClient();
byte[] raw = wc.DownloadData("http://www.yoursite.com/resource/file.htm");
string webData = System.Text.Encoding.UTF8.GetString(raw);
and other way
System.Net.WebClient wc = new System.Net.WebClient();
string webData =
wc.DownloadString("http://www.yoursite.com/resource/file.htm");
System.Net.WebClient wc = new System.Net.WebClient();
I would suggest checking if the site you want to get the data from has a public API (it's easier to call, and there is a chance the site has a "No bots" policy, your IP could get banned)
That being said, if you want to automatically log in the site and then get the data, you'll need to use something like Selenium (not an expert on it, but I can give you a link with documentation)
https://www.javatpoint.com/selenium-csharp
Selenium is usually used for automation testing, but it will allow you to simulate user interaction with a site (finding the field input and typing values).
Nos for getting the information, I used HtmlAgilityPack in the past, it is a C# library, that allows you to look for specific elements in a site (using something called XPath, it's easy to learn).
https://html-agility-pack.net/
They have some great documentation, and after you get the results from the site you can just expose it using an API that you can consume from you angular app.
Like Facundo Gallardo said the best way to get data from a website is using the site's API if it has one. If not there isn't much you can do unfortunately.
Using a web browser simulator like selenium could be an option if you were building a desktop application, but for a server it is way too resource intensive. If you were to use it (and I am not even sure you can in a server environment), your server would have to open a new browser like chrome for every user and every time you wanted to scrap data from the other website.
Any other solution that doesn't require you to open a full browser can only scrap static data that require no authentication to be seen
You can use python script to do so. Prepare a python script to automate the login and use the same script in c# to complete the process.
Here are the two links for reference that may be helpfull.
submitting a webform using python
running a python script in c#
For automation purpose with some Webui you will want to use something like https://www.puppeteersharp.com/ .
Most things that you can do manually in the browser can be done using Puppeteer!
Given something like a login screen like
<!DOCTYPE html>
<html>
<body>
<form action="/action_page.php">
<label for="name">name:</label><br>
<input type="text" id="name" name="name"><br>
<label for="password">password:</label><br>
<input type="password" id="password" name="password"><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
The .net code for the login challenge would look like
using PuppeteerSharp;
//Setup puppeteer things
using var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });
await using var page = await browser.NewPageAsync();
//Using https://jsfiddle.net/hwu6bkj0/ as demo web form
await page.GoToAsync("https://jsfiddle.net/hwu6bkj0/");
//Wait for your input element to appear/get loaded. Use the F12/Dev tools of your browser to find out the right query
await Task.Delay(1000);
// JsFiddle specific - getting result iframe
var frameElement = await page.QuerySelectorAsync("iframe[name='result']");
var frame = await frameElement.ContentFrameAsync();
var frameContent = await frame.GetContentAsync();
// Setting values to the input elements
var usenanme = await frame.QuerySelectorAsync("input[name='name']");
await usenanme.TypeAsync("testUserName");
var passsword = await frame.QuerySelectorAsync("input[name='password']");
await passsword.TypeAsync("pa$$word");
var submitButton = await frame.QuerySelectorAsync("input[type='submit']");
await Task.Delay(1000);
await submitButton.ClickAsync();
await Task.Delay(5000);
Headless will be set to true and the "Task.Delay"s should be removed in a final version.
Every following form should work similar.

Braintree: Generate Client Token in ASP.NET MVC 4.5

I'm having some issues integrating Braintree, as well as understanding the concept of how the transaction takes place.
Here's how i currently understand Braintree:
Server Generates ClientToken -> Integrates into html/js -> User receives payment form and sends data to Braintree -> Nonce is sent to Server -> Server sends Transaction to Braintree
Is this correct?
I'm currently on step 1, trying to generate a client token, and i'm getting a NullReferenceException:
public ActionResult Payment(EditContainerViewModel newEdit)
{
//generate client token
newEdit.PaymentInfo.ClientToken = PaymentConstants.Gateway.ClientToken.generate();
return View(newEdit);
}
And heres the Gateway declaration:
public static class PaymentConstants
{
public static BraintreeGateway Gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "id",
PublicKey = "publickey",
PrivateKey = "privatekey"
};
}
Heres my view:
#model Sandbox.Models.EditContainerViewModel
<h2>Payment</h2>
<form id="checkout" method="post" action="/checkout">
<div id="payment-form"></div>
<input type="submit" value="Pay $10">
</form>
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
// We generated a client token for you so you can test out this code
// immediately. In a production-ready integration, you will need to
// generate a client token on your server (see section below).
var clientToken = "#Html.Raw(Model.PaymentInfo.ClientToken)";
braintree.setup(clientToken, "dropin", {
container: "payment-form"
});
</script>
I'd really appreciate any insight on this topic, especially as i found that the provided ASP.NET examples didn't show the token generation stage.
Thank you!
As said in the comment, i was far too focused on Braintree that i made an extremely beginner error. This serves as a great reminder that you can find the answer by just taking a step back and looking at the error from a new perspective. :)

Postback Fails On Default Document

So I've created a Web Application (not Web Site) with ASP.NET (C#) and it compiles just fine in the VS13 environment. But when I publish it on IIS, the Postback on the Default Document fails. The Default Document is called LoginPage.aspx. As soon as I click the <asp:Button> to run my code behind, all it does is refresh the page. This project has been published on my local 127.0.0.1 IP address for the time being.
I know this has been a documented issue, but I've tried many solutions and have not come across a resolution. Some solutions I have attempted:
Creating a brand new Web App with minimal code to attempt accessing any Postback with no success.
I tried the first solution presented here with no success: https://stackoverflow.com/a/7367076/4204026
I also tried URL mappings:
<urlMappings>
<add url="~/login" mappedUrl="~/Views/LoginPage.aspx" />
<add url="~/login/" mappedUrl="~/Views/LoginPage.aspx" />
</urlMappings>
I'm honestly at a loss as to what's happening here. One thing I did notice is when the application is being run through Visual Studio, the <form> tag on the LoginPage.aspx appears in Chrome as:
<form method="post" action="LoginPage" id="ct101" class=".myForm">
Through IIS:
<form method="post" action="./" id="ct101" class=".myForm">
Not sure if that's a problem either. I tried hard-coding the action to login to see what would happen and it does redirect to the correct page, but as suspected no Postback was fired - My Session variable returned null and no query string was used.
Here's the related LoginPage.aspx front-end code (trimmed out a bunch of unrelated HTML):
<%# Page Title="DREW KENNEDY | WELCOME" Language="C#" MasterPageFile="Site.Master" AutoEventWireup="true" CodeBehind="LoginPage.aspx.cs" Inherits="MyMedia.Views.LoginPage" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<!-- form is located on Site.Master -->
<asp:Button OnClick="LoginBtn_Click" CssClass="login" runat="server" name="submit" Text="Sign In" />
</asp:Content>
And the LoginBtn_Click method in LoginPage.aspx.cs:
protected void LoginBtn_Click(object sender, EventArgs e) {
//Tried the following line while commenting out everything else to make sure Postback is being ignored
//Response.Write("<script>alert('Test');</script>");
try {
AbstractPersistenceDecorator decorator = new PersistenceDecorator();
string uname = username.Text.Trim();//username is a TextBox Control
string pass = password.Text.Trim();//password is a TextBox control
bool isCookieRequested = CheckBox.Checked;
if (decorator.authenticate(uname, pass)) {//calling SQL Server for authentication
User AuthenticatedUser = (User)Session["User"] ?? decorator.getUserInfo(uname);
if (Session["User"] == null) Session["User"] = AuthenticatedUser;
if (isCookieRequested) {
HttpCookie cookie = new HttpCookie("username", AuthenticatedUser.Username);
cookie.Expires.AddDays(7);
Response.Cookies.Add(cookie);
} else {
Session.Timeout = 15;
}
Thread.Sleep(1600);
//string redirect = string.Format("dashboard?username={0}", AuthenticatedUser.Username);
Response.Redirect("dashboard?username=" + AuthenticatedUser.Username);
}
} catch (Exception ex) {
//who cares?
}
}
Final pieces of info:
Running IIS 8.0
Application created with 4.5 Framework, Application Pool is also 4.5 Framework
I have ensured that ASP.NET is installed on IIS
I do have URL ReWriting in the global.asax file, though I'm not sure if that is related in any way (I don't see how).
I have no Default.aspx page
EDIT:
Just tested the project through 127.0.0.1 on IE11 and FF with the same result.
EDIT #2:
Additional things I have tried with no success:
I tried removing my URL Rewriting
I tried adding an empty URL Rewrite rule, i.e. ("Empty URL", "", "~/Views/LoginPage.aspx")
Additional notes:
I do not use Telerik
I do not use ISAPI
The project in Visual Studio was set to debug and not release
I apologize for not giving enough information in the OP as I have found the answer. It turns out it had nothing to do with ASP.NET, but rather SQL Server. I stripped the code bare and after adding back one piece of code at a time and stripping away all exception handling, I found through IIS that IIS APPPOOL\.NET vX.X did not have permissions to access the database.
What I had to do is:
In MSQLSM, add a new Login for IIS APPPOOL\.NET v4.5
Further on, I found out that it needed the correct permissions to perform certain commands after receiving the following exception:
The SELECT permission was denied on the object 'X', database 'X', schema 'dbo'
This Was Solved Here
Give that new Login the proper access. Login Properties > User Mapping > checking db_datareader and public.
The code behind now executes. It still leaves the question why it was prohibiting any Postbacks, even if I removed any SQL Connectivity in the code behind. Very strange.
Anyway, thanks to those who helped.
I suggest that you redirect from the default page to the Expected page then this should work. Iis default page handling is done through isapi to handle static content so the post data may not survive

login to ajax web page from c# code

i'm trying to log in a site with username + password through a c# code.
i found out that it uses Ajax to authenticate...
how should i implement such login ?
the elements in the web page doesn't seem to have an "id"...
i tried to implement it using HtmlAgilityPack but i don't think this is the correct direction...
i can't simulate a click button since i don't find "id" for the button.
if (tableNode.Attributes["class"].Value == "loginTable")
{
var userInputNode =
tableNode.SelectSingleNode("//input[#data-logon-popup-form-user-name-input='true']");
var passwordInputNode =
tableNode.SelectSingleNode("//input[#data-logon-popup-form-password-input='true']");
userInputNode.SetAttributeValue("value", "myemail#gmail.com");
passwordInputNode.SetAttributeValue("value", "mypassword");
var loginButton = tableNode.SelectSingleNode("//div[#data-logon-popup-form-submit-btn='true']");
}
This question is quite broad but I'll help you in the general direction:
Use Chrome DevTools (F12) => Network tab => Check the "Preserve Log". An alternative could be Fiddler2
Login manually and look at the request the AJAX sends. Save the endpoint (the URL) and save the Body of the request (the Json data that's in the request with username and password)
Do the post directly in your C# code and forget about HtmlAgilityPack unless you need to actually get some dynamic data from the page, but that's rarely the case
Login with something like this code snippet: POSTing JSON to URL via WebClient in C#
Now you're logged in. You usually receive some data from the server when you're logging in, so save it and use it for whatever you want to do next. I'm guessing it might have some SessionId or some authentication token that your future requests will need as a parameter to prove that you're actually logged in.

How to get ClientCertificate from the request (comparing ASP.NET and Silverlight)

I have a Silverlight Web Application which uses Silverligh-enabled WCF service for getting datas from other Web-Services and Database. In the previous, end users signing in to the web site by writing their UserName and Password to the TextBoxes and clicking button. Now, end users have a card and a card reader. Certification prompt must be appeared after entering the web site. So, I have changed my web service and it uses HTTPS. And in IIS I set SSL Settings to Require for the Web Site. Of course, I have created Web Site certificate also and set the binding's certificate to it. Everything works fine now. The web site and the web service are opening with HTTPS. Also, certification prompt is displaying whenever entering to the Web Site. And after all certificates are shown in the list, user must choose one of them. After that he must enter his password and if data in the certificate store is same with the card in card reader, the webSite is opening.
I have read this article for configuring web Service to use HTTPS.
In ASP.NET we are getting certificate like that:
X509Certificate2 cert = new X509Certificate2(Request.ClientCertificate.Certificate);
string subject = Request.ClientCertificate.Subject;
if (!Request.ClientCertificate.IsValid || Request.ClientCertificate.Count == 0)
{
// failed
}
else
{
Session["isRegistered"] = true;
// success
}
But I dont know how to get certificate from the request with Web Service.
Thanks.
Looks like what the best option for you would be to implement a custom Certificate Validator for your service. This is basically a class that derives from X509CertificateValidator and is then registered through the config file.
There's more complete information on how to do this on this article.
You can find the security context of the WCF request in the System.ServiceModel.OperationContext.Current object, especially in the ServiceSecurityContext field.
I think that, I have solved the problem. I sent ClientCertificate property of request object from Asp.net to Silverlight like that:
<form id="form1" runat="server" style="height:100%">
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
...
<param name="initParams"
value="ClientCertificate=<%=Request.ClientCertificate.Subject %>, cc=true, m=/relative" />
...
</form>
And in App.xaml.cs I am getting values in Application_startup event:
private void Application_Startup(object sender, StartupEventArgs e)
{
if (e.InitParams != null)
{
foreach (var item in e.InitParams)
{
this.Resources.Add(item.Key, item.Value);
}
}
this.RootVisual = new MainPage();
}

Categories