HTTPS/Authenticated: Difference between revisions
(PowerShell added) |
(Added BaCon version.) |
||
Line 22: | Line 22: | ||
#Include COM.ahk |
#Include COM.ahk |
||
#Include COMinvokeDeep.ahk</lang> |
#Include COMinvokeDeep.ahk</lang> |
||
=={{header|BaCon}}== |
|||
<lang bacon>OPTION TLS TRUE |
|||
CONST Connect_Timeout = 2000 |
|||
website$ = "chiselapp.com" |
|||
username$ = "nobody" |
|||
password$ = "ignore" |
|||
OPEN website$ & ":443" FOR NETWORK AS connection |
|||
SEND "GET /user/bacon/repository/bacon/index HTTP/1.1\r\nHost: " & website$ & "\r\nAuthorization: Basic " & B64ENC$(username$ & ":" & password$) & "\r\n\r\n" TO connection |
|||
WHILE WAIT(connection, Connect_Timeout) |
|||
RECEIVE data$ FROM connection |
|||
total$ = total$ & data$ |
|||
IF INSTR(data$, "</html>") THEN BREAK |
|||
WEND |
|||
CLOSE NETWORK connection |
|||
PRINT total$</lang> |
|||
=={{header|C}}== |
=={{header|C}}== |
Revision as of 17:16, 22 August 2020
You are encouraged to solve this task according to the task description, using any language you may know.
The goal of this task is to demonstrate HTTPS requests with authentication. Implementations of this task should not use client certificates for this: that is the subject of another task.
AutoHotkey
<lang AutoHotkey>iWeb_Init() pwb := iWeb_newGui(0, 0, 1000, 800) iWeb_nav(pwb, "http://www.facebook.com/login.php?ref=pf") iWeb_Term() iWeb_complete(pwb) inputbox, email, email inputbox, pass, password iWeb_setDomObj(pwb,"Email",email) iWeb_setDomObj(pwb,"pass",pass) iWeb_clickDomObj(pwb, "login") return
- Include iweb.ahk
- Include COM.ahk
- Include COMinvokeDeep.ahk</lang>
BaCon
<lang bacon>OPTION TLS TRUE
CONST Connect_Timeout = 2000 website$ = "chiselapp.com" username$ = "nobody" password$ = "ignore"
OPEN website$ & ":443" FOR NETWORK AS connection
SEND "GET /user/bacon/repository/bacon/index HTTP/1.1\r\nHost: " & website$ & "\r\nAuthorization: Basic " & B64ENC$(username$ & ":" & password$) & "\r\n\r\n" TO connection
WHILE WAIT(connection, Connect_Timeout)
RECEIVE data$ FROM connection total$ = total$ & data$ IF INSTR(data$, "</html>") THEN BREAK
WEND
CLOSE NETWORK connection PRINT total$</lang>
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include "curl/curl.h"
int main(void) {
CURL *curl; char buffer[CURL_ERROR_SIZE];
if ((curl = curl_easy_init()) != NULL) { curl_easy_setopt(curl, CURLOPT_URL, "https://user:password@secure.example.com/"); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer); if (curl_easy_perform(curl) != CURLE_OK) { fprintf(stderr, "%s\n", buffer); return EXIT_FAILURE; } curl_easy_cleanup(curl); } return EXIT_SUCCESS;
}</lang>
C#
<lang csharp> using System; using System.Net;
class Program {
static void Main(string[] args) { var client = new WebClient();
// credentials of current user: client.Credentials = CredentialCache.DefaultCredentials; // or specify credentials manually: client.Credentials = new NetworkCredential("User", "Password");
var data = client.DownloadString("https://example.com");
Console.WriteLine(data); }
} </lang>
Clojure
<lang clojure>(clj-http.client/get "https://somedomain.com"
{:basic-auth ["user" "pass"]})</lang>
Delphi
<lang Delphi>program ShowHTTPSAuthenticated;
{$APPTYPE CONSOLE}
uses IdHttp, IdSSLOpenSSL;
var
s: string; lHTTP: TIdHTTP; lIOHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
ReportMemoryLeaksOnShutdown := True; lHTTP := TIdHTTP.Create(nil); lIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); try lHTTP.Request.Username := 'USERNAME'; lHTTP.Request.Password := 'PASSWD'; lHTTP.IOHandler := lIOHandler; lHTTP.HandleRedirects := True; s := lHTTP.Get('https://SomeSecureSite.net/'); Writeln(s); finally lHTTP.Free; lIOHandler.Free; end;
end.</lang>
Go
The task solution is really the client program, but to test it I wrote a server and created a custom certificate. I won't describe the certificate, but this is the server: <lang go>package main
import (
"encoding/base64" "io" "log" "net/http" "strings"
)
const userPass = "rosetta:code" const unauth = http.StatusUnauthorized
func hw(w http.ResponseWriter, req *http.Request) {
auth := req.Header.Get("Authorization") if !strings.HasPrefix(auth, "Basic ") { log.Print("Invalid authorization:", auth) http.Error(w, http.StatusText(unauth), unauth) return } up, err := base64.StdEncoding.DecodeString(auth[6:]) if err != nil { log.Print("authorization decode error:", err) http.Error(w, http.StatusText(unauth), unauth) return } if string(up) != userPass { log.Print("invalid username:password:", string(up)) http.Error(w, http.StatusText(unauth), unauth) return } io.WriteString(w, "Goodbye, World!")
}
func main() {
http.HandleFunc("/", hw) log.Fatal(http.ListenAndServeTLS(":8080", "cert.pem", "key.pem", nil))
}</lang> It is a "Hello world" server, but over TLS and with basic authentication required on the Get. Errors are logged to aid client debugging.
The client: <lang go>package main
import (
"crypto/tls" "crypto/x509" "fmt" "io/ioutil" "log" "net/http"
)
const (
userid = "rosetta" password = "code"
)
func main() {
// Use custom certificate for testing. Not exactly required by task. b, err := ioutil.ReadFile("cert.pem") if err != nil { log.Fatal(err) } pool := x509.NewCertPool() if ok := pool.AppendCertsFromPEM(b); !ok { log.Fatal("Failed to append cert") } tc := &tls.Config{RootCAs: pool} tr := &http.Transport{TLSClientConfig: tc} client := &http.Client{Transport: tr} req, err := http.NewRequest("GET", "https://127.0.0.1:8080", nil) if err != nil { log.Fatal(err) }
// This one line implements the authentication required for the task. req.SetBasicAuth(userid, password)
// Make request and show output. resp, err := client.Do(req) if err != nil { log.Fatal(err) } b, err = ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { log.Fatal(err) } fmt.Println(string(b))
}</lang>
Haskell
Example uses the req and aeson packages:
<lang haskell>{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Data.Aeson (Value) import Data.Default.Class (def) import Network.HTTP.Req
( (/:) , GET(..) , NoReqBody(..) , basicAuth , https , jsonResponse , req , responseBody , runReq )
main :: IO () main = do
response <- runReq def $ req GET (https "httpbin.org" /: "basic-auth" /: "someuser" /: "somepassword") NoReqBody jsonResponse (basicAuth "someuser" "somepassword") print (responseBody response :: Value)</lang>
Julia
An example using HTTP (see the source for HTTP.jl for the code below ) to access and play a song: <lang Julia> using HTTP, HTTP.IOExtras, JSON, MusicProcessing HTTP.open("POST", "http://music.com/play") do io
write(io, JSON.json([ "auth" => "12345XXXX", "song_id" => 7, ])) r = startread(io) @show r.status while !eof(io) bytes = readavailable(io) play(bytes) end
end </lang>
Kotlin
<lang scala>// version 1.2.0
import java.net.Authenticator import java.net.PasswordAuthentication import javax.net.ssl.HttpsURLConnection import java.net.URL import java.io.InputStreamReader import java.io.BufferedReader
object PasswordAuthenticator : Authenticator() {
override fun getPasswordAuthentication() = PasswordAuthentication ("username", "password".toCharArray())
}
fun main(args: Array<String>) {
val url = URL("https://somehost.com") val con = url.openConnection() as HttpsURLConnection Authenticator.setDefault(PasswordAuthenticator) con.allowUserInteraction = true con.connect() val isr = InputStreamReader(con.inputStream) val br = BufferedReader(isr) while (true) { val line = br.readLine() if (line == null) break println(line) }
}</lang>
Lasso
<lang Lasso>local(username = 'hello',password = 'world') local(x = curl('https://sourceforge.net'))
- x->set(CURLOPT_USERPWD, #username + ':' + #password)
local(y = #x->result)
- y->asString</lang>
LiveCode
HTTP Basic Auth as part of url <lang LiveCode>command getAuthWebResource
libURLFollowHttpRedirects true libURLSetSSLVerification true put URL "https://user:passwd@example.basicauth.com/" into response put response
end getAuthWebResource</lang>
You can also set the headers for the basic auth requests <lang LiveCode>command getAuthWebResource
libURLFollowHttpRedirects true libURLSetSSLVerification true set the httpHeaders to "Authorization: Basic " && base64Encode("user:passwd") put URL "https://example.basicauth.com" into response put response
end getAuthWebResource</lang>
Lua
<lang lua> local requests = require('requests') local auth = requests.HTTPBasicAuth('admin', 'admin') local resp, e = requests.get({
url = 'https://httpbin.org/basic-auth/admin/admin', auth = auth
}) io.write(string.format('Status: %d', resp.status_code)) </lang>
- Output:
Status: 200
Mathematica / Wolfram Language
<lang Mathematica>a = RunThrough["curl -u JohnDoe:Password https://www.example.com", 1] For[ i=0, i < Length[a] , i++, SomeFunction[a]]</lang>
Perl
<lang perl>use LWP::UserAgent qw(); my $ua = LWP::UserAgent->new; my $netloc = 'http://www.buddhism-dict.net/cgi-bin/xpr-dealt.pl:80'; $ua->credentials(
$netloc, 'CJK-E and Buddhist Dictionaries', # basic realm 'guest', # user , # empty pw
); my $response = $ua->get($netloc);
use WWW::Mechanize qw(); my $mech = WWW::Mechanize->new; $mech->get('https://login.yahoo.com/'); $mech->submit_form(with_fields => {
login => 'XXXXXX', passwd => 'YYYYYY', '.persistent' => 'y', # tick checkbox
});</lang>
Phix
Exactly the same as the HTTP#Phix task. You can of course use curl_easy_setopt(curl,CURLOPT_USERPWD,"user:password") rather than embed that in the url. <lang Phix>include builtins\libcurl.e curl_global_init() atom curl = curl_easy_init() curl_easy_setopt(curl, CURLOPT_URL, "https://user:password@example.com/") object res = curl_easy_perform_ex(curl) curl_easy_cleanup(curl) curl_global_cleanup()
puts(1,res)</lang>
PicoLisp
<lang PicoLisp>(let (User "Bill" Pass "T0p5ecRet" Url "https://www.example.com")
(in (list 'curl "-u" (pack User ': Pass) Url) (while (line) (doSomeProcessingWithLine @) ) ) )</lang>
PowerShell
<lang PowerShell>$client = [Net.WebClient]::new()
- credentials of current user:
$client.Credentials = [Net.CredentialCache]::DefaultCredentials
- or specify credentials manually:
- $client.Credentials = [System.Net.NetworkCredential]::new("User", "Password")
$data = $client.DownloadString("https://example.com") Write-Host $data</lang>
Python
Note: You should install mechanize to run code below. Visit: http://wwwsearch.sourceforge.net/mechanize/
<lang python>#!/usr/bin/python
- -*- coding: utf-8 -*-
from mechanize import Browser
USER_AGENT = "Mozilla/5.0 (X11; U; Linux i686; tr-TR; rv:1.8.1.9) Gecko/20071102 Pardus/2007 Firefox/2.0.0.9"
br = Browser() br.addheaders = [("User-agent", USER_AGENT)]
- remove comment if you get debug output
- br.set_debug_redirects(True)
- br.set_debug_responses(True)
- br.set_debug_http(True)
br.open("https://www.facebook.com")
br.select_form("loginform") br['email'] = "xxxxxxx@xxxxx.com" br['pass'] = "xxxxxxxxx" br['persistent'] = ["1"]
response = br.submit() print response.read()</lang>
<lang python>import requests
username = "user" password = "pass" url = "https://www.example.com"
response = requests.get(url, auth=(username, password)
print(response.text)</lang>
Racket
<lang racket>
- lang racket
(require net/url net/url-connect openssl)
(module+ main
(parameterize ([current-https-protocol (ssl-make-client-context)]) (ssl-set-verify! (current-https-protocol) #t)
;; When this is #f, we correctly get an exception: ;; error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (when #t (ssl-load-verify-source! (current-https-protocol) '(directory ;; This location works on Debian 6; ;; adjust as needed for your platform. "/etc/ssl/certs" )))
(for ([l (in-port read-line (get-pure-port (string->url "https://www.google.com/")))]) (displayln l))))
</lang>
Raku
(formerly Perl 6)
Used here to connect to my local wireless router to a page that is password protected. Obviously not going to be generally publicly accessible but should be easily adaptable to other sites / devices.
<lang perl6>use HTTP::UserAgent;
my $username = 'username'; # my username my $password = 'password'; # my password my $address = 'http://192.168.1.1/Status_Router.asp'; # my local wireless router
my $ua = HTTP::UserAgent.new; $ua.auth( $username, $password ); my $response = $ua.get: $address; say $response.is-success ?? $response.content !! $response.status-line;</lang>
Ruby
<lang ruby>require 'uri' require 'net/http'
uri = URI.parse('https://www.example.com') response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new uri request.basic_auth('username', 'password') http.request request
end</lang>
Run BASIC
<lang runbasic>html "
LOGIN | |
UserName | "
TEXTBOX #userName, ""html " |
Password: | "
PasswordBox #passWord, "" html " |
"
button #si, "Signin", [doSignin] html " " button #ex, "Exit", [exit] html " |
WAIT
[doSignin] loginUserName$ = trim$(#userName contents$()) loginPassWord$ = trim$(#passWord contents$()) if (loginUserName$ = "admin" and loginPassWord$ = "admin" then
print "Login ok" else print "invalid User or Pass" cls goto [loop]
end if
print Platform$ ' OS where Run BASIC is being hosted print UserInfo$ ' Information about the user's web browser print UserAddress$ ' IP address of the user
Scala
<lang Scala>import java.net.{Authenticator, PasswordAuthentication, URL}
import javax.net.ssl.HttpsURLConnection
import scala.io.BufferedSource
object Authenticated extends App {
val con: HttpsURLConnection = new URL("https://somehost.com").openConnection().asInstanceOf[HttpsURLConnection]
object PasswordAuthenticator extends Authenticator { override def getPasswordAuthentication = new PasswordAuthentication("username", "password".toCharArray) }
Authenticator.setDefault(PasswordAuthenticator) con.setAllowUserInteraction(true) con.connect()
new BufferedSource(con.getInputStream).getLines.foreach(println(_))
}</lang>
Sidef
<lang ruby>require('WWW::Mechanize')
var mech = %s'WWW::Mechanize'.new(
cookie_jar => Hash.new, agent => 'Mozilla/5.0',
)
mech.get('https://login.yahoo.com/') mech.submit_form(
form_id => 'mbr-login-form', # form id fields => Hash.new( 'login' => 'XXXXXX', 'passwd' => 'YYYYYY',
))</lang>
Tcl
for thebinary encode
subcommand, otherwise uses
Uses the Tls package. <lang Tcl>package require http package require tls http::register https 443 ::tls::socket
- Generate the authentication
set user theUser set pass thePassword dict set auth Authenticate "Basic [binary encode base64 ${user}:${pass}]"
- Make a secure authenticated connection
set token [http::geturl https://secure.example.com/ -headers $auth]
- Now as for conventional use of the “http” package
set data [http::data $token] http::cleanup $token</lang>
Visual Basic
<lang vb>Sub Main() ' in the "references" dialog of the IDE, check ' "Microsoft WinHTTP Services, version 5.1" (winhttp.dll) Dim HttpReq As WinHttp.WinHttpRequest Const WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 As Long = &H80& Const WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 As Long = &H200& Const WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 As Long = &H800& Const HTTPREQUEST_PROXYSETTING_PROXY As Long = 2
- Const USE_PROXY = 1
Set HttpReq = New WinHttp.WinHttpRequest HttpReq.Open "GET", "https://www.abc.com/xyz/index.html" HttpReq.Option(WinHttpRequestOption_SecureProtocols) = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 Or _ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 Or _ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 HttpReq.SetCredentials "<username>", "<password>", 0&
- If USE_PROXY Then
HttpReq.SetProxy HTTPREQUEST_PROXYSETTING_PROXY, "10.167.1.1:80"
- End If
HttpReq.SetTimeouts 1000, 1000, 1000, 1000 HttpReq.Send Debug.Print HttpReq.ResponseText
End Sub</lang>
zkl
Using cURL to do the heavy lifting, get a XML list of computers connected to my router. <lang zkl>zkl: var ZC=Import("zklCurl") zkl: var data=ZC().get("http://usr:pw@192.168.1.1/computer_list.xml") L(Data(1,049),121,0) zkl: data[0][121,*].text</lang>
- Output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <computers> <ip_address0>192.168.1.100</ip_address0><host_name0>core-shot ...
- Programming Tasks
- Networking and Web Interaction
- AutoHotkey
- Iweb
- COM
- BaCon
- C
- Libcurl
- C sharp
- Clojure
- Clj-http
- Delphi
- Go
- Haskell
- Julia
- Kotlin
- Lasso
- LiveCode
- Lua
- Lua-requests
- Mathematica
- Wolfram Language
- Perl
- LWP
- Phix
- PicoLisp
- PowerShell
- Python
- Requests
- Racket
- Raku
- Ruby
- Run BASIC
- Scala
- Sidef
- Tcl
- Tcllib
- Visual Basic
- Microsoft.WinHttp
- Zkl
- Batch File/Omit
- Brainf***/Omit
- Commodore BASIC/Omit
- Inform 7/Omit
- Locomotive Basic/Omit
- Lotus 123 Macro Scripting/Omit
- M4/Omit
- Maxima/Omit
- ML/I/Omit
- Openscad/Omit
- PARI/GP/Omit
- PostScript/Omit
- Retro/Omit
- SQL PL/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- Unlambda/Omit
- Yorick/Omit
- ZX Spectrum Basic/Omit