GithubHelp home page GithubHelp logo

juanifioren / django-oidc-provider Goto Github PK

View Code? Open in Web Editor NEW
404.0 19.0 242.0 2.36 MB

OpenID Connect and OAuth2 provider implementation for Djangonauts.

Home Page: http://django-oidc-provider.readthedocs.org

License: MIT License

Python 96.28% HTML 3.65% Dockerfile 0.07%
python django openid oauth2 identity openid-connect openid-provider oauth2-provider authentication

django-oidc-provider's Introduction

Django OpenID Connect Provider

Python Versions Django Versions PyPI Versions Documentation Status

About OpenID

OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol, which allows computing clients to verify the identity of an end-user based on the authentication performed by an authorization server, as well as to obtain basic profile information about the end-user in an interoperable and REST-like manner. Like Google for example.

About the package

django-oidc-provider can help you providing out of the box all the endpoints, data and logic needed to add OpenID Connect (and OAuth2) capabilities to your Django projects.

Support for Python 3 and latest versions of django.

Read documentation for more info.

Do you want to contribute? Please read this.

django-oidc-provider's People

Contributors

avallbona avatar bbkgh avatar bracki avatar brosner avatar cbouvier15 avatar dcollinsn avatar dhrp avatar ellmetha avatar evgenigordeev avatar fengsi avatar fgaudin avatar fishilico avatar fjouatte avatar gertjanol avatar grahamu avatar hpool avatar jerrykan avatar juanifioren avatar jvazquez avatar kevin-brown avatar maartenkos avatar mikkokeskinen avatar monkeypants avatar ngrjs avatar nmohoric avatar pabluk avatar psavoie avatar stefanfoulis avatar suutari-ai avatar wojtek-fliposports avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-oidc-provider's Issues

Migrate from Crypto to Cryptodome

Hi,
Can you please change the code in the v3 branch importing Crypto to Cryptodome?
I think the Crypto package is no longer maintained (last commit was two years ago).
As reference you can take a look at:
rohe/pyjwkest@d676d16

Best regards!

`prompt` value is ignored in Authorization endpoint

in section: 3.1.2.3. Authorization Server Authenticates End-User we can read:

The Authorization Server MUST attempt to Authenticate the End-User in the following cases:

  • The End-User is not already Authenticated.
  • The Authentication Request contains the prompt parameter with the value login. In this case, the Authorization Server MUST reauthenticate the End-User even if the End-User is already authenticated.

The Authorization Server MUST NOT interact with the End-User in the following case:

  • The Authentication Request contains the prompt parameter with the value none. In this case, the Authorization Server MUST return an error if an End-User is not already Authenticated or could not be silently Authenticated.

This parameter being ignored.

Maybe something like this patch will help. Only my worries is the last part about log out the user to force login screen.

*** django-rest-auth/rest_auth/views.py       2016-03-30 13:24:33.793060288 +0000
--- django-rest-auth/rest_auth/views.py       2016-03-30 13:24:23.457060791 +0000
***************
*** 2,7 ****
--- 2,8 ----

  from Crypto.PublicKey import RSA
  from django.contrib.auth.views import redirect_to_login, logout
+ from django.contrib.auth import logout as auth_logout
  from django.core.urlresolvers import reverse
  from django.http import JsonResponse
  from django.shortcuts import render
***************
*** 60,65 ****
--- 61,67 ----
          self.params.scope = query_dict.get('scope', '').split()
          self.params.state = query_dict.get('state', '')
          self.params.nonce = query_dict.get('nonce', '')
+         self.params.prompt = query_dict.get('prompt', '')

      def validate_params(self):
          try:
***************
*** 85,90 ****
--- 87,98 ----
              raise AuthorizeError(self.params.redirect_uri, 'invalid_request',
                  self.grant_type)

+         if self.is_authentication and self.params.prompt == 'none' and not self.request.user.is_authenticated():
+             raise AuthorizeError(self.params.redirect_uri, 'login_required', self.grant_type)
+
+         if self.is_authentication and self.params.prompt == 'login':
+             auth_logout(self.request)
+
          clean_redirect_uri = urlsplit(self.params.redirect_uri)
          clean_redirect_uri = urlunsplit(clean_redirect_uri._replace(query=''))
          if not (clean_redirect_uri in self.client.redirect_uris):

