I have a few problems authenticating to a website via Perl.
I can login to the website without any problems using a browser, if I do, it shows me a little prompt, where I have to supply my credentials.
Easy going!
But now I wanted to connect to the site by using the script and I am always running into a 401 unauthorized error.
The server I am trying to connect to runs IIS7 and the WWW-Authenticate header told me, the realm would be something like 'negotiate, NTLM' (I tried all three possibilities, one of the words or both, nothing happened).
So far I really don't know how to figure out what information is needed, my last try was to get the form, where I have to supply the credentials and then use the submit_form function, but to get the forms, I have to establish the connection.
I am really confused because I tried most of the things I found on google, but I don't know what is going on, especially from the technical view, which could give me a hint.
Well, I would really appreciate it, if someone could help me and I thank you in advance for doing it.
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use WWW::Mechanize;
use Authen::NTLM;
my $url = "some.url";
my $usr = 'bernd';
my $pwd = 'bernd';
my $mech = WWW::Mechanize->new(ssl_opts => {verify_hostname => 0});
$mech -> credentials($url.":443","NTLM",$usr,$pwd);
$mech->get("https://".$url); #added the https, because $url doesn't have it
print $mech->forms;
PS:
The bypassing of ssl verification was due to a certificate problem I had at the beginning.
I speculate that in your use of the 4 parameter form of the credentials method, the netloc and user are wrong.
When the URL is https://www.example.com/foo/bar?quux;baz=42#fnord, the netloc is www.example.com:443.
The user is a string of the NTLM domain, a single backslash, and the NTLM username, e.g. internal\bernd. Mind that if you hardcode that value as a string literal as you did in the example, you need to escape the backslash with a backslash.
Check for these possible errors.
Alright, the problem is not a script or Perl problem as it seems, some of the developers of the site did a really shitty job with the permissions, so you have to be authorized to view everything else, in order to view the single site and the service account I were told to use, does not have this permissions.
Very sad, but thanks for the help so far!
Related
Bellow is a script which grabs a cookie from "example.com" and encodes it base64,
It usually works, although for some reason I will have random days where it acts up and does not grab any cookies at all.
I've checked myself at times where the script was failing, and the site would still send a cookie to the client.
Same method, nothing changed on the sites behalf, and nothing would change on the script, though it would still just act up some times.
Anyone know what this could possibly be?
Do I have to change my method of grabbing cookies incase this method may be obsolete or ancient?
my $ua = new LWP::UserAgent;
$ua->cookie_jar({});
use Data::Dumper;
$ua->get("http://www.example.com");
my $cookie = encode_base64($ua->cookie_jar->as_string);
Other info: It's apart of a perl cgi script, hosted on a website.
I'm still unsure of the error thats causing this, Although, when I had turned off "CloudFlare" for my website, the problem resolved itself immediately.
Oh well there goes 3 hours of my life over CloudFlare...
I am trying to access Soundcloud from a local HTML page on my laptop. I am stuck at the part of hosting "callback.html" as a redirect_uri. The script I am trying to run is the basic Authenication JavaScript from the Soundcloud documentation page:
<script src="http://connect.soundcloud.com/sdk.js"></script>
<script>
// initialize client with app credentials
SC.initialize({
client_id: 'my_client_id',
redirect_uri: 'http://127.0.0.1/Users/Maria/Documents/SoundcloudClient/callback.html'
});
// initiate auth popup
SC.connect(function() {
SC.get('/me', function(me) {
alert('Hello, ' + me.username);
});
});
</script>
This script gets me to the connect pop-up when I launch the page in Chrome and Firefox.
But, once I have logged in as a Soundcloud user, I get the following error:
Oops! Google Chrome could not connect to 127.0.0.1
If I change my redirect_uri to localhost I get the same error.
If I try:
files:///C:/Users/Maria/Documents/SoundcloudThinClient/callback.html
I get a similar error.
I also tried:
ocalhost:3000
and:
localhost:8080
even though I'm not sure what would be listening on those ports.
So, basically, I'm asking what path do I put for callback.html in order for this to work?
I confess I don't know how the redirct_uri actually functions. I looked at the Oauth pages for it, but I don't understand them. I am beginning to think that I can't simply create an HTML page, paste the JavaScript, create a callback.html file and have this work, even though the SC documentation seems to say that this is possible. If so, what steps am I missing?
I am beginning to attempt this. I believe you have to go to the developer site and sign up as having an app. The redirect uri is asked for and the form gives you an API key you can use in your app.
I'm using drupal so, perhaps adding the oath module and using Php to add the api key might work well.
I had the same problem and I think I solved it.
Morning-after-edit: I posted this dead-tired after working towards a solution through the night. Now, the day after, I realize that you were speaking about the general problem, whereof I face a very particular instance. The following only applies directly to registering soundcloudlabs' soundcloud-group-recorder: https://github.com/soundcloudlabs/soundcloud-group-recorder. There is probably a more general principle lurking behind there, though:
First: yes, you do have to register the app as your own at Soundcloud. At least I presumed so. And doing that, you must register correctly where on your server you will place the callback.html file. Take the ClientID assigned to your app and use that in the API intialize procedure.
Now, I'm a novice and know very little coding. But I started looking around in the main file, application.js.
At the top of the file there are two instances of client_id and redirect_uri each. I'm not sure if that serves a purpose or if one is technically superfluous. Through trial and error I found out that replacing the second instance of each with my own data worked.
Then there is groupId and groupUrl, both of which should contain your info, within quotation marks.
After a lot of trial and error, still having trouble getting the thing to run, I looked around and saw that, whereas early in the file, client_id was hooked within SC.initialize, redirect_uri was not. Under the line:
client_id: CLIENT_ID
I added:
redirect_uri: REDIRECT_URI
– with a customary comma in between. And that's it. It runs.
I have built a CGI::Application currently running on local host and have used 2 authentication methods -
1. descried in http://www.perlmonks.org/?node_id=622071 by storing user password in database and
2. using LDAP credentials.
I was looking for a simple way to do google authentication but haven't found an easy way yet. Can someone point me in the right direction.
I looked at
1. Authen-GoogleAccount and
2. net-Google-FederatedLogin
but not enough documentation for either of these. Where do i start? Please let me know even if you have some pointer to doing this outside of cgi::application
This is the closest solution I could find. I am not a security expert, but I don't think websites serious about it would use this method. It uses WWW::Mechanize to authenticate using google email/password and then pull secure content out.
http://gregjessup.com/login-to-google-using-perl/
if $mech->get($url); returns error, authentication failed.
Here's the code I used for the Android Market for Developers (market.android.com/publish):
use WWW::Mechanize;
use HTTP::Cookies;
my $url = 'https://www.google.com/accounts/ServiceLogin';
my $username = 'username#gmail.com';
my $password = "PASSWORD";
my $mech = WWW::Mechanize->new();
$mech->cookie_jar(HTTP::Cookies->new());
$mech->get($url);
$mech->form_number(1);
$mech->field(Email => $username);
$mech->field(Passwd => $password);
$mech->click();
# Go to the next link, now that we are logged in.
$url = 'https://market.android.com/publish/Home';
$mech->get($url);
print $mech->content();
It's a small edit/cleanup of the link Prateek posted: http://gregjessup.com/login-to-google-using-perl.
I think it should be able to be used for most of Google's services that require you to be logged in.
Working from the Bugzilla API, I've written a quick Perl script to clone a Bugzilla Product (recreating all the Components under their new Product). The Bugzilla Perl API is quite easy to use from the command line. I could have just worked on the database directly, but I wanted a longer-term solution. Another option was the webservice, but I thought I'd try using the API directly this time.
The one problem I'm running into is authenticating as my Bz admin user so I can create the new components. Looking at Bugzilla's Bugzilla.pm file, I see that they just run login() from a Bugzilla::Auth object. I'm not sure how to get the username and password in there. I suppose I could just add the script to the Bugzilla admin interface...
Can any of you point me in the right direction?
Oh, I'm being rather ignorant today, I focused on "web services" and didn't understand what you really wanted.
If you're just using the API to communicate with the database (as opposed to manipulating the database directly), do you really need to authenticate as any user at all?
In the 3.2 source tree, look at merge-users.pl for instance, which uses Bugzilla::User objects. Couldn't you do the same with Bugzilla::Component?
You should also look at sanitycheck.pl, which uses Bugzilla->set_user.
There's been some significant upgrades in the web services capabilities since 3.2, can you upgrade?
In 3.6 at least, check out contrib/bz_webservice_demo.pl for how to use the User.login method.
http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/User.html
The following code snippet might enter the question.
Here we check also that the user has the correct "editcomponents" credential.
my $user = new Bugzilla::User({ name => $login })
|| ThrowUserError('invalid_username', { name => $login });
# Authenticate using this user account.
Bugzilla->set_user($user);
$user->in_group('editcomponents')
|| ThrowUserError("auth_failure", {group => "editcomponents",
action => "add",
object => "products"});
Based on this question I asked earlier on setting up cookies in Perl, I successfully got an answer and way to do this but am now faced with a new interesting challenge.
In Perl CGI scripts, it demands you setup a cookie on the header statement which ought to be the first statement in your script. To clarify, you need to have a CGI->header() statement at the top of your script for the CGI script to work!
My scenario:
I have a login screen with a user name and password, upon successful login I need to setup a cookie with the current user name, then redirect the user to another form that checks if the cookie is set before allowing any transactions.
Please note if I set the cookie after the CGI->header() statement, it never get set, and if I set it at the top of my script, it has a bogus value for obvious reasons (user has not logged in)
How do I achieve this? does the CGI->header() statement need to be at the top of my script always?
Gath
Your assertion is wrong: print CGI->header can appear anywhere in your script. However, headers must be output once and only once and before any other output is emitted.
For your purposes, I would recommend using CGI::Application along with CGI::Session (via CGI::Application::Plugin::Session).
You're gonna end up writing yourself some code that can be hijacked if you keep heading in that direction, given your current level of knowledge ("just enough to be dangerous").
I'd suggest reading my article on how to "brand" a browser using cookies. It's an oldie-but-a-goodie.
For the impatient, the trick is to use a cookie only to distinguish one browser from another, and keep everything important as server-side state.