django-oidc-provider/README.rst

224 lines
5.9 KiB
ReStructuredText
Raw Normal View History

2015-01-13 04:34:13 +00:00
.. image:: http://s1.postimg.org/qcm2dtr6n/title.png
####################################################
2014-12-19 15:27:43 +00:00
2015-01-08 20:55:24 +00:00
**This project is in ALFA version and is rapidly changing. DO NOT USE IT FOR PRODUCTION SITES.**
2015-01-05 20:32:58 +00:00
Important things that you should know:
2015-01-05 20:40:40 +00:00
- Although OpenID was built on top of OAuth2, this isn't an OAuth2 server. Maybe in a future it will be.
2015-01-30 20:20:36 +00:00
- Despite that implementation MUST support TLS. You can make request without using SSL. There is no control on that.
2015-01-09 00:25:52 +00:00
- This cover ``authorization_code`` flow and ``implicit`` flow, NO support for ``hybrid`` flow at this moment.
2015-01-05 20:40:40 +00:00
- Only support for requesting Claims using Scope Values.
2015-01-05 20:32:58 +00:00
2014-12-19 15:27:43 +00:00
************
Installation
************
Install the package using pip.
2014-12-19 15:59:11 +00:00
.. code:: bash
2015-01-28 20:44:38 +00:00
pip install git+https://github.com/juanifioren/django-openid-provider.git#egg=openid_provider
2014-12-19 15:59:11 +00:00
2015-01-09 00:25:52 +00:00
Add it to your apps.
2014-12-19 15:27:43 +00:00
.. code:: python
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'openid_provider',
# ...
)
2015-01-09 00:25:52 +00:00
Add the provider urls.
2014-12-19 15:27:43 +00:00
.. code:: python
urlpatterns = patterns('',
# ...
url(r'^openid/', include('openid_provider.urls', namespace='openid_provider')),
# ...
)
********
Settings
********
2014-12-19 15:27:43 +00:00
Add required variables to your project settings.
.. code:: python
# REQUIRED.
# Your server provider url.
SITE_URL = 'http://localhost:8000'
# Used to log the user in.
# See: https://docs.djangoproject.com/en/1.7/ref/settings/#login-url
LOGIN_URL = '/accounts/login/'
2014-12-19 15:27:43 +00:00
# OPTIONAL.
DOP_CODE_EXPIRE = 60*10 # 10 min.
2015-01-30 20:20:36 +00:00
DOP_EXTRA_SCOPE_CLAIMS = MyAppScopeClaims,
DOP_IDTOKEN_EXPIRE = 60*10, # 10 min.
DOP_TOKEN_EXPIRE = 60*60 # 1 hour.
2014-12-19 15:27:43 +00:00
********************
Create User & Client
********************
First of all, we need to create a user: ``python manage.py createsuperuser``.
Then let's create a Client. Start django shell: ``python manage.py shell``.
.. code:: python
>>> from openid_provider.models import Client
>>> c = Client(name='Some Client', client_id='123', client_secret='456', response_type='code', redirect_uris=['http://example.com/'])
2014-12-19 15:27:43 +00:00
>>> c.save()
2015-01-29 19:19:48 +00:00
****************
Server Endpoints
****************
2014-12-19 15:27:43 +00:00
2015-01-29 19:19:48 +00:00
**/authorize endpoint**
Example of an OpenID Authentication Request using the ``Authorization Code`` flow.
2015-01-09 00:25:52 +00:00
2014-12-19 15:27:43 +00:00
.. code:: curl
GET /openid/authorize?client_id=123&redirect_uri=http%3A%2F%2Fexample.com%2F&response_type=code&scope=openid%20profile%20email&state=abcdefgh HTTP/1.1
Host: localhost:8000
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
After the user accepts and authorizes the client application, the server redirects to:
.. code:: curl
http://example.com/?code=5fb3b172913448acadce6b011af1e75e&state=abcdefgh
2015-01-29 19:19:48 +00:00
The ``code`` param will be use it to obtain access token.
2014-12-19 15:27:43 +00:00
2015-01-29 19:19:48 +00:00
**/token endpoint**
2014-12-19 15:27:43 +00:00
.. code:: curl
POST /openid/token/ HTTP/1.1
Host: localhost:8000
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
client_id=123&client_secret=456&redirect_uri=http%253A%252F%252Fexample.com%252F&grant_type=authorization_code&code=[CODE]&state=abcdefgh
2015-01-29 19:19:48 +00:00
**/userinfo endpoint**
2014-12-19 15:27:43 +00:00
.. code:: curl
POST /openid/userinfo/ HTTP/1.1
Host: localhost:8000
Authorization: Bearer [ACCESS_TOKEN]
2015-01-29 19:19:48 +00:00
2015-01-30 20:20:36 +00:00
***************
Claims & Scopes
***************
OpenID Connect Clients will use scope values to specify what access privileges are being requested for Access Tokens.
Here you have the standard scopes defined by the protocol.
http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
If you need to add extra scopes specific for your app you can add them using the ``DOP_EXTRA_SCOPE_CLAIMS`` settings variable.
This class MUST inherit ``AbstractScopeClaims``.
Check out an example:
.. code:: python
from openid_provider.lib.claims import AbstractScopeClaims
class MyAppScopeClaims(AbstractScopeClaims):
def __init__(self, user, scopes):
# Don't forget this.
super(StandardScopeClaims, self).__init__(user, scopes)
# Here you can load models that will be used
# in more than one scope for example.
try:
self.some_model = SomeModel.objects.get(user=self.user)
except UserInfo.DoesNotExist:
# Create an empty model object.
self.some_model = SomeModel()
def scope_books(self, user):
# Here you can search books for this user.
# Remember that you have "self.some_model" also.
dic = {
'books_readed': books_readed_count,
}
return dic
See how we create our own scopes using the convention ``def scope_<SCOPE_NAME>(self, user):``.
If a field is empty or ``None`` will be cleaned from the response.
**Don't forget to add your class into your app settings.**
2015-01-29 19:19:48 +00:00
*********
Templates
*********
Add your own templates files inside a folder named ``templates/openid_provider/``.
You can copy the sample html here and edit them with your own styles.
2015-01-30 02:32:20 +00:00
**authorize.html**
2015-01-29 19:19:48 +00:00
.. code:: html
<h1>Request for Permission</h1>
<p>Client <strong>{{ client.name }}</strong> would like to access this information of you ...</p>
<form method="post" action="{% url 'openid_provider:authorize' %}">
{% csrf_token %}
{{ hidden_inputs }}
<ul>
{% for scope in params.scope %}
<li>{{ scope | capfirst }}</li>
{% endfor %}
</ul>
<input name="allow" type="submit" value="Authorize" />
</form>
{% endblock %}
2015-01-30 02:32:20 +00:00
**error.html**
2015-01-29 19:19:48 +00:00
.. code:: html
<h3>{{ error }}</h3>
<p>{{ description }}</p>
************
Contributing
************
We love contributions, so please feel free to fix bugs, improve things, provide documentation. Just submit a Pull Request.