Consider support for both pyjwkest and python-jose

I have a project that already uses python-jose, and I'd like to use django-oidc-provider as well. It seems a shame to have multiple implementations of JWT running around, so that there are possibly-conflicting transitive dependencies and interoperability concerns.

It's possible to have library users choose their transitive dependency by using extra_requires:
e.g.
https://github.com/jazzband/django-constance/blob/8f71bca1924df04274475dd013253ebfee633e93/docs/index.rst#installation
https://github.com/jazzband/django-constance/blob/8f71bca1924df04274475dd013253ebfee633e93/setup.py#L54

Would you consider this approach? I can do a PR if it sounds like a good idea.

Nonce support for both Code and Implicit flow

The spec say:

String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token.
The nonce in the returned ID Token is compared to the hash of the session cookie to detect ID Token replay by third parties. Use of the nonce is OPTIONAL when using the code flow.

When I ran the runserver it said that you code needed to be migrated.

It looks like you may have forgotten to commit the last DB migrations to your repo. I get a request when I run the runserver that your code needs migrations. I did makemigrations on your code and it fixed this. When I want to upgrade to a future version, of your code, there will be collisions with migrations, since we both will be making migrations on the same change set.

You may want to check this out and fix it ASAP before too many people run into this issue.

Add support for non-confidential App clients

Currently all clients registered by django-oidc-provider require a client secret, however some clients are not capable of keeping secrets confidential (specifically: downloadable apps).

If the client has approved the request previously, subsequent requests are auto-approved by django-oidc-provider. I recommend not auto-approving requests for non-confidential clients that use URI schemes with no authority (i.e. non-https schemes). This could be achieved by adding an "App" client type with no secret provisioned, so that requests from such clients could be processed differently.

Support HTTP Basic client authentication

As we can read in this section of the OAuth2 Spec:

Clients in possession of a client password MAY use the HTTP Basic
authentication scheme as defined in [RFC2617] to authenticate with
the authorization server.

Actually, we are only supporting the include of client credentials in the request-body.
So, HTTP Basic authentication scheme SHOULD be implemented.

Removal of Old Tokens/Codes

A client has requested that tokens/codes should no longer be usable if the same client has a newer one for that user, to allow for less possible attack vectors.

Before I begin implementing a solution I thought I would check here to see if:
a) this would be something you would be interested in merging in and, if so,
b) you had any preferences on implementation

I imagine the two possible solutions would be to set the old code/token to have expired long ago, or just delete it outright from the database.

Any feedback/suggestions/questions would be appreciated.

LOGIN_URL in settings.py in README

The README shows the following in settings.py:

# Used to log the user in.
# See: https://docs.djangoproject.com/en/1.7/ref/settings/#login-url
LOGIN_URL = '/accounts/login/'

but it is not clear why LOGIN_URL is required or what it should be set to ('/accounts/login/' ?).

Ignoring OIDC_SKIP_CONSENT_ENABLE in POST request

I have question to handling POST request in https://github.com/juanifioren/django-oidc-provider/blob/v0.3.x/oidc_provider/views.py#L104 ?

 89:    def post(self, request, *args, **kwargs):
 90:
 91:        authorize = AuthorizeEndpoint(request)
 92:
 93:        allow = True if request.POST.get('allow') else False
 94:
 95:        try:
 96:            authorize.validate_params()
 97:             
 98:            if not allow:
 99:                raise AuthorizeError(authorize.params.redirect_uri,
100:                                     'access_denied',
101:                                     authorize.grant_type)
102:
103:            # Save the user consent given to the client.
104:            authorize.set_client_user_consent()

And some additional questions:
Why You validating params before checking "allow" in POST ?. Is where any spec saying that "allow" must be in POST request ?

having hard time installing on windows

I am trying to install this on Windows 10 and receiving the following error:

error: Microsoft Visual C++ 10.0 is required (Unable to find vcvarsall.bat). 

Visual C++ 10.0 comes with Visual Studio 10 which is no longer available. Have you run into this? Do you know of a workaround? Thanks!

Add support for Django Rest Framework

The idea is to have both django-oidc-provider and djangorestframework working on a same project providing Authentication with OpenID Connect and Authorization with OAuth2.

Any help is welcomed.

Remember user consent and skipt it

