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


127

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

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

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

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


$ pair는 $pair = "$($user):$($pass)"승인 된 답변을 확인 해야합니다 . 나는 위의를 사용하고 있었다 그것은 나에게 너무 많은 고통을 준
Bhavjot을

-Credential접근 방식 을 제안하는 솔루션 은 요청이 생성 될 때 올바른 인증 헤더로 작동하지 않습니다.
StingyJack

@Shaun Luttin-이것은 질문 답변 사이트가 아닌 질문 ..... 및 답변 사이트입니다. 이 한 사용자는 특정 상황에서 효과가 있었던 것 이외의 가능한 질문과 답변으로 간결한 것을 보는 것을 선호하지만 두 번 읽을 필요는 없습니다 (편집 된 질문에서 한 번은 QuestionAnswer가 나온 다음 다시 답변에서 다시 표시됨). 문제가 질문에 가장 근접하지 않은 데 도움이 된 답변 인 경우 StackExchange는 이미 질문에 최대한 가깝게 최상의 / 허용 된 답변을 제공하는 기능을 제공합니다.
user66001

1
@ user66001 피드백에 감사드립니다. 나중에 참조 할 수 있도록 질문에 대한 답변을 자체 답변으로 옮겼습니다. 나는 이것이 개선이라고 생각합니다.
Shaun Luttin

@ShaunLuttin-좋은 생각입니다! :)
user66001

답변:


147

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

$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

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


1
내가 말했듯이 기본 인증에서 작동하지만 GitHub API가 어떤 종류의 인증을 사용하는지 모르겠습니다. 예상되는 사항에 대한 세부 정보를 게시하면 문제 해결에 도움이 될 수 있습니다.
briantist

1
아, GitHub는 RFC를 따르지 않지만 Powershell은 따르고 있습니다. 자세한 정보와 해결 방법으로 답변을 편집했습니다.
briantist

1
예, 이런 종류의 호출을 많이한다면 함수로 래핑하는 것이 좋습니다. 내가 말했듯이 나는 명확성을 위해 모든 조각을 나눴지만 한 줄로 모두 할 있습니다 (지저분 할 것입니다).
briantist

1
@Aref, 사용중인 코드로 새 질문을 게시해야합니다. 그렇게하시면 제가 한 번 살펴 보도록하겠습니다.
briantist

1
수동 너무 비주얼 스튜디오 팀 서비스 REST API에 대한 인증을 시도하는 경우 헤더를 구축해야합니다
브렌트 로빈슨

44

이것을 사용하십시오 :

$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

어떤 이유로 TFS vNext에서 사용할 때 선택한 답변이 작동하지 않았지만 이것은 트릭을 수행했습니다. 감사합니다!
Tybs

선택한 답변은 azure에서 powershell runbook을 실행하여 트리거 된 작업을 시작하는 데 작동하지 않았지만이 답변은 작동했습니다.
Sam

7

나는 그것을 작동시키기 위해 이것을해야했다.

$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

6

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로 테스트 됨


5

누군가가 하나의 라이너가 필요한 경우 :

iwr -Uri 'https://api.github.com/user' -Headers @{ Authorization = "Basic "+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("user:pass")) }

2

또 다른 방법은 certutil.exe를 사용하여 사용자 이름과 암호를 파일에 저장하는 것입니다 (예 : in.txt 사용자 이름 : 암호).

certutil -encode in.txt out.txt

이제 out.txt의 인증 값을 사용할 수 있습니다.

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

2

나는 이것이 OPs 원래 요청에서 약간 벗어난 것을 알고 있지만 기본 인증이 필요한 사이트에 대해 Invoke-WebRequest를 사용하는 방법을 찾는 동안 이것을 발견했습니다.

차이점은 스크립트에 암호를 기록하고 싶지 않다는 것입니다. 대신 스크립트 실행자에게 사이트에 대한 자격 증명을 요청하고 싶었습니다.

내가 처리 한 방법은 다음과 같습니다.

$creds = Get-Credential

$basicCreds = [pscredential]::new($Creds.UserName,$Creds.Password)

Invoke-WebRequest -Uri $URL -Credential $basicCreds

그 결과 스크립트 실행기에 U / P에 대한 로그인 대화 상자가 표시되고 Invoke-WebRequest가 해당 자격 증명으로 사이트에 액세스 할 수 있습니다. 이것은 $ Creds.Password가 이미 암호화 된 문자열이기 때문에 작동합니다.

위의 질문에 대한 유사한 솔루션을 찾는 사람이 스크립트에 사용자 이름이나 PW를 저장하지 않고 도움이되기를 바랍니다.


0

이것이 우리의 특정 상황에서 효과가 있었던 것입니다.

메모는 클라이언트 측의 기본 인증에 대한 Wikipedia에서 가져온 것 입니다. 도움을 주신 @briantist의 답변 에 감사드립니다 !

사용자 이름과 비밀번호를 단일 문자열로 결합 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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.