-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Parsing the Authorization HTTP header to grant API keys * Using HTTPAuthorizationHeader and BasicHTTPAuthorizationHeaderCredentials * Adding tests for grantAPIKey * Adding http_authentication/ folder * Removing test route * Using new classes to create the headers we pass to ES * No longer .toLowerCase() when parsing the scheme from the request * Updating snapshots * Update x-pack/plugins/security/server/authentication/http_authentication/http_authorization_header.ts Co-Authored-By: Aleh Zasypkin <aleh.zasypkin@gmail.com> * Updating another inline snapshot * Adding JSDoc * Renaming `grant` to `grantAsInternalUser` * Adding forgotten test. Fixing snapshot * Fixing mock * Apply suggestions from code review Co-Authored-By: Aleh Zasypkin <aleh.zasypkin@gmail.com> Co-Authored-By: Mike Côté <mikecote@users.noreply.github.com> * Using new classes for changing password * Removing unneeded asScoped call Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Mike Côté <mikecote@users.noreply.github.com> Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Mike Côté <mikecote@users.noreply.github.com>
- Loading branch information
1 parent
fbe3637
commit d4e86e1
Showing
22 changed files
with
534 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 0 additions & 58 deletions
58
x-pack/plugins/security/server/authentication/get_http_authentication_scheme.test.ts
This file was deleted.
Oops, something went wrong.
21 changes: 0 additions & 21 deletions
21
x-pack/plugins/security/server/authentication/get_http_authentication_scheme.ts
This file was deleted.
Oops, something went wrong.
56 changes: 56 additions & 0 deletions
56
...er/authentication/http_authentication/basic_http_authorization_header_credentials.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { BasicHTTPAuthorizationHeaderCredentials } from './basic_http_authorization_header_credentials'; | ||
|
||
const encodeToBase64 = (str: string) => Buffer.from(str).toString('base64'); | ||
|
||
describe('BasicHTTPAuthorizationHeaderCredentials.parseFromRequest()', () => { | ||
it('parses username from the left-side of the single colon', () => { | ||
const basicCredentials = BasicHTTPAuthorizationHeaderCredentials.parseFromCredentials( | ||
encodeToBase64('fOo:bAr') | ||
); | ||
expect(basicCredentials.username).toBe('fOo'); | ||
}); | ||
|
||
it('parses username from the left-side of the first colon', () => { | ||
const basicCredentials = BasicHTTPAuthorizationHeaderCredentials.parseFromCredentials( | ||
encodeToBase64('fOo:bAr:bAz') | ||
); | ||
expect(basicCredentials.username).toBe('fOo'); | ||
}); | ||
|
||
it('parses password from the right-side of the single colon', () => { | ||
const basicCredentials = BasicHTTPAuthorizationHeaderCredentials.parseFromCredentials( | ||
encodeToBase64('fOo:bAr') | ||
); | ||
expect(basicCredentials.password).toBe('bAr'); | ||
}); | ||
|
||
it('parses password from the right-side of the first colon', () => { | ||
const basicCredentials = BasicHTTPAuthorizationHeaderCredentials.parseFromCredentials( | ||
encodeToBase64('fOo:bAr:bAz') | ||
); | ||
expect(basicCredentials.password).toBe('bAr:bAz'); | ||
}); | ||
|
||
it('throws error if there is no colon', () => { | ||
expect(() => { | ||
BasicHTTPAuthorizationHeaderCredentials.parseFromCredentials(encodeToBase64('fOobArbAz')); | ||
}).toThrowErrorMatchingInlineSnapshot( | ||
`"Unable to parse basic authentication credentials without a colon"` | ||
); | ||
}); | ||
}); | ||
|
||
describe(`toString()`, () => { | ||
it('concatenates username and password using a colon and then base64 encodes the string', () => { | ||
const basicCredentials = new BasicHTTPAuthorizationHeaderCredentials('elastic', 'changeme'); | ||
|
||
expect(basicCredentials.toString()).toEqual(Buffer.from(`elastic:changeme`).toString('base64')); // I don't like that this so closely mirror the actual implementation | ||
expect(basicCredentials.toString()).toEqual('ZWxhc3RpYzpjaGFuZ2VtZQ=='); // and I don't like that this is so opaque. Both together seem reasonable... | ||
}); | ||
}); |
44 changes: 44 additions & 0 deletions
44
.../server/authentication/http_authentication/basic_http_authorization_header_credentials.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
export class BasicHTTPAuthorizationHeaderCredentials { | ||
/** | ||
* Username, referred to as the `user-id` in https://tools.ietf.org/html/rfc7617. | ||
*/ | ||
readonly username: string; | ||
|
||
/** | ||
* Password used to authenticate | ||
*/ | ||
readonly password: string; | ||
|
||
constructor(username: string, password: string) { | ||
this.username = username; | ||
this.password = password; | ||
} | ||
|
||
/** | ||
* Parses the username and password from the credentials included in a HTTP Authorization header | ||
* for the Basic scheme https://tools.ietf.org/html/rfc7617 | ||
* @param credentials The credentials extracted from the HTTP Authorization header | ||
*/ | ||
static parseFromCredentials(credentials: string) { | ||
const decoded = Buffer.from(credentials, 'base64').toString(); | ||
if (decoded.indexOf(':') === -1) { | ||
throw new Error('Unable to parse basic authentication credentials without a colon'); | ||
} | ||
|
||
const [username] = decoded.split(':'); | ||
// according to https://tools.ietf.org/html/rfc7617, everything | ||
// after the first colon is considered to be part of the password | ||
const password = decoded.substring(username.length + 1); | ||
return new BasicHTTPAuthorizationHeaderCredentials(username, password); | ||
} | ||
|
||
toString() { | ||
return Buffer.from(`${this.username}:${this.password}`).toString('base64'); | ||
} | ||
} |
Oops, something went wrong.