Revision 34457e9c
Added by Serghei Mihai over 9 years ago
ckanext/ozwillo_pyoidc/oidc.py | ||
---|---|---|
27 | 27 |
self.behaviour = behaviour |
28 | 28 |
|
29 | 29 |
def create_authn_request(self, acr_value=None): |
30 |
self.state = rndstr()
|
|
30 |
state = rndstr() |
|
31 | 31 |
nonce = rndstr() |
32 | 32 |
request_args = { |
33 | 33 |
"response_type": self.behaviour["response_type"], |
34 | 34 |
"scope": self.behaviour["scope"], |
35 |
"state": self.state,
|
|
35 |
"state": state, |
|
36 | 36 |
"nonce": nonce, |
37 | 37 |
"redirect_uri": self.registration_response["redirect_uris"][0] |
38 | 38 |
} |
... | ... | |
51 | 51 |
logger.info("URL: %s" % url) |
52 | 52 |
logger.debug("ht_args: %s" % ht_args) |
53 | 53 |
|
54 |
return str(url), ht_args |
|
54 |
return str(url), ht_args, state
|
|
55 | 55 |
|
56 |
def callback(self, response): |
|
56 |
def callback(self, state, response):
|
|
57 | 57 |
""" |
58 | 58 |
This is the method that should be called when an AuthN response has been |
59 | 59 |
received from the OP. |
60 |
|
|
61 |
:param response: The URL returned by the OP |
|
62 |
:return: |
|
63 | 60 |
""" |
64 | 61 |
authresp = self.parse_response(AuthorizationResponse, response, |
65 | 62 |
sformat="dict", keyjar=self.keyjar) |
63 |
app_admin = False |
|
64 |
app_user = False |
|
66 | 65 |
try: |
67 |
if self.state != authresp['state']:
|
|
66 |
if state != authresp['state']: |
|
68 | 67 |
raise OIDCError("Invalid state %s." % authresp["state"]) |
69 | 68 |
except AttributeError: |
70 | 69 |
raise OIDCError("access denied") |
71 | 70 |
|
72 | 71 |
if isinstance(authresp, ErrorResponse): |
73 |
return OIDCError("Access denied")
|
|
72 |
raise OIDCError("Access denied")
|
|
74 | 73 |
|
75 | 74 |
try: |
76 | 75 |
self.id_token[authresp["state"]] = authresp["id_token"] |
... | ... | |
93 | 92 |
scope="openid", state=authresp["state"], request_args=args, |
94 | 93 |
authn_method=self.registration_response["token_endpoint_auth_method"]) |
95 | 94 |
id_token = atresp['id_token'] |
96 |
self.app_admin = 'app_admin' in id_token and id_token['app_admin']
|
|
97 |
self.app_user = 'app_user' in id_token and id_token['app_user']
|
|
95 |
app_admin = 'app_admin' in id_token and id_token['app_admin'] |
|
96 |
app_user = 'app_user' in id_token and id_token['app_user'] |
|
98 | 97 |
except Exception as err: |
99 | 98 |
logger.error("%s" % err) |
100 | 99 |
raise |
... | ... | |
112 | 111 |
|
113 | 112 |
logger.debug("UserInfo: %s" % inforesp) |
114 | 113 |
|
115 |
return userinfo |
|
114 |
return userinfo, app_admin, app_user, self.access_token, self.id_token
|
|
116 | 115 |
|
117 | 116 |
def create_client(**kwargs): |
118 | 117 |
""" |
ckanext/ozwillo_pyoidc/plugin.py | ||
---|---|---|
19 | 19 |
log = logging.getLogger(__name__) |
20 | 20 |
plugin_controller = __name__ + ':OpenidController' |
21 | 21 |
|
22 |
_CLIENTS = {} |
|
23 | 22 |
|
24 | 23 |
class Clients(object): |
25 | 24 |
|
26 | 25 |
@classmethod |
27 |
def get(cls, g): |
|
28 |
global _CLIENTS |
|
29 |
if g.id in _CLIENTS: |
|
30 |
return _CLIENTS.get(g.id) |
|
31 |
client = cls().get_client(g) |
|
32 |
_CLIENTS.update({g.id: client}) |
|
33 |
return client |
|
34 |
|
|
35 |
def get_client(self, g): |
|
26 |
def get_client(cls, g): |
|
36 | 27 |
params = conf.CLIENT.copy() |
37 | 28 |
params['client_registration'].update({ |
38 | 29 |
'client_id': g._extras['client_id'].value, |
... | ... | |
82 | 73 |
|
83 | 74 |
if 'organization_id' in session: |
84 | 75 |
g = model.Group.get(session['organization_id']) |
85 |
client = Clients.get(g) |
|
86 |
url, ht_args = client.create_authn_request(conf.ACR_VALUES) |
|
76 |
client = Clients.get_client(g) |
|
77 |
url, ht_args, state = client.create_authn_request(conf.ACR_VALUES) |
|
78 |
session['state'] = state |
|
79 |
session.save() |
|
87 | 80 |
if ht_args: |
88 | 81 |
toolkit.request.headers.update(ht_args) |
89 | 82 |
redirect_to(url) |
... | ... | |
128 | 121 |
|
129 | 122 |
def callback(self): |
130 | 123 |
g = model.Group.get(session['organization_id']) |
131 |
client = Clients.get(g) |
|
124 |
client = Clients.get_client(g)
|
|
132 | 125 |
org_url = str(toolkit.url_for(controller="organization", |
133 | 126 |
action='read', |
134 | 127 |
id=g.name)) |
135 | 128 |
try: |
136 |
userinfo = client.callback(request.GET) |
|
129 |
userinfo, app_admin, app_user, access_token, id_token \ |
|
130 |
= client.callback(session['state'], request.GET) |
|
131 |
session['access_token'] = access_token |
|
132 |
session['id_token'] = id_token |
|
133 |
session.save() |
|
137 | 134 |
except OIDCError, e: |
138 | 135 |
flash_error('Login failed') |
139 | 136 |
redirect_to(org_url, qualified=True) |
... | ... | |
159 | 156 |
'session': model.Session} |
160 | 157 |
user_create(context, user_dict) |
161 | 158 |
userobj = model.User.get(userinfo['sub']) |
162 |
if client.app_admin or client.app_user:
|
|
159 |
if app_admin or app_user:
|
|
163 | 160 |
member_dict = { |
164 | 161 |
'id': g.id, |
165 | 162 |
'object': userinfo['sub'], |
... | ... | |
212 | 209 |
org_url = str(org_url) |
213 | 210 |
|
214 | 211 |
if toolkit.c.user: |
215 |
client = Clients.get(g) |
|
212 |
client = Clients.get_client(g)
|
|
216 | 213 |
logout_url = client.end_session_endpoint |
217 | 214 |
|
218 | 215 |
redirect_uri = org_url + '/logout' |
219 | 216 |
|
220 |
if not hasattr(client, 'access_token'): |
|
221 |
self.sso(g.name) |
|
222 |
|
|
223 | 217 |
# revoke the access token |
224 | 218 |
headers = {'Content-Type': 'application/x-www-form-urlencoded'} |
225 |
data = 'token=' + client.access_token
|
|
219 |
data = 'token=' + session.get('access_token')
|
|
226 | 220 |
data += '&token_type_hint=access_token' |
227 | 221 |
client.http_request(client.revocation_endpoint, 'POST', |
228 | 222 |
data=data, headers=headers) |
229 | 223 |
|
230 | 224 |
# redirect to IDP logout |
231 |
logout_url += '?id_token_hint=%s&' % client.id_token
|
|
225 |
logout_url += '?id_token_hint=%s&' % session.get('id_token')
|
|
232 | 226 |
logout_url += 'post_logout_redirect_uri=%s' % redirect_uri |
233 | 227 |
redirect_to(str(logout_url)) |
234 | 228 |
redirect_to(org_url) |
Also available in: Unified diff
sso attributes stored in session.