In the Authentication Request, if users previously gave consent to some client
(for a specific list of scopes) and because they might be prompted for the same
authorization multiple times.

I have some doubts.
¿Could be acceptable to skip it?.
¿Works on both auth code and implicit flows?.

Am hearing opinions about it. Thanks.

get_issuer returns a wrong value

I think that the issuer value sent by /.well-known/openid-configuration/ is wrong:

$ curl "https://id.seminar.io/openid/.well-known/openid-configuration/" | python -m json.tool
{
    "authorization_endpoint": "https://id.seminar.io/openid/authorize",
    "end_session_endpoint": "https://id.seminar.io/openid/logout",
    "id_token_signing_alg_values_supported": [
        "RS256"
    ],
    "issuer": "https://id.seminar.io/openid/.well-known/openid-configuration",
    "jwks_uri": "https://id.seminar.io/openid/jwks",
    "response_types_supported": [
        "code",
        "id_token",
        "id_token token"
    ],
    "subject_types_supported": [
        "public"
    ],
    "token_endpoint": "https://id.seminar.io/openid/token",
    "token_endpoint_auth_methods_supported": [
        "client_secret_post",
        "client_secret_basic"
    ],
    "userinfo_endpoint": "https://id.seminar.io/openid/userinfo"
}

using the oic library I see this error:

>>> client.provider_config("https://id.seminar.io/openid/")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pabluk/temp/venv/local/lib/python2.7/site-packages/oic/oic/__init__.py", line 917, in provider_config
    self.handle_provider_config(pcr, issuer, keys, endpoints)
  File "/home/pabluk/temp/venv/local/lib/python2.7/site-packages/oic/oic/__init__.py", line 868, in handle_provider_config
    pcr)
oic.exception.IssuerMismatch: 'https://id.seminar.io/openid' != 'http://id.seminar.io/openid/.well-known/openid-configuration'
>>> 

and looking at https://github.com/juanifioren/django-oidc-provider/blob/v0.2.3/oidc_provider/lib/utils/common.py#L23:L24 I see that the value returned by reverse('oidc_provider:provider_info') has no ending slash:

>>> from django.core.urlresolvers import reverse
>>> reverse('oidc_provider:provider_info')
u'/openid/.well-known/openid-configuration'
>>> reverse('oidc_provider:provider_info').split('/.well-known/openid-configuration/')
[u'/openid/.well-known/openid-configuration']

so it's never split.

Only one key supported

We wanted to use multiple keys (per client) and it appears that the library only allows one.

Is there a plan to support multiple keys?

Thanks,
-r

OpenID Provider Discovery

Per http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig:

OpenID Providers supporting Discovery MUST make a JSON document available at the path formed by concatenating the string /.well-known/openid-configuration to the Issuer. The syntax and semantics of .well-known are defined in RFC 5785 [RFC5785] and apply to the Issuer value when it contains no path component. openid-configuration MUST point to a JSON document compliant with this specification and MUST be returned using the application/json content type.

Currently there is no view for /.well-known/openid-configuration.

pyoidc does support this feature and other libraries expect that as well: django-oidc-auth and AWS.

creatersakey management command doesn't work in Python 3.x

Following the documentation to create the example project, I've found this error with the creatersakey management command using Python 3.4 and the branch v0.2.x:

$ python manage.py creatersakey
Traceback (most recent call last):
  File "/home/pabluk/dev/projects/django-oidc-provider/venv/lib/python3.4/site-packages/oidc_provider/management/commands/creatersakey.py", line 15, in handle
    f.write(key.exportKey('PEM'))
TypeError: must be str, not bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/pabluk/dev/projects/django-oidc-provider/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/home/pabluk/dev/projects/django-oidc-provider/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/pabluk/dev/projects/django-oidc-provider/venv/lib/python3.4/site-packages/django/core/management/base.py", line 390, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/pabluk/dev/projects/django-oidc-provider/venv/lib/python3.4/site-packages/django/core/management/base.py", line 441, in execute
    output = self.handle(*args, **options)
  File "/home/pabluk/dev/projects/django-oidc-provider/venv/lib/python3.4/site-packages/oidc_provider/management/commands/creatersakey.py", line 18, in handle
    self.stdout.write('Something goes wrong: ' + e.message)
