Project

General

Profile

« Previous | Next » 

Revision 34457e9c

Added by Serghei Mihai over 9 years ago

sso attributes stored in session.

View differences:

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