5050import java .security .cert .X509Certificate ;
5151import java .util .*;
5252
53+ import static io .swagger .v3 .oas .models .security .SecurityScheme .In .QUERY ;
54+ import static io .swagger .v3 .oas .models .security .SecurityScheme .In .HEADER ;
55+
56+
5357public class GenerateTemplate implements APIMCLIServiceProvider {
5458
5559
@@ -59,6 +63,11 @@ public class GenerateTemplate implements APIMCLIServiceProvider {
5963 public static final String PASS_THROUGH = "Pass Through" ;
6064 public static final String REMOVE_CREDENTIALS_ON_SUCCESS = "removeCredentialsOnSuccess" ;
6165 public static final String TOKEN_STORE = "tokenStore" ;
66+ public static final String TAKE_FROM = "takeFrom" ;
67+ public static final String OAUTH_TOKEN_CLIENT_ID = "${oauth.token.client_id}" ;
68+ public static final String USE_CLIENT_REGISTRY = "useClientRegistry" ;
69+ public static final String SUBJECT_SELECTOR = "subjectSelector" ;
70+ public static final String HEADER_STR = "HEADER" ;
6271
6372 @ Override
6473 public String getName () {
@@ -292,42 +301,71 @@ public Map<String, InboundProfile> addInboundPerMethodOverride(OpenAPI openAPI,
292301 operationId = httpMethod .name () + " " + key ;
293302 }
294303 List <SecurityRequirement > securityRequirements = operation .getSecurity ();
295- if (securityRequirements == null ) {
296- SecurityProfile passThroughProfile = createPassThroughSecurityProfile ();
297- inboundProfile .setSecurityProfile (passThroughProfile .getName ());
298- inboundProfiles .put (operationId , inboundProfile );
299- securityProfiles .add (passThroughProfile );
300- } else {
301-
302- for (SecurityRequirement securityRequirement : securityRequirements ) {
303- Set <String > keys = securityRequirement .keySet ();
304- for (String securityKey : keys ) {
305- SecurityScheme securityScheme = openAPI .getComponents ().getSecuritySchemes ().get (securityKey );
306- SecurityScheme .Type type = securityScheme .getType ();
307-
308- if (type == SecurityScheme .Type .OAUTH2 ) {
309- List <String > scopes = securityRequirement .get (securityKey );
310- SecurityProfile oauth2SecurityProfile = createOauthSecurityProfile (operationId , scopes );
311- inboundProfile .setSecurityProfile (oauth2SecurityProfile .getName ());
312- inboundProfiles .put (operationId , inboundProfile );
313- securityProfiles .add (oauth2SecurityProfile );
314- } else if (type == SecurityScheme .Type .APIKEY ) {
315- LOG .warn ("API key is not handled" );
316- } else if (type == SecurityScheme .Type .MUTUALTLS ) {
317- LOG .warn ("Mutual auth is not handled" );
318- }
319- }
320- }
321- }
304+ handleSecurity (openAPI , inboundProfiles , securityRequirements , securityProfiles , inboundProfile , operationId );
322305 }
323306 }
324307 api .setSecurityProfiles (securityProfiles );
325308 return inboundProfiles ;
326309 }
327310
328- public SecurityProfile createPassThroughSecurityProfile () {
311+
312+ public void handleSecurity (OpenAPI openAPI , Map <String , InboundProfile > inboundProfiles , List <SecurityRequirement > securityRequirements , List <SecurityProfile > securityProfiles , InboundProfile inboundProfile , String operationId ) {
313+ if (securityRequirements == null || securityRequirements .isEmpty ()) {
314+ SecurityProfile passThroughProfile = createPassThroughSecurityProfile (operationId );
315+ inboundProfile .setSecurityProfile (passThroughProfile .getName ());
316+ inboundProfiles .put (operationId , inboundProfile );
317+ securityProfiles .add (passThroughProfile );
318+ } else {
319+ for (SecurityRequirement securityRequirement : securityRequirements ) {
320+ Set <String > keys = securityRequirement .keySet ();
321+ for (String securityKey : keys ) {
322+ SecurityScheme securityScheme = openAPI .getComponents ().getSecuritySchemes ().get (securityKey );
323+ mapAPIMSecurity (securityRequirement , securityScheme , inboundProfiles , inboundProfile , securityProfiles , operationId , securityKey );
324+ }
325+ }
326+ }
327+ }
328+
329+ public void mapAPIMSecurity (SecurityRequirement securityRequirement , SecurityScheme securityScheme , Map <String , InboundProfile > inboundProfiles , InboundProfile inboundProfile , List <SecurityProfile > securityProfiles , String operationId , String securityKey ) {
330+ SecurityScheme .Type type = securityScheme .getType ();
331+ if (type == SecurityScheme .Type .OAUTH2 ) {
332+ LOG .info ("mapping oauth2 profile" );
333+ List <String > scopes = securityRequirement .get (securityKey );
334+ SecurityProfile oauth2SecurityProfile = createOauthSecurityProfile (operationId , scopes );
335+ inboundProfile .setSecurityProfile (oauth2SecurityProfile .getName ());
336+ inboundProfiles .put (operationId , inboundProfile );
337+ securityProfiles .add (oauth2SecurityProfile );
338+ } else if (type == SecurityScheme .Type .APIKEY ) {
339+ LOG .info ("mapping API key profile" );
340+ List <String > scopes = securityRequirement .get (securityKey );
341+ SecurityScheme .In in = securityScheme .getIn ();
342+ if (in == SecurityScheme .In .COOKIE ) {
343+ LOG .warn ("API key in cookie not supported" );
344+ return ;
345+ }
346+ String apikeyLocation = in .name ();
347+ String fieldName = securityScheme .getName ();
348+ SecurityProfile apiKeySecurityProfile = createApiKeySecurityProfile (operationId , apikeyLocation , fieldName , scopes );
349+ inboundProfile .setSecurityProfile (apiKeySecurityProfile .getName ());
350+ inboundProfiles .put (operationId , inboundProfile );
351+ securityProfiles .add (apiKeySecurityProfile );
352+ } else if (type == SecurityScheme .Type .MUTUALTLS ) {
353+ LOG .warn ("Mutual auth is not handled" );
354+ } else if (type == SecurityScheme .Type .OPENIDCONNECT || type == SecurityScheme .Type .HTTP && securityScheme .getScheme ().equalsIgnoreCase ("bearer" )) {
355+ LOG .info ("External auth / openid connect is not handled" );
356+ List <String > scopes = securityRequirement .get (securityKey );
357+ SecurityProfile oauth2ExternalSecurityProfile = createOauthExternalSecurityProfile (operationId , scopes );
358+ inboundProfile .setSecurityProfile (oauth2ExternalSecurityProfile .getName ());
359+ inboundProfiles .put (operationId , inboundProfile );
360+ securityProfiles .add (oauth2ExternalSecurityProfile );
361+ } else if (type == SecurityScheme .Type .HTTP && securityScheme .getScheme ().equalsIgnoreCase ("basic" )) {
362+ LOG .warn ("Basic Auth is not handled" );
363+ }
364+ }
365+
366+ public SecurityProfile createPassThroughSecurityProfile (String operationId ) {
329367 SecurityProfile profile = new SecurityProfile ();
330- profile .setName (PASS_THROUGH );
368+ profile .setName (PASS_THROUGH + " " + operationId );
331369 profile .setIsDefault (false );
332370 SecurityDevice securityDevice = new SecurityDevice ();
333371 securityDevice .setName (PASS_THROUGH );
@@ -343,6 +381,60 @@ public SecurityProfile createPassThroughSecurityProfile() {
343381 return profile ;
344382 }
345383
384+ public SecurityProfile createApiKeySecurityProfile (String operationId , String apikeyLocation , String fieldName , List <String > scopes ) {
385+ SecurityProfile profile = new SecurityProfile ();
386+ profile .setName ("apikey " + operationId );
387+ profile .setIsDefault (false );
388+ SecurityDevice securityDevice = new SecurityDevice ();
389+ securityDevice .setName ("API Key" );
390+ securityDevice .setType (DeviceType .apiKey );
391+ securityDevice .setOrder (0 );
392+ Map <String , String > properties = new HashMap <>();
393+ properties .put (REMOVE_CREDENTIALS_ON_SUCCESS , "true" );
394+ if (apikeyLocation .equals (HEADER .name ())) {
395+ properties .put (TAKE_FROM , HEADER_STR );
396+ } else if (apikeyLocation .equals (QUERY .name ())) {
397+ properties .put (TAKE_FROM , "QUERY" );
398+ }
399+ properties .put ("apiKeyFieldName" , fieldName );
400+ if (scopes != null && !scopes .isEmpty ()) {
401+ String scope = String .join (" " , scopes );
402+ properties .put ("scopes" , scope );
403+ properties .put ("scopesMustMatch" , "All" );
404+ }
405+ securityDevice .setProperties (properties );
406+ List <SecurityDevice > securityDevices = new ArrayList <>();
407+ securityDevices .add (securityDevice );
408+ profile .setDevices (securityDevices );
409+ return profile ;
410+ }
411+
412+
413+ public SecurityProfile createOauthExternalSecurityProfile (String operationId , List <String > scopes ) {
414+ SecurityProfile profile = new SecurityProfile ();
415+ profile .setName ("External Oauth2 " + operationId );
416+ profile .setIsDefault (false );
417+ SecurityDevice securityDevice = new SecurityDevice ();
418+ securityDevice .setName ("OAuth (External)" );
419+ securityDevice .setType (DeviceType .oauthExternal );
420+ securityDevice .setOrder (0 );
421+ Map <String , String > properties = new HashMap <>();
422+ properties .put (TOKEN_STORE , "Tokeninfo policy 1" );
423+ properties .put (USE_CLIENT_REGISTRY , "true" );
424+ properties .put (SUBJECT_SELECTOR , OAUTH_TOKEN_CLIENT_ID );
425+ properties .put ("oauth.token.client_id" , OAUTH_TOKEN_CLIENT_ID );
426+ properties .put ("oauth.token.scopes" , "${oauth.token.scopes}" );
427+ properties .put ("oauth.token.valid" , "${oauth.token.valid}" );
428+ String scope = String .join (" " , scopes );
429+ setupOauthProperties (properties , scope );
430+ securityDevice .setProperties (properties );
431+ List <SecurityDevice > securityDevices = new ArrayList <>();
432+ securityDevices .add (securityDevice );
433+ profile .setDevices (securityDevices );
434+ return profile ;
435+ }
436+
437+
346438 public SecurityProfile createOauthSecurityProfile (String operationId , List <String > scopes ) {
347439 SecurityProfile profile = new SecurityProfile ();
348440 profile .setName ("Oauth2 " + operationId );
@@ -490,20 +582,20 @@ private List<SecurityProfile> addInboundSecurityToAPI(String frontendAuthType) t
490582 Map <String , String > properties = new HashMap <>();
491583 if (deviceType .equals (DeviceType .apiKey )) {
492584 properties .put ("apiKeyFieldName" , "KeyId" );
493- properties .put ("takeFrom" , "HEADER" );
585+ properties .put (TAKE_FROM , HEADER_STR );
494586 properties .put (REMOVE_CREDENTIALS_ON_SUCCESS , "true" );
495587 } else if (deviceType .equals (DeviceType .oauth )) {
496588 properties .put (TOKEN_STORE , "OAuth Access Token Store" );
497589 setupOauthProperties (properties , "resource.WRITE, resource.READ" );
498590 } else if (deviceType .equals (DeviceType .oauthExternal )) {
499591 properties .put (TOKEN_STORE , "Tokeninfo policy 1" );
500- properties .put ("useClientRegistry" , "true" );
501- properties .put ("subjectSelector" , "${oauth.token.client_id}" );
592+ properties .put (USE_CLIENT_REGISTRY , "true" );
593+ properties .put (SUBJECT_SELECTOR , OAUTH_TOKEN_CLIENT_ID );
502594 setupOauthProperties (properties , "resource.WRITE, resource.READ" );
503595 } else if (deviceType .equals (DeviceType .authPolicy )) {
504596 properties .put ("authenticationPolicy" , "Custom authentication policy" );
505- properties .put ("useClientRegistry" , "true" );
506- properties .put ("subjectSelector" , "authentication.subject.id" );
597+ properties .put (USE_CLIENT_REGISTRY , "true" );
598+ properties .put (SUBJECT_SELECTOR , "authentication.subject.id" );
507599 properties .put ("descriptionType" , ORIGINAL );
508600 properties .put ("descriptionUrl" , "" );
509601 properties .put ("descriptionMarkdown" , "" );
@@ -521,7 +613,7 @@ private List<SecurityProfile> addInboundSecurityToAPI(String frontendAuthType) t
521613 }
522614
523615 private void setupOauthProperties (Map <String , String > properties , String scopes ) {
524- properties .put ("accessTokenLocation" , "HEADER" );
616+ properties .put ("accessTokenLocation" , HEADER_STR );
525617 properties .put ("authorizationHeaderPrefix" , "Bearer" );
526618 properties .put ("accessTokenLocationQueryString" , "" );
527619 properties .put ("scopesMustMatch" , "All" );
0 commit comments