AttributeError: 'TypeError' object has no attribute 'message'

Running the same command in Python 2.7 works as expected.

Skip user consent entirely

Hi Juan,

I'm using your app to split a project into multiple smaller projects but we develop all the clients so asking for user consent is irrelevant for us. Would it make sense to add a setting (OIDC_ALWAYS_SKIP_CONSENT?) to completely bypass it?

I can provide a pull request if you're interested.

In the mean time, I'm planning to implement it by adding UserConsent objects on User create and Client create and OIDC_SKIP_CONSENT_EXPIRE = 99999.

ID Tokens MUST be signed/encrypted with RS256 at least

As the spec says:

ID Tokens MUST be signed using JWS and optionally both signed and then encrypted using JWS and JWE respectively, thereby providing authentication, integrity, non-repudiation, and optionally, confidentiality, per Section 16.14.

Read more here.

pyjwkest update breaks python 3 support

I found some errors running the test suite with tox in the v0.2.x branch without making any changes to the code on python 3.4, for example:

ERROR: test_idtoken_sign_validation (oidc_provider.tests.test_token_endpoint.TokenTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pabluk/dev/projects/django-oidc-provider-pabluk/oidc_provider/tests/test_token_endpoint.py", line 314, in test_idtoken_sign_validation
    SIGKEYS = self._get_keys()
  File "/home/pabluk/dev/projects/django-oidc-provider-pabluk/oidc_provider/tests/test_token_endpoint.py", line 97, in _get_keys
    response = JwksView.as_view()(request)
  File "/home/pabluk/dev/projects/django-oidc-provider-pabluk/.tox/py34-django18/lib/python3.4/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/pabluk/dev/projects/django-oidc-provider-pabluk/.tox/py34-django18/lib/python3.4/site-packages/django/views/generic/base.py", line 89, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/pabluk/dev/projects/django-oidc-provider-pabluk/oidc_provider/views.py", line 192, in get
    'n': long_to_base64(public_key.n).decode('utf-8'),
AttributeError: 'str' object has no attribute 'decode'

Comparing the dependencies used in the latest travis run with python 3.4, I saw that it installed pyjwkest-1.0.5 and my tox tests install pyjwkest-1.0.6 following the requirement pyjwkest>=1.0.3,<1.1 of setup.py.
Then looking at the changes in rohe/pyjwkest@1.0.5...1.0.6 I found this commit rohe/pyjwkest@42b52e7 that seems to change the type of value returned by long_to_base64().

Token / UserInfo endpoints not checking for expired code / access token.

I was developing a example with that project and I realised that both Token or UserInfo endpoint are not checking if the code / access token has expired or not. Just checks for that code / token in the database.
(In the token endpoint checks for the expiration, but if the token has not be used, and the first time is used has expired the response is successful response as well)

Do you think to change that in the future? Or there is a reason to do like that?
I fix that just adding a check in the validate_params functions, but I would like to heard yours answers before.

ID token does not contain kid

It appears that current implementation contains only "alg" in the token header.

E.g.
{"alg":"RS256")

Should include kid and look like:
{"alg":"RS256","kid":"1f8965c7a3f36d7ed39b1f95cb5143dd"}

I believe the issue is with encode_id_token method in utils/token.py. It should be calculating kid and passing it as an argument to RSAKey constructor.

Version 0.2.2 not accessible from PIP

Hi.
The latest version 0.2.2 is not accessible from PyPI:

Collecting django-oidc-provider==0.2.2 (from -r /opt/python/ondeck/app/requirements.txt (line 3))
    Could not find a version that satisfies the requirement django-oidc-provider==0.2.2 (from -r /opt/python/ondeck/app/requirements.txt (line 3)) (from versions: 0.0.1, 0.0.2, 0.0.3, 0.0.5, 0.0.6, 0.0.7, 0.1.0, 0.1.1, 0.1.2, 0.2.0, 0.2.1)

Dynamic registration endpoint

Thanks for creating the new branch for the dynamic registration. Is there anything you need me to do with it at this point, or is it just waiting to be merged?

Forcing SSL

The README states:

Despite that implementation MUST support TLS. You can make request without using SSL. There is no control on that.

If you want to suggest to the users, something like this:
https://github.com/rdegges/django-sslify can be used to prevent non SSL connections.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.