Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ref #2659 public HTTP Basic credentials extraction #2662

Merged
merged 8 commits into from
Sep 1, 2016
Merged

ref #2659 public HTTP Basic credentials extraction #2662

merged 8 commits into from
Sep 1, 2016

Conversation

canni
Copy link
Contributor

@canni canni commented Jul 1, 2016

Expose HTTP Basic credentials extraction to public API, it is helpful also outside of HttpBasicAuthenticationPolicy

Also try first logic from WebOb before doing everything manually

# First try authorization extraction logic from WebOb
try:
authmeth, auth = request.authorization
except AttributeError: # Probably a DummyRequest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the point in this fallback. It's trying to reproduce all of the logic, but likely with bugs and inconsistencies from the original request.authorization code. This looks like a maintenance nightmare.

@mmerickel
Copy link
Member

I thought you wanted to support custom headers. This obviously does not. In fact, adding request.authorization from webob means you have no chance.

Regardless, I see no point in supporting custom headers myself. Parsing an HTTP BASIC header is completely trivial (base64 decode, convert to latin-1 or utf8, split on colon). If you're using this encoding and it's not in the standard Authorization header then it's really not our problem and not worth us maintaining just for you.

I'm fine merging this if the comment above is addressed about the fallbacks. But adding in custom header support is something I'm against.

@canni
Copy link
Contributor Author

canni commented Jul 2, 2016

@mmerickel yes, I also came to the conclusion, that adding custom header support is out of the framework scope, anyway this code is still useful outside of authentication policy code, I'll remove fallback

@digitalresistor
Copy link
Member

I wonder if this or something like it shouldn't live instead within WebOb instead of part of Pyramid?

@canni
Copy link
Contributor Author

canni commented Jul 15, 2016

Is there anything else I should do to get this merged? Or are we just rejecting this?

@@ -1145,46 +1145,56 @@ def forget(self, request):
return [('WWW-Authenticate', 'Basic realm="%s"' % self.realm)]

def callback(self, username, request):
# Username arg is ignored. Unfortunately _get_credentials winds up
# Username arg is ignored. Unfortunately extract_http_basic_credentials winds up
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crosses 79 chars, but I will fix it in the merge.

@mmerickel
Copy link
Member

It's debatable whether this belongs in webob. It's not in there right now because webob began in paste and paste had the helper methods in paste.authentication. Webob was then split out and paste was the lib with all the wsgi helpers. Now paste is much less popular than it once was and so placing this type of logic in there is less desirable.

@mmerickel
Copy link
Member

@canni Can you add your name to contributors.txt please.

@canni
Copy link
Contributor Author

canni commented Jul 18, 2016

Can we re-run checks? the failure was a connection error from intersphinx

@stevepiercy
Copy link
Member

@canni you will need to pull in this change on master:
https://github.com/Pylons/pyramid/pull/2702/files

@canni
Copy link
Contributor Author

canni commented Jul 18, 2016

@stevepiercy done

@stevepiercy
Copy link
Member

@mmerickel OK to merge? Backport needed as well?

@tseaver
Copy link
Member

tseaver commented Jul 18, 2016

@stevepiercy I'd say no to a backport: it is a new feature.

@digitalresistor
Copy link
Member

digitalresistor commented Jul 18, 2016

Sorry, thought @mmerickel had already provided a +1 as well.

This LGTM.

@mmerickel
Copy link
Member

Are we making this a public API? I'd like to be clear on the point of this PR.

@mmerickel
Copy link
Member

Right now, all the tests are a side-effect of its usage in the auth policy, obviously. Certainly it'd be nice if that were fixed but not critical.

@mmerickel
Copy link
Member

If this is a public API then it needs to be added to the docs as such in docs/api/authentication.rst.

@canni
Copy link
Contributor Author

canni commented Jul 18, 2016

I'll update docs (if we're decided on making this a public API?) extracting tests shouldn't be a problem also

@mmerickel
Copy link
Member

@canni I don't have a problem making it public I guess. Below is just to make sure we're all on the same page and happy with what we're doing before we ship a public api that we get to maintain since it's changed in scope and doesn't solve your original issue #2659.

There's 3 separate algorithms required to identify basic credentials.

  1. Where are the credentials? Header? Somewhere else?
  2. How to parse the credential envelope?
  3. How to get the username/password from the basic-serialized content?

1 is pretty arbitrary. Obviously it's usually the Authorization header. Could be something else for some reason.
2 depends on the source. If it's the Authorization header. Then you split check the auth type of the header, check for Basic and send the second part to step 3.
Finally part 3 is standard, using the b64decode/split on colon algorithm.

I'd argue that everything is up to the user (re: auth policy) except part 3 which is standard.

This api you want to expose combines all 3 parts and thus is only useable in one very specific scenario... The credentials passed via Authorization header with Basic auth type. This is fine because it's like 99% of the use cases for basic auth, but you came in here originally asking for the 1% in #2659.

So anyway, if you want to make the changes to the docs and the tests then I have no problem merging it.

@canni
Copy link
Contributor Author

canni commented Jul 19, 2016

@mmerickel yes I came with < 1% use-cases, and my use case is quite complex :)

Short answer: Yes this solves my case

Long answer:

One of legacy systems has been designed (don't ask me why) in such a way that credentials are coming from HTTP Basic auth, but with renamed header (I can work-around that easily) but after successful auth the sessions are used instead (HTTP Basic is just a credentials delivery on 1st request, then session cookie)

So I'm trying to mix'n'match Session based auth policy, and HTTP Basic one, into single thing.

Current implementation, with _get_credentials "private" instance method prevents me from (relatively) easy re-use of credentials extraction logic already in place.

So by extracting get_http_basic_credentials my Auth Policy becomes swift and simple subclass of Session Auth Policy

@canni
Copy link
Contributor Author

canni commented Aug 10, 2016

@mmerickel I added new fn to docs, and (re-)created test cases. (I was wondering if I should mock usage of this helper fn for policy, but in the end the policy tests are still valid, as standalone...)

@mmerickel
Copy link
Member

LGTM, thank you @canni !

@canni
Copy link
Contributor Author

canni commented Aug 11, 2016

I also changed the return value to be a namedtuple gives a nicer API, with B/C

@mmerickel mmerickel merged commit 693cb09 into Pylons:master Sep 1, 2016
mmerickel added a commit that referenced this pull request Sep 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants