sso attributes stored in session.

This commit is contained in:
Serghei Mihai 2015-04-08 12:19:45 +02:00
parent e5e6f14a94
commit 34457e9cc5
2 changed files with 26 additions and 33 deletions

View File

@ -27,12 +27,12 @@ class Client(oic.Client):
self.behaviour = behaviour
def create_authn_request(self, acr_value=None):
self.state = rndstr()
state = rndstr()
nonce = rndstr()
request_args = {
"response_type": self.behaviour["response_type"],
"scope": self.behaviour["scope"],
"state": self.state,
"state": state,
"nonce": nonce,
"redirect_uri": self.registration_response["redirect_uris"][0]
}
@ -51,26 +51,25 @@ class Client(oic.Client):
logger.info("URL: %s" % url)
logger.debug("ht_args: %s" % ht_args)
return str(url), ht_args
return str(url), ht_args, state
def callback(self, response):
def callback(self, state, response):
"""
This is the method that should be called when an AuthN response has been
received from the OP.
:param response: The URL returned by the OP
:return:
"""
authresp = self.parse_response(AuthorizationResponse, response,
sformat="dict", keyjar=self.keyjar)
app_admin = False
app_user = False
try:
if self.state != authresp['state']:
if state != authresp['state']:
raise OIDCError("Invalid state %s." % authresp["state"])
except AttributeError:
raise OIDCError("access denied")
if isinstance(authresp, ErrorResponse):
return OIDCError("Access denied")
raise OIDCError("Access denied")
try:
self.id_token[authresp["state"]] = authresp["id_token"]
@ -93,8 +92,8 @@ class Client(oic.Client):
scope="openid", state=authresp["state"], request_args=args,
authn_method=self.registration_response["token_endpoint_auth_method"])
id_token = atresp['id_token']
self.app_admin = 'app_admin' in id_token and id_token['app_admin']
self.app_user = 'app_user' in id_token and id_token['app_user']
app_admin = 'app_admin' in id_token and id_token['app_admin']
app_user = 'app_user' in id_token and id_token['app_user']
except Exception as err:
logger.error("%s" % err)
raise
@ -112,7 +111,7 @@ class Client(oic.Client):
logger.debug("UserInfo: %s" % inforesp)
return userinfo
return userinfo, app_admin, app_user, self.access_token, self.id_token
def create_client(**kwargs):
"""

View File

@ -19,20 +19,11 @@ plugin_config_prefix = 'ckanext.ozwillo_pyoidc.'
log = logging.getLogger(__name__)
plugin_controller = __name__ + ':OpenidController'
_CLIENTS = {}
class Clients(object):
@classmethod
def get(cls, g):
global _CLIENTS
if g.id in _CLIENTS:
return _CLIENTS.get(g.id)
client = cls().get_client(g)
_CLIENTS.update({g.id: client})
return client
def get_client(self, g):
def get_client(cls, g):
params = conf.CLIENT.copy()
params['client_registration'].update({
'client_id': g._extras['client_id'].value,
@ -82,8 +73,10 @@ class OzwilloPyoidcPlugin(plugins.SingletonPlugin):
if 'organization_id' in session:
g = model.Group.get(session['organization_id'])
client = Clients.get(g)
url, ht_args = client.create_authn_request(conf.ACR_VALUES)
client = Clients.get_client(g)
url, ht_args, state = client.create_authn_request(conf.ACR_VALUES)
session['state'] = state
session.save()
if ht_args:
toolkit.request.headers.update(ht_args)
redirect_to(url)
@ -128,12 +121,16 @@ class OpenidController(base.BaseController):
def callback(self):
g = model.Group.get(session['organization_id'])
client = Clients.get(g)
client = Clients.get_client(g)
org_url = str(toolkit.url_for(controller="organization",
action='read',
id=g.name))
try:
userinfo = client.callback(request.GET)
userinfo, app_admin, app_user, access_token, id_token \
= client.callback(session['state'], request.GET)
session['access_token'] = access_token
session['id_token'] = id_token
session.save()
except OIDCError, e:
flash_error('Login failed')
redirect_to(org_url, qualified=True)
@ -159,7 +156,7 @@ class OpenidController(base.BaseController):
'session': model.Session}
user_create(context, user_dict)
userobj = model.User.get(userinfo['sub'])
if client.app_admin or client.app_user:
if app_admin or app_user:
member_dict = {
'id': g.id,
'object': userinfo['sub'],
@ -212,23 +209,20 @@ class OpenidController(base.BaseController):
org_url = str(org_url)
if toolkit.c.user:
client = Clients.get(g)
client = Clients.get_client(g)
logout_url = client.end_session_endpoint
redirect_uri = org_url + '/logout'
if not hasattr(client, 'access_token'):
self.sso(g.name)
# revoke the access token
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
data = 'token=' + client.access_token
data = 'token=' + session.get('access_token')
data += '&token_type_hint=access_token'
client.http_request(client.revocation_endpoint, 'POST',
data=data, headers=headers)
# redirect to IDP logout
logout_url += '?id_token_hint=%s&' % client.id_token
logout_url += '?id_token_hint=%s&' % session.get('id_token')
logout_url += 'post_logout_redirect_uri=%s' % redirect_uri
redirect_to(str(logout_url))
redirect_to(org_url)