Changeset 8057
- Timestamp:
- 10/05/12 15:33:15 (9 years ago)
- Location:
- trunk/ndg_oauth
- Files:
-
- 45 added
- 1 deleted
- 14 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/ndg_oauth/ndg_oauth_client/ndg/oauth/client/examples/config/get_url_app_proxy.ini
r8036 r8057 12 12 error_email_from = paste@localhost 13 13 14 # AuthKit Cookie secret used to secure it. This secret must be the same as the 15 # one used in the equivalent services application(s) ini file(s) that serve 16 # the OpenID Relying Party and SSL authentication service. This is 17 # because the cookie is shared between this app and the services app(s) so that 18 # a user's OpenID can be communicated between them. 19 authkitCookieSecret = 5dFZM97jBeWNsZUqee7TDnCrSicehfod 20 baseURI = http://localhost:5002/ 14 21 beakerSessionKeyName = beaker.session.oauth2client 15 22 #beakerSessionKeyName = ndg.security.session … … 22 29 23 30 [pipeline:main] 24 pipeline = BeakerSessionFilter OAuth2Client SSLCtxEnvironMiddleware NDGSecurityProxy App 31 pipeline = BeakerSessionFilter 32 OAuth2Client 33 SSLCtxEnvironMiddleware 34 NDGSecurityProxy 35 CertificateSubjectEnvironMiddleware 36 SessionHandlerFilter 37 AuthorisationFilter 38 App 25 39 26 40 # This filter sets up a server side session linked to a cookie. The session … … 43 57 paste.filter_app_factory = ndg.oauth.client.wsgi.oauth2_client:Oauth2ClientMiddleware.filter_app_factory 44 58 oauth2.session_key = %(beakerSessionKeyName)s 59 oauth2.authentication_trigger = unauthorized 45 60 # Default: 46 61 #oauth2.oauth2_token_key = oauth2client.token 47 62 # OAuth client configuration 48 oauth2.client_cert = /home/rwilkinson_local/dev/ndg_oauth/certificate/usercert.pem49 oauth2.client_key = /home/rwilkinson_local/dev/ndg_oauth/certificate/userkey.pem50 oauth2.ca_dir = /home/rwilkinson_local/dev/ndg_oauth/ca51 # ca_cert_file = /home/rwilkinson_local/dev/oauthclient/ca.pem63 oauth2.client_cert = %(here)s/certificate/usercert.pem 64 oauth2.client_key = %(here)s/certificate/userkey.pem 65 oauth2.ca_dir = %(here)s/ca 66 # ca_cert_file = 52 67 oauth2.client_id=22 53 68 # OAuth authorization server URLs … … 62 77 #ssl_ctx.ctxEnvKeyName = ssl_ctx 63 78 #ssl_ctx.caCertFilePath = 64 ssl_ctx.caCertDir = /home/rwilkinson_local/dev/ndg_oauth/ca79 ssl_ctx.caCertDir = %(here)s/ca 65 80 #ssl_ctx.verifyPeer = True 66 81 … … 76 91 # These can be specified here to override values set in environment variables 77 92 # needed to direct requests through the proxy. 78 ndg_security_proxy.proxy.http_proxy = http:// cache.inst.ac.uk:888879 ndg_security_proxy.proxy.https_proxy = http:// cache.inst.ac.uk:888893 ndg_security_proxy.proxy.http_proxy = http://wwwcache.rl.ac.uk:8080 94 ndg_security_proxy.proxy.https_proxy = http://wwwcache.rl.ac.uk:8080 80 95 ndg_security_proxy.proxy.no_proxy = localhost 81 96 97 ################################################################################ 98 99 [filter:CertificateSubjectEnvironMiddleware] 100 paste.filter_app_factory = ndg.security.server.wsgi.client_proxy.environ_certificate:CertificateSubjectEnvironMiddleware.filter_app_factory 101 cert_subject.certEnvKeyName = oauth2client.token 102 #cert_subject.remoteUserKeyName = REMOTE_USER 103 104 ######################################## 105 106 [filter:SessionHandlerFilter] 107 paste.filter_app_factory=ndg.security.server.wsgi.session:SessionHandlerMiddleware.filter_app_factory 108 109 # Default URI to return to if middleware wasn't able to set via HTTP_REFERER or 110 # passed return to query argument 111 sessionHandler.defaultLogoutReturnToURI = %(baseURI)s 112 sessionHandler.sessionKey = %(beakerSessionKeyName)s 113 sessionHandler.signoutPath = /logout 114 115 ######################################## 116 117 # 118 # Authorisation filter contains a Policy Enforcement Point which enforces access 119 # control decisions made by a separate Authorisation Service 120 [filter:AuthorisationFilter] 121 # XACML-SAML Profile: 122 paste.filter_app_factory=ndg.security.server.wsgi.authz:XACMLAuthorisationFilter.filter_app_factory 123 # SAML requests and responses: 124 #paste.filter_app_factory=ndg.security.server.wsgi.authz:AuthorisationFilter.filter_app_factory 125 126 # Result handler handles the response for HTTP 403 responses set by the 127 # application or the PEP. 128 resultHandler = ndg.security.server.wsgi.authz.result_handler.genshi.GenshiPEPResultHandlerMiddleware 129 #resultHandler.staticContentDir = %(here)s/ndg-security/pep_result_handler 130 resultHandler.baseURL = %(baseURI)s 131 resultHandler.staticContentDir = %(here)s/pep_result_handler 132 resultHandler.heading = Access Denied 133 resultHandler.templateRootDir = %(here)s/pep_result_handler/templates 134 resultHandler.footerText = CEDA WPS Service 135 136 # Settings for the PEP (Policy Enforcement Point) 137 pep.sessionKey = %(beakerSessionKeyName)s 138 # Test authorisation service 139 pep.authzServiceURI = https://localhost/authz/AuthorisationService/ 140 # This cannot be enabled currently for XACMLAuthorisationFilter: 141 pep.cacheDecisions = False 142 pep.subjectIdFormat = urn:esg:openid 143 144 # Including this setting activates a simple PDP local to this PEP which filters 145 # requests to cut down on calls to the authorisation service. This is useful 146 # for example to avoid calling the authorisation service for non-secure content 147 # such as HTML CSS or graphics. Note that filters based on resource URI 148 # requested alone. Subject, action and environment settings are not passed in 149 # the request context to the local PDP. 150 # 151 # The policy content should be set carefully to avoid unintended override of the 152 # authorisation service's policy 153 pep.localPolicyFilePath = %(here)s/ndg-security/request-filter.xml 154 155 # Settings for Policy Information Point used by the Policy Decision Point to 156 # retrieve subject attributes from the Attribute Authority associated with the 157 # resource to be accessed 158 159 # If omitted, DN of SSL Cert is used 160 pep.authzDecisionQuery.issuerName = /C=GB/O=Science and Technology Facilities Council/OU=RAL-SPBU/CN=localhost.badc.rl.ac.uk 161 pep.authzDecisionQuery.issuerFormat = urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName 162 # This is a pep parameter when using XACML profile: 163 #pep.authzDecisionQuery.subjectIdFormat = urn:esg:openid 164 pep.authzDecisionQuery.clockSkewTolerance = 2. 165 pep.authzDecisionQuery.sslCACertDir=%(here)s/certificates 166 pep.authzDecisionQuery.sslCertFilePath=%(here)s/certificates/localhost.crt 167 pep.authzDecisionQuery.sslPriKeyFilePath=%(here)s/certificates/localhost.key 168 169 ############################################################################# 170 82 171 [app:App] 83 paste.app_factory = ndg.oauth.client. wsgi.get_url_app:GetUrlApp.app_factory172 paste.app_factory = ndg.oauth.client.examples.wsgi.get_url_app:GetUrlApp.app_factory 84 173 url = http://localhost:8080/thredds/dodsC/test/testData.nc.ascii 85 174 -
trunk/ndg_oauth/ndg_oauth_client/ndg/oauth/client/examples/config/test_app.ini
r8030 r8057 44 44 #oauth2.oauth2_token_key = oauth2client.token 45 45 # OAuth client configuration 46 oauth2.client_cert = /home/rwilkinson_local/dev/ndg_oauth/certificate/usercert.pem47 oauth2.client_key = /home/rwilkinson_local/dev/ndg_oauth/certificate/userkey.pem48 oauth2.ca_dir = /home/rwilkinson_local/dev/ndg_oauth/ca49 # ca_cert_file = /home/rwilkinson_local/dev/oauthclient/ca.pem46 oauth2.client_cert = %(here)s/certificate/usercert.pem 47 oauth2.client_key = %(here)s/certificate/userkey.pem 48 oauth2.ca_dir = %(here)s/ca 49 # ca_cert_file = 50 50 oauth2.client_id=22 51 51 # OAuth authorization server URLs … … 56 56 57 57 [app:App] 58 paste.app_factory = ndg.oauth.client. wsgi.wsgi_test_app:WsgiTestApp.app_factory58 paste.app_factory = ndg.oauth.client.examples.wsgi.wsgi_test_app:WsgiTestApp.app_factory 59 59 60 60 # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* -
trunk/ndg_oauth/ndg_oauth_client/ndg/oauth/client/examples/wsgi/get_url_app.py
r8026 r8057 26 26 "/get": 'get' 27 27 } 28 TOKEN_ENV_KEYNAME = 'oauth2client.token'29 28 def __init__(self, app, globalConfig, **localConfig): 30 29 self.beakerSessionKeyName = globalConfig['beakerSessionKeyName'] … … 54 53 response = ["<h2>WSGI Test Application - Get URL</h2>"] 55 54 56 # Unprotected:55 # Access to proxy doesn't require certificate. 57 56 ssl_context = ssl_context_util.make_ssl_context() 58 57 -
trunk/ndg_oauth/ndg_oauth_client/ndg/oauth/client/lib/oauth2client.py
r8030 r8057 13 13 import uuid 14 14 15 import ndg.oauth.client.lib.urlfetcher as urlfetcher 15 import ndg.httpsclient.utils as httpsclient_utils 16 import ndg.httpsclient.ssl_context_util as ssl_context_util 16 17 17 18 log = logging.getLogger(__name__) … … 228 229 log.debug("Requesting access token - parameters: %s", parameters) 229 230 data = urllib.urlencode(parameters) 230 response_json = urlfetcher.fetch_stream_from_url( 231 self.client_config.access_token_endpoint, data, ssl_config) 231 response_json = httpsclient_utils.fetch_stream_from_url( 232 self.client_config.access_token_endpoint, 233 httpsclient_utils.Configuration( 234 ssl_context_util.make_ssl_context_from_config(ssl_config)), 235 data) 232 236 response = json.load(response_json) 233 237 access_token = response.get('access_token', None) -
trunk/ndg_oauth/ndg_oauth_client/ndg/oauth/client/wsgi/oauth2_client.py
r8030 r8057 13 13 from webob import Request 14 14 15 from ndg.httpsclient.ssl_context_util import SSlContextConfig 16 from ndg.oauth.client.lib.oauth2client import Oauth2Client 15 17 from ndg.oauth.client.lib.oauth2client import Oauth2ClientConfig 16 18 from ndg.oauth.client.lib.oauth2_myproxy_client import Oauth2MyProxyClient 17 from ndg.httpsclient.ssl_context_util import SSlContextConfig 19 from ndg.oauth.client.lib.render.configuration import RenderingConfiguration 20 from ndg.oauth.client.lib.render.factory import callModuleObject 21 from ndg.oauth.client.lib.render.renderer_interface import RendererInterface 18 22 19 23 log = logging.getLogger(__name__) … … 24 28 """ 25 29 PARAM_PREFIX = 'oauth2.' 30 LAYOUT_PREFIX = 'layout.' 31 ACCESS_TOKEN_TYPE_OPTION = 'access_token_type' 32 AUTHENTICATION_TRIGGER_OPTION = 'authentication_trigger' 33 AUTHENTICATION_TRIGGER_ALWAYS = 'always' 34 AUTHENTICATION_TRIGGER_UNAUTHORIZED = 'unauthorized' 35 AUTHENTICATION_TRIGGER_URL = 'url' 36 AUTHENTICATION_TRIGGER_OPTIONS = [AUTHENTICATION_TRIGGER_ALWAYS, 37 AUTHENTICATION_TRIGGER_UNAUTHORIZED, 38 AUTHENTICATION_TRIGGER_URL] 39 AUTHENTICATION_URL_OPTION = 'authentication_url' 40 AUTHENTICATION_COMPLETE_OPTION = 'login_complete' 26 41 BASE_URL_PATH_OPTION = 'base_url_path' 27 42 CERTIFICATE_REQUEST_PARAMETER_OPTION = 'certificate_request_parameter' 43 REDIRECT_URI = 'oauth_redirect' 44 RENDERER_CLASS_OPTION = 'renderer_class' 45 SCOPE_OPTION = 'scope' 28 46 SESSION_KEY_OPTION = 'session_key' 29 47 SESSION_CALL_CONTEXT_KEY = 'oauth2_call_context' 30 48 TOKEN_KEY_OPTION = 'oauth2_token_key' 31 49 propertyDefaults = { 50 ACCESS_TOKEN_TYPE_OPTION: 'myproxy', 51 AUTHENTICATION_COMPLETE_OPTION: '', 52 AUTHENTICATION_TRIGGER_OPTION: AUTHENTICATION_TRIGGER_ALWAYS, 53 AUTHENTICATION_URL_OPTION: 'oauth_authenticate', 32 54 BASE_URL_PATH_OPTION: '', 33 55 CERTIFICATE_REQUEST_PARAMETER_OPTION: 'certificate_request', 56 RENDERER_CLASS_OPTION: 'ndg.oauth.client.lib.render.genshi_renderer.GenshiRenderer', 57 SCOPE_OPTION: '', 34 58 SESSION_KEY_OPTION: 'beaker.session.oauth2client', 35 59 TOKEN_KEY_OPTION: 'oauth2client.token', 36 60 } 61 LAYOUT_PARAMETERS = ['heading', 62 'title', 63 'message', 64 'leftLogo', 65 'leftAlt', 66 'leftImage', 67 'leftLink', 68 'rightAlt', 69 'rightImage', 70 'rightLink', 71 'footerText', 72 'helpIcon', 73 'client_id', 74 'client_name', 75 'scope'] 76 37 77 client_instances = {} 38 78 … … 53 93 self._app = app 54 94 self._set_configuration(prefix, local_conf) 55 self._oauth_client_class = Oauth2MyProxyClient 95 if self.access_token_type == 'myproxy': 96 log.debug("Setting client as Oauth2MyProxyClient") 97 self._oauth_client_class = Oauth2MyProxyClient 98 self._token_retriever_class = MyProxyTokenRetriever 99 else: 100 log.debug("Setting client as Oauth2Client") 101 self._oauth_client_class = Oauth2Client 102 self._token_retriever_class = TokenRetriever 103 104 self._renderingConfiguration = RenderingConfiguration( 105 self.LAYOUT_PARAMETERS, 106 prefix + self.LAYOUT_PREFIX, 107 local_conf) 108 self.renderer = callModuleObject(self.renderer_class, 109 objectName=None, moduleFilePath=None, 110 objectType=RendererInterface, 111 objectArgs=None, objectProperties=None) 56 112 57 113 def __call__(self, environ, start_response): … … 70 126 log.debug("Request host_url: %s", req.host_url) 71 127 log.debug("Request application_url: %s", req.application_url) 128 is_redirect_back = False 72 129 original_environ = {'PATH_INFO': environ['PATH_INFO'], 73 130 'QUERY_STRING': environ['QUERY_STRING'], 74 'SCRIPT_NAME': environ['SCRIPT_NAME']} 75 log.debug("Request environ: %s", environ) 131 'SCRIPT_NAME': environ['SCRIPT_NAME'], 132 'url': req.url} 133 #log.debug("Request environ: %s", environ) 76 134 77 135 # Get session. … … 82 140 '"%s" found in environ' % self.session_env_key) 83 141 142 # Determine trigger for starting authentication process. 143 authenticate_before_delegating = False 144 authenticate_on_unauthorized = False 145 is_authentication_url = (environ['PATH_INFO'].strip('/') == 146 self.authentication_url) 147 if (self.authentication_trigger == 148 self.__class__.AUTHENTICATION_TRIGGER_ALWAYS): 149 authenticate_before_delegating = True 150 elif (self.authentication_trigger == 151 self.__class__.AUTHENTICATION_TRIGGER_URL): 152 if is_authentication_url: 153 authenticate_before_delegating = True 154 elif (self.authentication_trigger == 155 self.__class__.AUTHENTICATION_TRIGGER_UNAUTHORIZED): 156 authenticate_on_unauthorized = True 157 84 158 # Check whether redirecting back after requesting authorization. 159 redirect_url = None 85 160 if self.client_config.is_redirect_uri(req.application_url, req.url): 86 161 log.debug("Redirected back after requesting authorization.") 162 is_redirect_back = True 87 163 token = self._get_token_after_redirect(session, req) 88 164 original_environ = session[self.__class__.SESSION_CALL_CONTEXT_KEY] 89 165 else: 90 # Start the OAuth2 transaction to get a certificate.166 # Start the OAuth2 transaction to get a token. 91 167 log.debug("Starting OAuth2 protocol") 92 (token, redirect_url) = self._get_token(session, req.application_url) 93 if redirect_url: 94 session[self.__class__.SESSION_CALL_CONTEXT_KEY] = original_environ 168 (token, redirect_url) = self._get_token(session, 169 req.application_url) 170 if authenticate_before_delegating and redirect_url: 171 session[self.__class__.SESSION_CALL_CONTEXT_KEY 172 ] = original_environ 95 173 session.save() 174 log.debug("Redirecting to %s", redirect_url) 96 175 start_response(self._get_http_status_string(httplib.FOUND), 97 176 [('Location', redirect_url)]) 98 177 return [] 99 178 179 local_start_response = start_response 100 180 if token: 181 log.debug("Setting token in environ[%s]=%s", self.token_env_key, 182 token) 101 183 environ[self.token_env_key] = token 184 elif authenticate_on_unauthorized and redirect_url: 185 def local_start_response(status, response_headers, exc_info=None): 186 status_code = status.split(' ')[0] 187 log.debug("Response HTTP status %s", status_code) 188 if status_code == str(httplib.UNAUTHORIZED): 189 session[self.__class__.SESSION_CALL_CONTEXT_KEY 190 ] = original_environ 191 session.save() 192 log.debug("Redirecting to %s", redirect_url) 193 start_response(self._get_http_status_string(httplib.FOUND), 194 [('Location', redirect_url)]) 195 return [] 196 else: 197 return start_response(status, response_headers, exc_info) 198 199 if is_authentication_url: 200 c = {'baseURL': req.application_url} 201 response = self.renderer.render(self.authentication_complete, 202 self._renderingConfiguration.merged_parameters(c)) 203 start_response(self._get_http_status_string(httplib.OK), 204 [('Content-type', 'text/html'), 205 ('Content-length', str(len(response))) 206 ]) 207 return [response] 208 # response = "OAuth authentication complete" 209 # start_response(("%d %s" % 210 # (httplib.OK, httplib.responses[httplib.OK])), 211 # [('Content-type', 'text/plain'), 212 # ('Content-length', str(len(response))) 213 # ]) 214 # return [response] 102 215 103 216 # Ensure that the URL is that prior to authentication redirection. 104 environ['PATH_INFO'] = original_environ['PATH_INFO'] 105 environ['QUERY_STRING'] = original_environ['QUERY_STRING'] 106 107 app_iter = self._app(environ, start_response) 217 if is_redirect_back: 218 original_url = original_environ['url'] 219 log.debug("Redirecting to %s", original_url) 220 start_response(self._get_http_status_string(httplib.FOUND), 221 [('Location', original_url)]) 222 return [] 223 # environ['PATH_INFO'] = original_environ['PATH_INFO'] 224 # environ['QUERY_STRING'] = original_environ['QUERY_STRING'] 225 # environ['SCRIPT_NAME'] = original_environ['SCRIPT_NAME'] 226 227 app_iter = self._app(environ, local_start_response) 108 228 return app_iter 109 229 … … 119 239 """ 120 240 cls = self.__class__ 241 self.access_token_type = cls._get_config_option(prefix, local_conf, 242 cls.ACCESS_TOKEN_TYPE_OPTION) 243 self.authentication_complete = cls._get_config_option(prefix, 244 local_conf, cls.AUTHENTICATION_COMPLETE_OPTION) 245 self.authentication_trigger = cls._get_config_option( 246 prefix, local_conf, cls.AUTHENTICATION_TRIGGER_OPTION).lower() 247 if self.authentication_trigger not in cls.AUTHENTICATION_TRIGGER_OPTIONS: 248 raise Exception("Illegal value for %s option; expected one of %s" % 249 self.authentication_trigger_str, 250 cls.AUTHENTICATION_TRIGGER_OPTIONS) 251 self.authentication_url = cls._get_config_option( 252 prefix, local_conf, cls.AUTHENTICATION_URL_OPTION).strip('/') 253 self.renderer_class = cls._get_config_option(prefix, local_conf, cls.RENDERER_CLASS_OPTION) 254 self.scope = cls._get_config_option(prefix, local_conf, cls.SCOPE_OPTION) 121 255 self.session_env_key = cls._get_config_option(prefix, local_conf, cls.SESSION_KEY_OPTION) 122 256 self.token_env_key = self._get_config_option(prefix, local_conf, cls.TOKEN_KEY_OPTION) … … 136 270 access_token_endpoint = cls._get_config_option(prefix, local_conf, 'access_token_endpoint') 137 271 base_url_path = cls._get_config_option(prefix, local_conf, cls.BASE_URL_PATH_OPTION) 138 redirect_uri = 'oauth_redirect'272 redirect_uri = cls.REDIRECT_URI 139 273 self.client_config = Oauth2ClientConfig( 140 274 client_id, authorization_endpoint, access_token_endpoint, … … 173 307 self.client_config, create=True) 174 308 175 callback = TokenRetriever(client)309 callback = self._token_retriever_class(client) 176 310 177 311 (result, redirect_url) = client.call_with_access_token( 178 s cope='', application_url=application_url, callback=callback)312 self.scope, application_url, callback) 179 313 session.save() 180 314 … … 193 327 if client: 194 328 # Return callback result. 195 callback = TokenRetriever(client)329 callback = self._token_retriever_class(client) 196 330 result = client.call_with_access_token_redirected_back(req, 197 331 callback, … … 210 344 211 345 class TokenRetriever(object): 346 def __init__(self, client): 347 self.client = client 348 349 def __call__(self, access_token, error, error_description): 350 """ 351 Returns authorization token. 352 @type access_token: type of access token 353 @param access_token: access token 354 @type error: str 355 @param error: OAuth error string 356 @type error_description: str 357 @param error_description: error description 358 @rtype: type of access token 359 @return: access token 360 """ 361 if error: 362 return None 363 return self.client.access_token 364 365 class MyProxyTokenRetriever(object): 212 366 def __init__(self, client): 213 367 self.client = client … … 231 385 """ 232 386 if error: 233 return ("", ("Token not available because of error: %s - %s" % (error, error_description))) 387 return None 388 # return ("", ("Token not available because of error: %s - %s" % (error, error_description))) 234 389 return (self.client.private_key, self.client.access_token) -
trunk/ndg_oauth/ndg_oauth_client/serve.py
r8030 r8057 1 1 from paste.script.serve import ServeCommand 2 2 3 ServeCommand("serve").run(["get_url_app_proxy.ini"]) 3 ServeCommand("serve").run(["get_url_using_token_app2.ini"]) 4 #ServeCommand("serve").run(["req_cert_app.ini"]) 5 #ServeCommand("serve").run(["get_url_app_proxy2.ini"]) 6 #ServeCommand("serve").run(["get_url_app_proxy.ini"]) 4 7 #ServeCommand("serve").run(["test_app.ini"]) 5 8 #ServeCommand("serve").run(["development.ini"]) -
trunk/ndg_oauth/ndg_oauth_server/client_register.ini
r8030 r8057 10 10 #id=477bfc8c-a739-45b3-a63b-5b1662cc12d7 11 11 type=confidential 12 redirect_uris=http:// localhost:5001/client/redirect_target13 authentication_data=/O=STFC/OU=BADC/OU=simpleCA- localhost/OU=badc.rl.ac.uk/CN=test1.client12 redirect_uris=http://ice.badc.rl.ac.uk:5001/client/redirect_target 13 authentication_data=/O=STFC/OU=BADC/OU=simpleCA-ice.badc.rl.ac.uk/OU=badc.rl.ac.uk/CN=test1.client 14 14 15 15 [client:test2] 16 name= test216 name=WPS on Ice 17 17 id=22 18 18 #id=691ad8cc-293c-4fbe-b8eb-980fcd621157 19 19 type=confidential 20 redirect_uris=http:// localhost:5002/oauth2/oauth_redirect21 authentication_data=/O=STFC/OU=BADC/OU=simpleCA- localhost/OU=badc.rl.ac.uk/CN=test.client20 redirect_uris=http://ice.badc.rl.ac.uk:5002/oauth2/oauth_redirect,http://ice.badc.rl.ac.uk:5005/oauth2/oauth_redirect 21 authentication_data=/O=STFC/OU=BADC/OU=simpleCA-ice.badc.rl.ac.uk/OU=badc.rl.ac.uk/CN=test.client -
trunk/ndg_oauth/ndg_oauth_server/development.ini
r8030 r8057 18 18 host = 0.0.0.0 19 19 port = 5000 20 ssl_pem = /home/rwilkinson_local/dev/MyProxyWebService/host0.pem20 ssl_pem = %(here)s/host.pem 21 21 22 22 [pipeline:main] 23 pipeline = BeakerSessionFilter repoze_who MyProxyClient OAuth2Authz OAuth2Server 23 pipeline = BeakerSessionFilter 24 repoze_who 25 AuthnForm 26 MyProxyClient 27 OAuth2Authz 28 OAuth2ServerFilterApp 29 # OAuth2Server 24 30 25 31 # This filter sets up a server side session linked to a cookie. The session … … 34 40 environ_key = %(beakerSessionKeyName)s 35 41 beaker.session.secret = somesecret 36 beaker.cache.data_dir = %(here)s/authn/beaker/cache 42 #beaker.cache.data_dir = %(here)s/authn/beaker/cache 43 beaker.session.type = file 37 44 beaker.session.data_dir = %(here)s/authn/beaker/sessions 38 45 … … 42 49 log_file = stdout 43 50 log_level = debug 51 52 [filter:AuthnForm] 53 paste.filter_app_factory = ndg.oauth.server.wsgi.authentication_filter:AuthenticationFormMiddleware.filter_app_factory 54 authenticationForm.base_url_path = /authentication 55 authenticationForm.client_register=%(here)s/client_register.ini 56 # If true, client authorization included on login form, otherwise the separate 57 # client authorization form is always used. 58 authenticationForm.combined_authorization = True 59 authenticationForm.login_cancelled = %(here)s/ndg/oauth/server/templates/login_cancelled.html 60 authenticationForm.login_form = %(here)s/ndg/oauth/server/templates/login_form.html 61 authenticationForm.return_url_param = returnurl 62 authenticationForm.session_key_name = %(beakerSessionKeyName)s 63 # Authentication form configuration 64 authenticationForm.layout.heading = OAuth Login 65 authenticationForm.layout.title = OAuth Login 66 authenticationForm.layout.rightLink = http://ceda.ac.uk/ 67 authenticationForm.layout.rightImage = /oas/layout/CEDA_RightButton60.png 68 #authenticationForm.layout.rightImage = /layout/CEDA_RightButton60.png 69 authenticationForm.layout.rightAlt = Centre for Environmental Data Archival 70 authenticationForm.layout.footerText = This site is for test purposes only. 71 authenticationForm.layout.helpIcon = /oas/layout/icons/help.png 72 #authenticationForm.layout.helpIcon = /layout/icons/help.png 44 73 45 74 [filter:MyProxyClient] … … 51 80 # fully qualified domain name or else set the MYPROXY_SERVER environment 52 81 # variable. See the documentation for the MyProxyClient egg for details 53 myproxy.client.hostname = localhost82 myproxy.client.hostname = myproxy.ac.uk 54 83 #myproxy.client.port = 7512 55 84 … … 57 86 # server that it fronts e.g. set to /etc/grid-security/certificates. For these 58 87 # tests set to local ca directory 59 #MyProxy.client.caCertDir = %(here)s/ca 60 myproxy.client.caCertDir = /home/users/rwilkinson/.esg/certificates_ice 88 myproxy.client.caCertDir = %(here)s/ca 61 89 62 90 [filter:OAuth2Authz] … … 69 97 oauth2authorization.session_key_name = %(beakerSessionKeyName)s 70 98 #oauth2authorization.user_identifier_key=REMOTE_USER 99 # Authorization form configuration 100 oauth2authorization.layout.heading = OAuth Authorisation 101 oauth2authorization.layout.title = OAuth Authorisation 102 oauth2authorization.layout.rightLink = http://ceda.ac.uk/ 103 oauth2authorization.layout.rightImage = /layout/CEDA_RightButton60.png 104 oauth2authorization.layout.rightAlt = Centre for Environmental Data Archival 105 oauth2authorization.layout.footerText = This site is for test purposes only. 106 oauth2authorization.layout.helpIcon = /layout/icons/help.png 71 107 72 108 [app:OAuth2Server] … … 75 111 # OAuth2 server configuration options - defaults are commented out. 76 112 #oauth2server.access_token_lifetime=86400 77 # Allowed values: myproxy (default) or bearer (which returns a UUID for testing purposes only)113 # Allowed values: myproxy (default) or bearer (which returns a UUID) 78 114 #oauth2server.access_token_type=myproxy 115 oauth2server.access_token_type=bearer 79 116 #oauth2server.authorization_grant_lifetime=600 80 117 oauth2server.base_url_path=/oauth … … 82 119 # Allowed values: certificate (default) or none. 83 120 #oauth2server.client_authentication_method=certificate 121 oauth2server.client_authentication_method=none 84 122 #oauth2server.client_authorization_url=client_authorization/authorize 85 123 #oauth2server.client_authorizations_key=client_authorizations 86 124 oauth2server.client_register=%(here)s/client_register.ini 87 125 #oauth2server.myproxy_client_key=myproxy.server.wsgi.middleware.MyProxyClientMiddleware.myProxyClient 88 oauth2server.myproxy_global_password= changeme126 oauth2server.myproxy_global_password=i93rRugz 89 127 #oauth2server.session_key_name=beaker.session.oauth2server 90 128 #oauth2server.user_identifier_key=REMOTE_USER … … 103 141 # data_dir is used if lock_dir not set: 104 142 #oauth2server.cache.authorizationgrantregister.lock_dir 143 144 [filter-app:OAuth2ServerFilterApp] 145 use = egg:Paste#httpexceptions 146 next = cascade 147 148 [composit:cascade] 149 use = egg:Paste#cascade 150 app1 = OAuth2Server 151 app2 = StaticContent 152 catch = 404 153 154 [app:StaticContent] 155 use = egg:Paste#static 156 document_root = %(here)s/static 105 157 106 158 # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/lib/authorization_server.py
r8033 r8057 364 364 return 365 365 366 def check_token(self, request ):366 def check_token(self, request, scope=None): 367 367 """ 368 368 Simple service that could be used to validate bearer tokens. It would … … 388 388 @param request: HTTP request object 389 389 390 @type scope: str 391 @param scope: required scope 392 390 393 @rtype: tuple: (str, int, str) 391 394 @return: tuple ( 392 395 OAuth JSON response 393 HTTP status if error396 HTTP status 394 397 error description 395 398 ) … … 399 402 error = 'invalid_request' 400 403 else: 401 access_token = request.params['access_token'] 402 scope = request.params.get('scope', None) 403 (token, error) = self.access_token_register.get_token(access_token, scope) 404 404 access_token = params['access_token'] 405 if scope: 406 required_scope = scope 407 else: 408 required_scope = params.get('scope', None) 409 (token, error) = self.access_token_register.get_token(access_token, 410 required_scope) 411 405 412 status = {'invalid_request': httplib.BAD_REQUEST, 406 'invalid_token': httplib. UNAUTHORIZED,413 'invalid_token': httplib.FORBIDDEN, 407 414 None: httplib.OK}.get(error, httplib.BAD_REQUEST) 408 415 … … 411 418 content_dict['error'] = error 412 419 content = json.dumps(content_dict) 413 return (content, None, None) 420 return (content, status, error) 421 422 def get_registered_token(self, request, scope=None): 423 """ 424 Checks that a token in the request is valid. It would 425 be called from a resource service that trusts this authorization 426 service. This is not part of the OAuth specification. 427 428 Request parameters 429 430 access_token 431 REQUIRED. Bearer token 432 scope 433 OPTIONAL. Scope 434 435 Response: 436 application/json format: 437 status 438 HTTP status indicating the access control decision 439 error 440 error as described in 441 http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-5.2 442 443 @type request: webob.Request 444 @param request: HTTP request object 445 446 @type scope: str 447 @param scope: required scope 448 449 @rtype: tuple: (str, int, str) 450 @return: tuple ( 451 access token 452 HTTP status 453 error description 454 ) 455 """ 456 params = request.params 457 token = None 458 if 'access_token' not in params: 459 error = 'invalid_request' 460 else: 461 access_token = params['access_token'] 462 if scope: 463 required_scope = scope 464 else: 465 required_scope = params.get('scope', None) 466 (token, error) = self.access_token_register.get_token(access_token, 467 required_scope) 468 469 status = {'invalid_request': httplib.BAD_REQUEST, 470 'invalid_token': httplib.FORBIDDEN, 471 'insufficient_scope': httplib.FORBIDDEN, 472 None: httplib.OK}.get(error, httplib.BAD_REQUEST) 473 474 return (token, status, error) 414 475 415 476 def is_registered_client(self, request): -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/lib/register/access_token.py
r8030 r8057 12 12 13 13 from ndg.oauth.server.lib.register.register_base import RegisterBase 14 import ndg.oauth.server.lib.register.scopeutil as scopeutil 14 15 15 16 log = logging.getLogger(__name__) … … 23 24 self.token_type = token_type 24 25 self.grant = grant 25 self.scope = grant.scope.split() if grant.scope else []26 self.scope = scopeutil.scopeStringToList(grant.scope_str) 26 27 self.timestamp = datetime.now() 27 28 self.lifetime = lifetime … … 41 42 42 43 def add_token(self, token): 44 """Adds a token to the register. 45 @type token: AccessToken 46 @param token: access token 47 """ 43 48 if self.has_key(token.token_id): 44 49 # Internal error … … 47 52 48 53 self.set_value(token.token_id, token) 54 log.debug("Added token of ID: %s", token.token_id) 49 55 return True 50 56 51 57 def get_token(self, token_id, scope): 58 """Retrieves a registered token by token ID and required scope. 59 @type token_id: basestring 60 @param token_id: token ID 61 @type scope: basestring 62 @param scope: required scopes as space separated string 63 """ 52 64 try: 53 65 token = self.get_value(token_id) 54 66 except KeyError: 67 log.debug("Request for token of ID that is not registered: %s", 68 token_id) 55 69 return (None, 'invalid_token') 56 70 … … 62 76 return (None, 'invalid_token') 63 77 # Check scope 64 if scope and (scope not in token.scope): 78 if not scopeutil.isScopeGranted(token.scope, 79 scopeutil.scopeStringToList(scope)): 65 80 log.debug("Request for token of ID: %s - token was not granted scope %s", 66 81 token_id, scope) 67 return (None, 'in valid_token')82 return (None, 'insufficient_scope') 68 83 return (token, None) -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/lib/register/authorization_grant.py
r8030 r8057 24 24 self.redirect_uri = request.redirect_uri 25 25 # Allow for authorized scope to be different from requested scope. 26 self.scope = (scope if scope is not None else request.scope)26 self.scope_str = (scope if scope is not None else request.scope) 27 27 self.additional_data = additional_data 28 28 self.timestamp = datetime.utcnow() -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/lib/register/client_authorization.py
r7952 r8057 8 8 __revision__ = "$Id$" 9 9 10 import ndg.oauth.server.lib.register.scopeutil as scopeutil 11 10 12 class ClientAuthorization(object): 11 13 """ … … 15 17 self.user = user 16 18 self.client_id = client_id 17 self.scope = scope 19 self.scope = scopeutil.scopeStringToList(scope) 18 20 self.is_authorized = is_authorized 19 21 20 22 def eq_authz_basis(self, other): 23 """Determines whether a requested client authorization is equivalent to 24 a granted one. 25 @type other: ClientAuthorization 26 @param other: requested authorization 27 @rtype: bool 28 @return: True if the user and client ID are the same and if there are no 29 requested scopes that are not granted, otherwise False 30 """ 21 31 return ((self.user == other.user) 22 32 and (self.client_id == other.client_id) 23 and (self.scope ==other.scope))33 and scopeutil.isScopeGranted(self.scope, other.scope)) 24 34 25 35 def __repr__(self): … … 56 66 def __repr__(self): 57 67 s = [] 58 for u , uv in self.register.iteritems():59 for c , cv in uv.iteritems():68 for uv in self.register.itervalues(): 69 for cv in uv.itervalues(): 60 70 s.append(cv.__repr__()) 61 71 return ' '.join(s) -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/lib/render/genshi_renderer.py
r8030 r8057 8 8 __revision__ = "$Id$" 9 9 10 from genshi.template import MarkupTemplate 10 import os 11 12 #from genshi.template import MarkupTemplate 13 from genshi.template import TemplateLoader 11 14 12 15 from ndg.oauth.server.lib.render.renderer_interface import RendererInterface … … 24 27 @return: rendered template 25 28 """ 26 tmpl_file = open(filename) 27 tmpl = MarkupTemplate(tmpl_file) 28 tmpl_file.close() 29 fname = os.path.basename(filename) 30 dirname = os.path.dirname(filename) 31 loader = TemplateLoader(dirname, auto_reload=True) 32 tmpl = loader.load(fname) 29 33 response = tmpl.generate(c=parameters).render('html') 30 34 return response 35 36 # def render(self, filename, parameters): 37 # """Render a page from a template. 38 # @type filename: basestring 39 # @param filename: filename of template 40 # @type parameters: dict 41 # @param parameters: parameters to substitute into template 42 # @rtype: basestring 43 # @return: rendered template 44 # """ 45 # tmpl_file = open(filename) 46 # tmpl = MarkupTemplate(tmpl_file) 47 # tmpl_file.close() 48 # response = tmpl.generate(c=parameters).render('html') 49 # return response -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/templates/auth_client_form.html
r7950 r8057 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" 3 xmlns:py="http://genshi.edgewall.org/" 4 xmlns:xi="http://www.w3.org/2001/XInclude" 5 lang="en"> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 8 <title>Login</title> 9 </head> 10 <body> 11 <form method="post" action="${c.submit_url}"> 12 <table border="0" style="margin-left: auto; margin-right: auto;"> 13 <tr> 14 <td align="center" colspan="2"> 15 Do you grant permission to client "${c.client_name}"? 16 </td> 17 </tr> 18 <tr> 19 <td align="center" colspan="2"> 20 1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 2 <html xmlns:xi="http://www.w3.org/2001/XInclude" 3 xmlns="http://www.w3.org/1999/xhtml" 4 xmlns:py="http://genshi.edgewall.org/"> 5 <div py:def="oauthAuthClient()" id="oauthAuthClient"> 6 <form action="$c.submit_url" method="post"> 7 <table cellspacing="0" border="0" cellpadding="5" style="align: left"> 8 <tr align="left"> 9 <td colspan="2"> 10 <p>If you press the OK button you are granting permission to client "${c.client_name}" to use your credentials. 11 Press the cancel button if you do not want to do that.</p> 12 <p>Client details:</p> 21 13 </td> 22 14 </tr> … … 29 21 </td> 30 22 </tr> 31 <tr> 32 <td align="center" colspan="2"> 33 23 <tr py:if="c.scope"> 24 <td> 25 Scope in which credentials are to be used: 26 </td> 27 <td> 28 ${c.scope} 34 29 </td> 35 30 </tr> 36 31 <tr> 37 <td colspan="2" >38 < table border="0" width="100%">39 <tr>40 <td align="center"><input type="submit" value="Yes" name="yes-button"/></td>41 <td align="center"><input type="submit" value="No" name="no-button"/></td>42 < /tr>43 </ table>32 <td colspan="2" align="right"> 33 <input type="submit" name="submit" value="OK"/> 34 <input type="submit" name="cancel" value="Cancel"/> 35 <span> 36 <a href="javascript:;" title="Toggle help" onclick="toggleDiv(1,'aboutOpenID','shown','hidden','div'); return false;"> 37 <img src="$c.helpIcon" alt="Toggle help" class="helpicon"/></a> 38 </span> 44 39 </td> 45 40 </tr> 46 41 </table> 47 </form> 42 <div id="aboutOpenID" class="hidden"> 43 <div class="helptxt"> 44 <p>You are being asked to log in to an OAuth server. OAuth is a protocol that allows you 45 to grant access to services to act on your behalf while only logging in to the OAuth 46 server. You will be asked to confirm that you wish to delegate authority to the service. 47 </p> 48 <p> 49 This server uses OAuth version 2.0. The latest specification at the time of writing is 50 <a href="http://tools.ietf.org/html/draft-ietf-oauth-v2-24">The OAuth 2.0 Authorization Protocol</a> 51 </p> 52 </div> 53 </div> 54 </form> 55 </div> 56 57 <xi:include href="base.html" /> 58 <head> 59 <replace py:replace="pagehead()"/> 60 </head> 61 <body> 62 <div id="main"> 63 <div py:replace="header()"/> 64 <replace py:replace="oauthAuthClient()"/> 65 <div py:replace="footer(showLoginStatus=False)"/> 66 </div> 48 67 </body> 49 68 </html> -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/wsgi/authorization_filter.py
r8033 r8057 16 16 from ndg.oauth.server.lib.register.client_authorization import ( 17 17 ClientAuthorization, ClientAuthorizationRegister) 18 from ndg.oauth.server.lib.render.configuration import RenderingConfiguration 18 19 from ndg.oauth.server.lib.render.factory import callModuleObject 19 20 from ndg.oauth.server.lib.render.renderer_interface import RendererInterface … … 31 32 SESSION_CALL_CONTEXT_KEY = 'oauth2_client_authorizations_context' 32 33 PARAM_PREFIX = 'oauth2authorization.' 34 LAYOUT_PREFIX = 'layout.' 33 35 # Configuration options 34 36 BASE_URL_PATH_OPTION = 'base_url_path' … … 51 53 USER_IDENTIFIER_KEY_OPTION: 'REMOTE_USER' 52 54 } 55 LAYOUT_PARAMETERS = ['heading', 56 'title', 57 'message', 58 'leftLogo', 59 'leftAlt', 60 'leftImage', 61 'leftLink', 62 'rightAlt', 63 'rightImage', 64 'rightLink', 65 'footerText', 66 'helpIcon'] 53 67 54 68 def __init__(self, app, app_conf, prefix=PARAM_PREFIX, **local_conf): … … 73 87 """ 74 88 self._app = app 89 self._renderingConfiguration = RenderingConfiguration( 90 self.LAYOUT_PARAMETERS, 91 prefix + self.LAYOUT_PREFIX, 92 local_conf) 75 93 self._set_configuration(prefix, local_conf) 76 94 self.client_register = ClientRegister(self.client_register_file) … … 217 235 'client_id': client_id, 218 236 'scope': scope, 219 'submit_url': submit_url} 220 response = self.renderer.render(self.client_authorization_form, c) 237 'submit_url': submit_url, 238 'baseURL': req.application_url} 239 response = self.renderer.render(self.client_authorization_form, 240 self._renderingConfiguration.merged_parameters(c)) 221 241 start_response(self._get_http_status_string(httplib.OK), 222 242 [('Content-type', 'text/html'), … … 249 269 return [response] 250 270 251 if (' yes-button' in req.params) and ('no-button' not in req.params):271 if ('submit' in req.params) and ('cancel' not in req.params): 252 272 log.debug("User authorized client.") 253 273 granted = True -
trunk/ndg_oauth/ndg_oauth_server/ndg/oauth/server/wsgi/oauth2_server.py
r8033 r8057 9 9 10 10 import httplib 11 import json 11 12 import logging 12 13 import urllib … … 20 21 from ndg.oauth.server.lib.authenticate.noop_client_authenticator import NoopClientAuthenticator 21 22 from ndg.oauth.server.lib.authorization_server import AuthorizationServer 22 from ndg.oauth.server.lib.authorize.authorizer import Authorizer23 23 from ndg.oauth.server.lib.authorize.authorizer_storing_identifier import AuthorizerStoringIdentifier 24 from ndg.oauth.server.lib.resource_request.myproxy_cert_request import MyproxyCertRequest 24 25 25 26 log = logging.getLogger(__name__) … … 37 38 """ 38 39 PARAM_PREFIX = 'oauth2server.' 40 CERT_DN_ENVIRON_KEY = 'SSL_CLIENT_S_DN' 39 41 # Configuration options 40 42 ACCESS_TOKEN_LIFETIME_OPTION = 'access_token_lifetime' … … 68 70 '/access_token': 'access_token', 69 71 '/authorize': 'authorize', 70 '/check_token': 'check_token' 72 '/check_token': 'check_token', 73 '/request_certificate': 'request_certificate' 71 74 } 72 75 … … 96 99 if self.access_token_type == 'bearer': 97 100 # Simple bearer token configuration. 98 authorizer = Authorizer(self.authorization_grant_lifetime_seconds)99 101 access_token_generator = BearerTokenGenerator(self.access_token_lifetime_seconds, self.access_token_type) 100 102 elif self.access_token_type == 'myproxy': 101 103 # Configure authorization server to use MyProxy certificates as access tokens. 102 authorizer = AuthorizerStoringIdentifier(103 self.authorization_grant_lifetime_seconds,104 user_identifier_env_key=self.user_identifier_env_key,105 user_identifier_grant_data_key=self.USER_IDENTIFIER_GRANT_DATA_KEY)106 107 104 access_token_generator = MyProxyCertTokenGenerator( 108 105 self.access_token_lifetime_seconds, self.access_token_type, … … 115 112 (self.access_token_type, 116 113 self.ACCESS_TOKEN_TYPE_OPTION)) 114 # Store user identifier with grant - this isn't needed for the OAuth 115 # protocol but is needed to return certificates using MyProxy. 116 authorizer = AuthorizerStoringIdentifier( 117 self.authorization_grant_lifetime_seconds, 118 user_identifier_env_key=self.user_identifier_env_key, 119 user_identifier_grant_data_key=self.USER_IDENTIFIER_GRANT_DATA_KEY) 117 120 118 121 # Determine client authentication type. A 'none' options is allowed so … … 130 133 self.client_register_file, authorizer, client_authenticator, 131 134 access_token_generator, conf) 135 136 self._myproxy_cert_request = MyproxyCertRequest( 137 certificate_request_parameter=self.certificate_request_parameter, 138 myproxy_client_env_key=self.myproxy_client_env_key, 139 myproxy_global_password=self.myproxy_global_password, 140 user_identifier_grant_data_key=self.USER_IDENTIFIER_GRANT_DATA_KEY) 132 141 133 142 def __call__(self, environ, start_response): … … 177 186 @return: WSGI response 178 187 """ 188 log.debug("authorize called") 189 # Stop immediately if the client is not registered. 190 (error, error_description 191 ) = self._authorizationServer.is_registered_client(req) 192 if error: 193 log.debug("Error checking if client registered: %s - %s", error, 194 error_description) 195 return self._error_response(error, error_description, 196 start_response) 197 179 198 # User authentication is required before authorization can proceed. 180 199 user = req.environ.get(self.user_identifier_env_key) … … 183 202 start_response(self._get_http_status_string(httplib.UNAUTHORIZED), []) 184 203 return [] 185 186 # Stop immediately if the client is not registered.187 (error, error_description188 ) = self._authorizationServer.is_registered_client(req)189 if error:190 return self._error_response(error, error_description,191 start_response)192 204 193 205 # User authorization for the client is also required. … … 270 282 @return: WSGI response 271 283 """ 284 log.debug("access_token called") 272 285 (response, error_status, error_description) = self._authorizationServer.access_token(req) 273 log.debug("Access token response is of type %s", type(response))274 286 if response is None: 275 287 response = '' … … 281 293 ] 282 294 status_str = self._get_http_status_string(error_status if error_status else httplib.OK) 283 295 if error_status: 296 log.debug("Error obtaining access token: %s - %s", status_str, 297 error_description) 298 284 299 start_response(status_str, headers) 285 300 return [response] … … 304 319 ('Content-Type', 'application/json; charset=UTF-8'), 305 320 ('Cache-Control', 'no-store'), 306 ('Content-length', str(len(response))) 321 ('Content-length', str(len(response))), 307 322 ('Pragma', 'no-store') 308 323 ] 309 324 status_str = self._get_http_status_string(error_status if error_status else httplib.OK) 310 325 326 start_response(status_str, headers) 327 return [response] 328 329 def request_certificate(self, req, start_response): 330 """ 331 Resource service to issue a certificate based on a certificate request 332 contained in the request and the identity of the client for whom the 333 access token was issued. 334 @type req: webob.Request 335 @param req: HTTP request object 336 337 @type start_response: 338 @param start_response: WSGI start response function 339 340 @rtype: iterable 341 @return: WSGI response 342 """ 343 log.debug("request_certificate called") 344 cert = None 345 error = None 346 status = httplib.OK 347 dn = req.environ.get(self.CERT_DN_ENVIRON_KEY) 348 if dn: 349 log.debug("Found certificate DN: %s", dn) 350 else: 351 # Client must be authenticated - no other error should be included 352 # in this case. 353 status = httplib.FORBIDDEN 354 355 if status == httplib.OK: 356 (token, status, 357 error) = self._authorizationServer.get_registered_token(req, dn) 358 359 if status == httplib.OK: 360 # Token is valid so get a certificate. 361 cert = self._myproxy_cert_request.get_resource(token, req) 362 if not cert: 363 status = httplib.INTERNAL_SERVER_ERROR 364 365 content_dict = {'status': status} 366 if error: 367 content_dict['error'] = error 368 if cert: 369 content_dict['certificate'] = cert 370 response = json.dumps(content_dict) 371 372 headers = [ 373 ('Content-Type', 'application/json; charset=UTF-8'), 374 ('Cache-Control', 'no-store'), 375 ('Content-length', str(len(response))), 376 ('Pragma', 'no-store') 377 ] 378 status_str = self._get_http_status_string(status if status 379 else httplib.OK) 380 if error: 381 log.debug("Error obtaining certificate: %s - %s", status_str, error) 382 311 383 start_response(status_str, headers) 312 384 return [response] -
trunk/ndg_oauth/ndg_oauth_server/repoze_who.ini
r7950 r8057 2 2 # identificaion and challenge 3 3 use = repoze.who.plugins.redirector:make_plugin 4 login_url = /login.html 4 login_url = /authentication/login_form 5 came_from_param = returnurl 5 6 6 7 [plugin:auth_tkt] … … 58 59 # plugin_name;classifier_name:.. or just plugin_name (good for any) 59 60 plugins = 60 #redirector;browser61 redirector;browser 61 62 basicauth 62 63
Note: See TracChangeset
for help on using the changeset viewer.