code

GitHub API에서 기본 인증을 위해 사용자 이름 및 비밀번호와 함께 Invoke-WebRequest 사용

codestyles 2020. 8. 13. 23:24
반응형

GitHub API에서 기본 인증을 위해 사용자 이름 및 비밀번호와 함께 Invoke-WebRequest 사용


초기 질문

cURL을 사용하면 다음과 같이 HTTP 웹 요청과 함께 사용자 이름을 전달할 수 있습니다.

$ curl -u <your_username> https://api.github.com/user

-u플래그는 인증을위한 사용자 이름을 받아, 다음 컬 암호를 요청합니다. cURL 예제는 GitHub Api를 사용한 기본 인증입니다 .

Invoke-WebRequest와 함께 사용자 이름과 암호를 어떻게 유사하게 전달합니까? 궁극적 인 목표는 GitHub API에서 기본 인증을 사용하여 PowerShell을 사용하는 것입니다.

편집 (이것은 작동 한 것입니다)

메모는 클라이언트 측의 기본 인증에 대한 Wikipedia에서 가져온 것 입니다.

사용자 이름과 비밀번호를 단일 문자열로 결합 username:password

$user = "shaunluttin"
$pass = "super-strong-alpha-numeric-symbolic-long-password"
$pair = "${user}:${pass}"

76 자 / 줄로 제한되지 않는 경우를 제외하고 Base64의 RFC2045-MIME 변형으로 문자열을 인코딩합니다.

$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)

인증 값을 메서드, 공백, 인코딩 된 쌍으로 만듭니다. Method Base64String

$basicAuthValue = "Basic $base64"

헤더 만들기 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

$headers = @{ Authorization = $basicAuthValue }

웹 요청 호출

Invoke-WebRequest -uri "https://api.github.com/user" -Headers $headers

도움을 주신 @briantist에게 감사드립니다!

토론

이것의 PowerShell 버전은 cURL 버전보다 더 장황합니다. 왜 그런 겁니까? @briantist는 GitHub가 RFC를 깨고 있고 PowerShell이이를 고수하고 있다고 지적했습니다. 그것은 cURL도 표준을 위반하고 있음을 의미합니까?


여기서 기본 인증을 가정하고 있습니다.

$cred = Get-Credential
Invoke-WebRequest -Uri 'https://whatever' -Credential $cred

다른 수단 ( Import-Clixml등)을 통해 자격 증명을 얻을 수 있지만 [PSCredential]객체 여야 합니다.

댓글에 따라 수정 :

GitHub는 제공된 링크 에서 설명하는대로 RFC를 중단 합니다 .

API는 약간의 차이를 제외하고 RFC2617에 정의 된 기본 인증을 지원합니다. 주요 차이점은 RFC가 401 Unauthorized 응답으로 응답하기 위해 인증되지 않은 요청을 요구한다는 것입니다. 많은 곳에서 이것은 사용자 데이터의 존재를 공개합니다. 대신 GitHub API는 404 Not Found로 응답합니다. 이로 인해 401 Unauthorized 응답을 가정하는 HTTP 라이브러리에 문제가 발생할 수 있습니다. 해결책은 Authorization 헤더를 수동으로 만드는 것입니다.

Powershell Invoke-WebRequest은 자격 증명을 보내기 전에 401 응답을 기다립니다. GitHub는 자격 증명을 제공하지 않으므로 자격 증명이 전송되지 않습니다.

수동으로 헤더 작성

대신 기본 인증 헤더를 직접 만들어야합니다.

기본 인증은 콜론으로 구분 된 사용자 이름과 암호로 구성된 문자열을 user:pass가져온 다음 Base64로 인코딩 된 결과를 보냅니다.

다음과 같은 코드가 작동합니다.

$user = 'user'
$pass = 'pass'

$pair = "$($user):$($pass)"

$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))

$basicAuthValue = "Basic $encodedCreds"

$Headers = @{
    Authorization = $basicAuthValue
}

Invoke-WebRequest -Uri 'https://whatever' -Headers $Headers

일부 문자열 연결을 결합 할 수 있지만 더 명확하게하기 위해 분리하고 싶었습니다.


이것을 사용하십시오 :

$root = 'REST_SERVICE_URL'
$user = "user"
$pass= "password"
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)

$result = Invoke-RestMethod $root -Credential $credential

Invoke-WebRequest@briantist가 언급했듯이 RFC2617을 따르지만 Authorization헤더가없는 경우 익명 사용을 허용 하지만 401 Forbidden헤더에 잘못된 자격 증명이 포함 된 경우 응답하는 일부 시스템 (예 : JFrog Artifactory)이 있습니다.

이것은 401 Forbidden응답 을 트리거하고 -Credentials작업을 시작 하는 데 사용할 수 있습니다 .

$login = Get-Credential -Message "Enter Credentials for Artifactory"

                              #Basic foo:bar
$headers = @{ Authorization = "Basic Zm9vOmJhcg==" }  

Invoke-WebRequest -Credential $login -Headers $headers -Uri "..."

이렇게하면 처음에 잘못된 헤더가 전송되며 헤더를 -Credentials재정의하므로 두 번째 요청에서 유효한 자격 증명으로 대체됩니다 Authorization.

Powershell 5.1로 테스트 됨


I had to do this to get it to work:

$pair = "$($user):$($pass)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Pair))
$headers = @{ Authorization = "Basic $encodedCredentials" }
Invoke-WebRequest -Uri $url -Method Get -Headers $headers -OutFile Config.html

another way is to use certutil.exe save your username and password in a file e.g. in.txt as username:password

certutil -encode in.txt out.txt

Now you should be able to use auth value from out.txt

$headers = @{ Authorization = "Basic $((get-content out.txt)[1])" }
Invoke-WebRequest -Uri 'https://whatever' -Headers $Headers

참고URL : https://stackoverflow.com/questions/27951561/use-invoke-webrequest-with-a-username-and-password-for-basic-authentication-on-t

반응형