1616from openapi_core .schema .request_bodies .exceptions import MissingRequestBody
1717from openapi_core .schema .security_schemes .enums import SecuritySchemeType
1818from openapi_core .schema .servers .exceptions import InvalidServer
19+ from openapi_core .security .exceptions import SecurityError
1920from openapi_core .unmarshalling .schemas .exceptions import (
2021 UnmarshalError , ValidateError ,
2122)
23+ from openapi_core .validation .exceptions import InvalidSecurity
2224from openapi_core .validation .request .datatypes import (
2325 RequestParameters , RequestValidationResult ,
2426)
@@ -45,8 +47,7 @@ def validate(self, request):
4547
4648 try :
4749 security = self ._get_security (request , operation )
48- # TODO narrow exceptions
49- except Exception as exc :
50+ except InvalidSecurity as exc :
5051 return RequestValidationResult ([exc , ], None , None , None )
5152
5253 params , params_errors = self ._get_parameters (
@@ -108,14 +109,16 @@ def _get_security(self, request, operation):
108109 return {}
109110
110111 for security_requirement in security :
111- data = {
112- security_requirement .name : self ._get_security_value (
113- security_requirement .name , request )
114- }
115- if all (value for value in data .values ()):
116- return data
112+ try :
113+ return {
114+ scheme_name : self ._get_security_value (
115+ scheme_name , request )
116+ for scheme_name in security_requirement
117+ }
118+ except SecurityError :
119+ continue
117120
118- return {}
121+ raise InvalidSecurity ()
119122
120123 def _get_parameters (self , request , params ):
121124 errors = []
@@ -196,27 +199,10 @@ def _get_security_value(self, scheme_name, request):
196199 if not scheme :
197200 return
198201
199- if scheme .type == SecuritySchemeType .API_KEY :
200- source = getattr (request .parameters , scheme .apikey_in .value )
201- return source .get (scheme .name )
202- elif scheme .type == SecuritySchemeType .HTTP :
203- auth_header = request .parameters .header .get ('Authorization' )
204- try :
205- auth_type , encoded_credentials = auth_header .split (' ' , 1 )
206- except ValueError :
207- raise ValueError ('Could not parse authorization header.' )
208-
209- if auth_type .lower () != scheme .scheme .value :
210- raise ValueError (
211- 'Unknown authorization method %s' % auth_type )
212- try :
213- return base64 .b64decode (
214- encoded_credentials .encode ('ascii' ), validate = True
215- ).decode ('latin1' )
216- except binascii .Error :
217- raise ValueError ('Invalid base64 encoding.' )
218-
219- warnings .warn ("Only api key security scheme type supported" )
202+ from openapi_core .security .factories import SecurityProviderFactory
203+ security_provider_factory = SecurityProviderFactory ()
204+ security_provider = security_provider_factory .create (scheme )
205+ return security_provider (request )
220206
221207 def _get_parameter_value (self , param , request ):
222208 location = request .parameters [param .location .value ]
0 commit comments