Changeset 4132
- Timestamp:
- 21/08/08 16:53:48 (12 years ago)
- Location:
- TI12-security/trunk/python/ndg.security.server/ndg/security/server
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/python/ndg.security.server/ndg/security/server/pylons/container/lib/openid_provider_util.py
r4125 r4132 105 105 c.xml = "<b><pre>%s</pre></b>" % identityURL 106 106 107 return _render('ndg.security.identityPage', 108 c=c, g=config, h=h) 109 107 return _render('ndg.security.identityPage', c=c, g=config, h=h) 108 109 110 110 def renderDecidePage(self, environ, oidRequest): 111 111 """Handle user interaction required before final submit back to Relying … … 124 124 c.xml = msg 125 125 return _render('ndg.security.error', c=c, g=config, h=h) 126 127 # Earth System Grid interoperability tests 128 129 #esgAxAttr = {'urn:esg.security.gateway': 'BADC', 130 # 'urn:esg.security.authority': 'group_IPCC_role_default', 131 # 'http://axschema.org/namePerson/last': 'UserLastName', 132 # 'http://axschema.org/contact/country/home': 'UK', 133 # 'http://axschema.org/namePerson/middle': 'UserMiddleName', 134 # 'urn:esg.security.uuid': '0123456789abcdef', 135 # 'http://axschema.org/namePerson/first': 'UserFirstName', 136 # 'http://axschema.org/namePerson/friendly': '', 137 # 'http://axschema.org/contact/email': 'tester@test.com', 138 # 'urn:esg.security.organization': 'British Atmospheric Data Centre', 139 #} 140 141 esgAxAttr = { 142 'http://openid.net/schema/contact/state/home': 'Oxfordshire', 143 'http://openid.net/schema/namePerson/middle': 'George', 144 'http://openid.net/schema/contact/city/home': 'Didcot', 145 'http://openid.net/schema/person/guid': '0123456789abcdef', 146 'http://openid.net/schema/namePerson/friendly': 'username', 147 'http://openid.net/schema/company/name': 'The British Atmospheric Data Centre', 148 'http://openid.net/schema/contact/country/home': 'UK', 149 'http://openid.net/schema/namePerson/first': 'John', 150 'http://openid.net/schema/namePerson/last': 'Smith', 151 'http://openid.net/schema/contact/internet/email': 'testABC@rl.ac.uk', 152 'http://www.earthsystemgrid.org/authority': 'group_IPCC_role_default', 153 'http://www.earthsystemgrid.org/gateway': 'BADC', 154 } 155 esgAxAlias = { 156 'http://openid.net/schema/contact/state/home': 'state', 157 'http://openid.net/schema/namePerson/middle': 'middlename', 158 'http://openid.net/schema/contact/city/home': 'city', 159 'http://openid.net/schema/person/guid': 'uuid', 160 'http://openid.net/schema/namePerson/friendly': 'username', 161 'http://openid.net/schema/company/name': 'organization', 162 'http://openid.net/schema/contact/country/home': 'country', 163 'http://openid.net/schema/namePerson/first': 'firstname', 164 'http://openid.net/schema/namePerson/last': 'lastname', 165 'http://openid.net/schema/contact/internet/email': 'email', 166 'http://www.earthsystemgrid.org/authority': 'authority', 167 'http://www.earthsystemgrid.org/gateway': 'gateway', 168 } 169 170 esgSRegAttr = { 171 'nickname':'', 172 'email':'E-mail Address', 173 'country':'UK', 174 'language':'English', 175 'timezone':'BST', 176 } 177 178 179 def esgSRegResponseHandler(username): 180 """Interface function to OpenIdProviderMiddleware to set custom attributes 181 """ 182 attr = esgSRegAttr.copy() 183 # attr['username'] = username 184 attr['nickname'] = username 185 return attr 186 187 def esgAXResponseHandler(axReq, axResp, username): 188 """Respond to attributes requested by Relying Party via the Attribute 189 Exchange interface""" 190 attr = esgAxAttr.copy() 191 attr['http://openid.net/schema/namePerson/friendly'] = username 192 193 for typeURI, attrInfo in axReq.requested_attributes.items(): 194 # Value input must be list type 195 axResp.setValues(typeURI, [attr[typeURI]]) -
TI12-security/trunk/python/ndg.security.server/ndg/security/server/pylons/development.ini
r4126 r4132 12 12 13 13 # Layout 14 server = http://localhost:8200 14 #server = http://localhost:8200 15 server = https://gabriel.badc.rl.ac.uk 15 16 LeftLogo = %(server)s/layout/NERC_Logo.gif 16 17 LeftAlt = Natural Environment Research Council … … 72 73 openid_provider.session_middleware=beaker.session 73 74 openid_provider.base_url=http://localhost:8200 74 openid_provider.consumer_store_dirpath=./ 75 openid_provider.base_url=https://gabriel.badc.rl.ac.uk 76 #openid_provider.consumer_store_dirpath=./ 75 77 openid_provider.charset=None 76 78 openid_provider.trace=False 77 79 openid_provider.renderingClass=ndg.security.server.pylons.container.lib.openid_provider_util.OpenIDProviderKidRendering 78 openid_provider.getSRegData= 80 openid_provider.sregResponseHandler=ndg.security.server.pylons.container.lib.openid_provider_util:esgSRegResponseHandler 81 openid_provider.axResponseHandler=ndg.security.server.pylons.container.lib.openid_provider_util:esgAXResponseHandler 79 82 80 83 # Logging configuration -
TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid_provider.py
r4126 r4132 23 23 from authkit.authenticate import AuthKitConfigError 24 24 25 from openid.extensions import sreg 25 from openid.extensions import sreg, ax 26 26 from openid.server import server 27 27 from openid.store.filestore import FileOpenIDStore … … 37 37 class OpenIDProviderMiddlewareError(Exception): 38 38 """OpenID Provider WSGI Middleware Error""" 39 39 40 class OpenIDProviderConfigError(Exception): 41 """OpenID Provider Configuration Error""" 42 40 43 class OpenIDProviderMiddleware(object): 41 44 """WSGI Middleware to implement an OpenID Provider""" … … 56 59 trace=False, 57 60 renderingClass=None, 58 getSRegData=None) 61 sregResponseHandler=None, 62 axResponseHandler=None) 59 63 60 64 defPaths=dict([(k,v) for k,v in defKw.items() if k.startswith('path_')]) … … 91 95 opt['renderingClass'] = eval_import(renderingClassVal) 92 96 93 getSRegDataVal = opt.get('getSRegData', None)94 if getSRegDataVal:95 opt[' getSRegData'] = eval_import(getSRegDataVal)97 sregResponseHandlerVal = opt.get('sregResponseHandler', None) 98 if sregResponseHandlerVal: 99 opt['sregResponseHandler']=eval_import(sregResponseHandlerVal) 96 100 else: 97 opt['getSRegData'] = None 98 101 opt['sregResponseHandler'] = None 102 103 axResponseHandlerVal = opt.get('axResponseHandler', None) 104 if axResponseHandlerVal: 105 opt['axResponseHandler'] = eval_import(axResponseHandlerVal) 106 else: 107 opt['axResponseHandler'] = None 108 99 109 invalidKw = getInvalidKw(kw) 100 110 if len(invalidKw) > 0: … … 104 114 # overwritten 105 115 opt.update(kw) 106 log.debug("opt=%r", opt)107 116 108 117 # Paths relative to base URL - Nb. remove trailing '/' … … 131 140 # If True and debug log level is set display content of response 132 141 self._trace = opt['trace'] 133 142 143 log.debug("opt=%r", opt) 144 134 145 # Pages can be customised by setting external rendering interface 135 146 # class … … 148 159 raise 149 160 150 # Callable for setting of additional attributes in HTTP header of151 # response to Relying Party152 self. getSRegData = opt.get('getSRegData', None)153 if self. getSRegData and not callable(self.getSRegData):161 # Callable for setting of Simple Registration attributes in HTTP header 162 # of response to Relying Party 163 self.sregResponseHandler = opt.get('sregResponseHandler', None) 164 if self.sregResponseHandler and not callable(self.sregResponseHandler): 154 165 raise OpenIDProviderMiddlewareError("Expecting callable for " 155 "getSRegData keyword, got %r"%\ 156 self.getSRegData) 166 "sregResponseHandler keyword, " 167 "got %r" % \ 168 self.sregResponseHandler) 169 170 # Callable to handle OpenID Attribute Exchange (AX) requests from 171 # the Relying Party 172 self.axResponseHandler = opt.get('axResponseHandler', None) 173 if self.axResponseHandler and not callable(self.axResponseHandler): 174 raise OpenIDProviderMiddlewareError("Expecting callable for " 175 "axResponseHandler keyword, " 176 "got %r" % \ 177 self.axResponseHandler) 157 178 158 179 self.app = app … … 166 187 167 188 def __call__(self, environ, start_response): 189 168 190 if not environ.has_key(self.session_middleware): 169 raise AuthKitConfigError( 170 'The session middleware %r is not present. ' 171 'Have you set up the session middleware?'%( 172 self.session_middleware 173 ) 174 ) 191 raise OpenIDProviderConfigError('The session middleware %r is not ' 192 'present. Have you set up the ' 193 'session middleware?' % \ 194 self.session_middleware) 175 195 176 196 self.path = environ.get('PATH_INFO').rstrip('/') … … 218 238 response = self._renderer.renderIdentityPage(environ) 219 239 220 start_response("200 OK", [('Content-length', str(len(response)))]) 240 start_response("200 OK", 241 [('Content-type', 'text/html'+self.charset), 242 ('Content-length', str(len(response)))]) 221 243 return response 222 244 … … 272 294 self.session['approved'] = {trust_root: 'always'} 273 295 self.session.save() 274 296 275 297 oidResponse = self._identityApproved(oidRequest, identity) 276 return self._displayResponse(oidResponse) 298 response = self._displayResponse(oidResponse) 299 log.debug("do_allow response = \n%s" % response) 300 return response 277 301 278 302 elif 'No' in self.query: … … 288 312 'post. %r' % self.query) 289 313 290 291 tmplServerYadis = """\292 <?xml version="1.0" encoding="UTF-8"?>293 <xrds:XRDS294 xmlns:xrds="xri://$xrds"295 xmlns="xri://$xrd*($v*2.0)">296 <XRD>297 298 <Service priority="0">299 <Type>%(openid20type)s</Type>300 <URI>%(endpoint_url)s</URI>301 </Service>302 303 </XRD>304 </xrds:XRDS>305 """306 314 307 315 def do_serveryadis(self, environ, start_response): 308 316 """Handle Server Yadis call""" 309 start_response("200 OK", [('Content-type', 'application/xrds+xml')]) 310 311 endpoint_url = self.urls['url_openidserver'] 312 return [OpenIDProviderMiddleware.tmplServerYadis % \ 313 {'openid20type': discover.OPENID_IDP_2_0_TYPE, 314 'endpoint_url': endpoint_url}] 317 response = self._renderer.renderServerYadis(environ) 318 start_response("200 OK", 319 [('Content-type', 'application/xrds+xml'), 320 ('Content-length', str(len(response)))]) 321 return response 315 322 316 323 … … 424 431 425 432 def _addSRegResponse(self, request, response): 426 '''Add additionalattributes to response to Relying Party'''427 if self. getSRegDatais None:433 '''Add Simple Registration attributes to response to Relying Party''' 434 if self.sregResponseHandler is None: 428 435 return 429 436 … … 432 439 # Callout to external callable sets additional user attributes to be 433 440 # returned in response to Relying Party 434 sreg_data = self.getSRegData(self.session.get('username')) 435 441 sreg_data = self.sregResponseHandler(self.session.get('username')) 436 442 sreg_resp = sreg.SRegResponse.extractResponse(sreg_req, sreg_data) 437 443 response.addExtension(sreg_resp) 438 444 439 445 446 def _addAXResponse(self, request, response): 447 '''Add attributes to response based on the OpenID Attribute Exchange 448 interface''' 449 450 ax_req = ax.FetchRequest.fromOpenIDRequest(request) 451 if ax_req is None: 452 log.debug("No Attribute Exchange extension set in request") 453 return 454 455 ax_resp = ax.FetchResponse(request=ax_req) 456 457 if self.axResponseHandler is None: 458 requiredAttr = ax_req.getRequiredAttrs() 459 if len(requiredAttr) > 0: 460 log.error("Relying party requires these attributes: %s; but no" 461 "Attribute exchange handler 'axResponseHandler' has " 462 "been set" % requiredAttr) 463 return 464 465 # Set requested values - need user intervention here to confirm 466 # release of attributes + assignment based on required attributes - 467 # possibly via FetchRequest.getRequiredAttrs() 468 # for typeURI, attrInfo in ax_req.requested_attributes.items(): 469 # # Value input must be list type 470 # ax_resp.setValues(typeURI, [attrInfo.alias+"Value"]) 471 self.axResponseHandler(ax_req, ax_resp, self.session.get('username')) 472 473 response.addExtension(ax_resp) 474 475 440 476 def _identityApproved(self, request, identifier=None): 441 477 '''Action following approval of a Relying Party by the user''' 442 478 response = request.answer(True, identity=identifier) 443 479 self._addSRegResponse(request, response) 480 self._addAXResponse(request, response) 444 481 return response 445 482 … … 482 519 return response 483 520 484 485 def _displayResponse(self, response): 521 # If the response to the Relying Party is too long it's rendered as form 522 # with the POST method instead of query arguments in a GET 302 redirect. 523 # Wrap the form in this document to make the form submit automatically 524 # without user intervention. See _displayResponse method below... 525 formRespWrapperTmpl = """<html> 526 <head> 527 <script type="text/javascript"> 528 function doRedirect() 529 { 530 document.forms[0].submit(); 531 } 532 </script> 533 </head> 534 <body onLoad="doRedirect()"> 535 %s 536 </body> 537 </html>""" 538 539 def _displayResponse(self, oidResponse): 486 540 try: 487 webresponse = self.oidserver.encodeResponse( response)541 webresponse = self.oidserver.encodeResponse(oidResponse) 488 542 except server.EncodingError, why: 489 543 text = why.response.encodeToKVForm() … … 494 548 lenWebResponseBody = len(webresponse.body) 495 549 if lenWebResponseBody: 496 response = webresponse.body 497 else: 498 response = [] 499 500 hdr += [('Content-length', str(lenWebResponseBody))] 501 550 # Wrap in HTML with JAvascript OnLoad to submit the form 551 # automatically without user intervention 552 response = OpenIDProviderMiddleware.formRespWrapperTmpl % \ 553 webresponse.body 554 else: 555 response = '' 556 557 hdr += [('Content-type', 'text/html'+self.charset), 558 ('Content-length', str(lenWebResponseBody))] 559 560 log.debug("webresponse.code = %d" % webresponse.code) 502 561 self.start_response('%d %s' % (webresponse.code, 503 562 httplib.responses[webresponse.code]), … … 552 611 %s 553 612 ''' % (ident, msg)) 613 614 tmplServerYadis = """\ 615 <?xml version="1.0" encoding="UTF-8"?> 616 <xrds:XRDS 617 xmlns:xrds="xri://$xrds" 618 xmlns="xri://$xrd*($v*2.0)"> 619 <XRD> 620 621 <Service priority="0"> 622 <Type>%(openid20type)s</Type> 623 <URI>%(endpoint_url)s</URI> 624 </Service> 625 626 </XRD> 627 </xrds:XRDS> 628 """ 629 630 def renderServerYadis(self, environ): 631 '''Render Yadis info''' 632 endpoint_url = self.urls['url_openidserver'] 633 return RenderingInterface.tmplServerYadis % \ 634 {'openid20type': discover.OPENID_IDP_2_0_TYPE, 635 'endpoint_url': endpoint_url} 554 636 555 637 tmplYadis = """\ … … 569 651 </XRD> 570 652 </xrds:XRDS>""" 653 571 654 572 655 def renderYadis(self, environ):
Note: See TracChangeset
for help on using the changeset viewer.