Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e2e639f

Browse files
committedMar 9, 2023
fix update #2094
1 parent f0be53e commit e2e639f

File tree

4 files changed

+410
-115
lines changed

4 files changed

+410
-115
lines changed
 

‎springdoc-openapi-security/src/main/java/org/springdoc/security/SpringDocSecurityOAuth2Customizer.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.slf4j.LoggerFactory;
2323
import org.springdoc.core.SpringDocAnnotationsUtils;
2424
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
25+
import org.springdoc.security.oauth2.SpringDocOAuth2AuthorizationServerMetadata;
26+
import org.springdoc.security.oauth2.SpringDocOAuth2TokenIntrospection;
2527

2628
import org.springframework.beans.BeansException;
2729
import org.springframework.context.ApplicationContext;
@@ -31,8 +33,6 @@
3133
import org.springframework.security.oauth2.core.OAuth2Error;
3234
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
3335
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
34-
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadata;
35-
import org.springframework.security.oauth2.server.authorization.OAuth2TokenIntrospection;
3636
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationToken;
3737
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenRevocationAuthenticationToken;
3838
import org.springframework.security.oauth2.server.authorization.web.NimbusJwkSetEndpointFilter;
@@ -119,7 +119,7 @@ private void getOAuth2TokenIntrospectionEndpointFilter(OpenAPI openAPI, Security
119119
Object oAuth2EndpointFilter =
120120
new SpringDocSecurityOAuth2EndpointUtils(OAuth2TokenIntrospectionEndpointFilter.class).findEndpoint(securityFilterChain);
121121
if (oAuth2EndpointFilter != null) {
122-
ApiResponses apiResponses = buildApiResponsesWithBadRequest(SpringDocAnnotationsUtils.resolveSchemaFromType(OAuth2TokenIntrospection.class, openAPI.getComponents(), null), openAPI);
122+
ApiResponses apiResponses = buildApiResponsesWithBadRequest(SpringDocAnnotationsUtils.resolveSchemaFromType(SpringDocOAuth2TokenIntrospection.class, openAPI.getComponents(), null), openAPI);
123123
Operation operation = buildOperation(apiResponses);
124124
Schema<?> schema = new ObjectSchema()
125125
.addProperty("token", new StringSchema())
@@ -143,7 +143,7 @@ private void getOAuth2AuthorizationServerMetadataEndpoint(OpenAPI openAPI, Secur
143143
Object oAuth2EndpointFilter =
144144
new SpringDocSecurityOAuth2EndpointUtils(OAuth2AuthorizationServerMetadataEndpointFilter.class).findEndpoint(securityFilterChain);
145145
if (oAuth2EndpointFilter != null) {
146-
ApiResponses apiResponses = buildApiResponses(SpringDocAnnotationsUtils.resolveSchemaFromType(OAuth2AuthorizationServerMetadata.class, openAPI.getComponents(), null));
146+
ApiResponses apiResponses = buildApiResponses(SpringDocAnnotationsUtils.resolveSchemaFromType(SpringDocOAuth2AuthorizationServerMetadata.class, openAPI.getComponents(), null));
147147
Operation operation = buildOperation(apiResponses);
148148
buildPath(oAuth2EndpointFilter, "requestMatcher", openAPI, operation, HttpMethod.GET);
149149
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package org.springdoc.security.oauth2;
2+
3+
import java.net.URL;
4+
import java.time.Instant;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
import io.swagger.v3.oas.annotations.media.Schema;
10+
11+
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadataClaimAccessor;
12+
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadataClaimNames;
13+
14+
/**
15+
* @author bnasslahsen
16+
*/
17+
@Schema(name = "OAuth2AuthorizationServerMetadata")
18+
public class SpringDocOAuth2AuthorizationServerMetadata implements OAuth2AuthorizationServerMetadataClaimAccessor {
19+
20+
21+
@Override
22+
public Map<String, Object> getClaims() {
23+
return null;
24+
}
25+
26+
@Override
27+
public <T> T getClaim(String claim) {
28+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClaim(claim);
29+
}
30+
31+
@Override
32+
public boolean hasClaim(String claim) {
33+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.hasClaim(claim);
34+
}
35+
36+
@Override
37+
public Boolean containsClaim(String claim) {
38+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.containsClaim(claim);
39+
}
40+
41+
@Override
42+
public String getClaimAsString(String claim) {
43+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClaimAsString(claim);
44+
}
45+
46+
@Override
47+
public Boolean getClaimAsBoolean(String claim) {
48+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClaimAsBoolean(claim);
49+
}
50+
51+
@Override
52+
public Instant getClaimAsInstant(String claim) {
53+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClaimAsInstant(claim);
54+
}
55+
56+
@Override
57+
public URL getClaimAsURL(String claim) {
58+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClaimAsURL(claim);
59+
}
60+
61+
@Override
62+
public Map<String, Object> getClaimAsMap(String claim) {
63+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClaimAsMap(claim);
64+
}
65+
66+
@Override
67+
public List<String> getClaimAsStringList(String claim) {
68+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClaimAsStringList(claim);
69+
}
70+
71+
@Override
72+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.ISSUER)
73+
public URL getIssuer() {
74+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getIssuer();
75+
}
76+
77+
@Override
78+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.AUTHORIZATION_ENDPOINT)
79+
public URL getAuthorizationEndpoint() {
80+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getAuthorizationEndpoint();
81+
}
82+
83+
@Override
84+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.TOKEN_ENDPOINT)
85+
public URL getTokenEndpoint() {
86+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getTokenEndpoint();
87+
}
88+
89+
@Override
90+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.TOKEN_ENDPOINT_AUTH_METHODS_SUPPORTED)
91+
public List<String> getTokenEndpointAuthenticationMethods() {
92+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getTokenEndpointAuthenticationMethods();
93+
}
94+
95+
@Override
96+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.JWKS_URI)
97+
public URL getJwkSetUrl() {
98+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getJwkSetUrl();
99+
}
100+
101+
@Override
102+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED)
103+
public List<String> getScopes() {
104+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getScopes();
105+
}
106+
107+
@Override
108+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.RESPONSE_TYPES_SUPPORTED)
109+
public List<String> getResponseTypes() {
110+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getResponseTypes();
111+
}
112+
113+
@Override
114+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.GRANT_TYPES_SUPPORTED)
115+
public List<String> getGrantTypes() {
116+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getGrantTypes();
117+
}
118+
119+
@Override
120+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.REVOCATION_ENDPOINT)
121+
public URL getTokenRevocationEndpoint() {
122+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getTokenRevocationEndpoint();
123+
}
124+
125+
@Override
126+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.REVOCATION_ENDPOINT_AUTH_METHODS_SUPPORTED)
127+
public List<String> getTokenRevocationEndpointAuthenticationMethods() {
128+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getTokenRevocationEndpointAuthenticationMethods();
129+
}
130+
131+
@Override
132+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.INTROSPECTION_ENDPOINT)
133+
public URL getTokenIntrospectionEndpoint() {
134+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getTokenIntrospectionEndpoint();
135+
}
136+
137+
@Override
138+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.INTROSPECTION_ENDPOINT_AUTH_METHODS_SUPPORTED)
139+
public List<String> getTokenIntrospectionEndpointAuthenticationMethods() {
140+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getTokenIntrospectionEndpointAuthenticationMethods();
141+
}
142+
143+
@Override
144+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.REGISTRATION_ENDPOINT)
145+
public URL getClientRegistrationEndpoint() {
146+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getClientRegistrationEndpoint();
147+
}
148+
149+
@Override
150+
@JsonProperty(OAuth2AuthorizationServerMetadataClaimNames.CODE_CHALLENGE_METHODS_SUPPORTED)
151+
public List<String> getCodeChallengeMethods() {
152+
return OAuth2AuthorizationServerMetadataClaimAccessor.super.getCodeChallengeMethods();
153+
}
154+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package org.springdoc.security.oauth2;
2+
3+
import java.net.URL;
4+
import java.time.Instant;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
import io.swagger.v3.oas.annotations.media.Schema;
10+
11+
import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimAccessor;
12+
import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames;
13+
14+
/**
15+
* @author bnasslahsen
16+
*/
17+
@Schema(name = "OAuth2TokenIntrospection")
18+
public class SpringDocOAuth2TokenIntrospection implements OAuth2TokenIntrospectionClaimAccessor {
19+
20+
@Override
21+
public Map<String, Object> getClaims() {
22+
return null;
23+
}
24+
25+
@Override
26+
public <T> T getClaim(String claim) {
27+
return OAuth2TokenIntrospectionClaimAccessor.super.getClaim(claim);
28+
}
29+
30+
@Override
31+
public boolean hasClaim(String claim) {
32+
return OAuth2TokenIntrospectionClaimAccessor.super.hasClaim(claim);
33+
}
34+
35+
@Override
36+
public Boolean containsClaim(String claim) {
37+
return OAuth2TokenIntrospectionClaimAccessor.super.containsClaim(claim);
38+
}
39+
40+
@Override
41+
public String getClaimAsString(String claim) {
42+
return OAuth2TokenIntrospectionClaimAccessor.super.getClaimAsString(claim);
43+
}
44+
45+
@Override
46+
public Boolean getClaimAsBoolean(String claim) {
47+
return OAuth2TokenIntrospectionClaimAccessor.super.getClaimAsBoolean(claim);
48+
}
49+
50+
@Override
51+
public Instant getClaimAsInstant(String claim) {
52+
return OAuth2TokenIntrospectionClaimAccessor.super.getClaimAsInstant(claim);
53+
}
54+
55+
@Override
56+
public URL getClaimAsURL(String claim) {
57+
return OAuth2TokenIntrospectionClaimAccessor.super.getClaimAsURL(claim);
58+
}
59+
60+
@Override
61+
public Map<String, Object> getClaimAsMap(String claim) {
62+
return OAuth2TokenIntrospectionClaimAccessor.super.getClaimAsMap(claim);
63+
}
64+
65+
@Override
66+
public List<String> getClaimAsStringList(String claim) {
67+
return OAuth2TokenIntrospectionClaimAccessor.super.getClaimAsStringList(claim);
68+
}
69+
70+
@Override
71+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.ACTIVE)
72+
public boolean isActive() {
73+
return OAuth2TokenIntrospectionClaimAccessor.super.isActive();
74+
}
75+
76+
@Override
77+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.USERNAME)
78+
public String getUsername() {
79+
return OAuth2TokenIntrospectionClaimAccessor.super.getUsername();
80+
}
81+
82+
@Override
83+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.CLIENT_ID)
84+
public String getClientId() {
85+
return OAuth2TokenIntrospectionClaimAccessor.super.getClientId();
86+
}
87+
88+
@Override
89+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.SCOPE)
90+
public List<String> getScopes() {
91+
return OAuth2TokenIntrospectionClaimAccessor.super.getScopes();
92+
}
93+
94+
@Override
95+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.TOKEN_TYPE)
96+
public String getTokenType() {
97+
return OAuth2TokenIntrospectionClaimAccessor.super.getTokenType();
98+
}
99+
100+
@Override
101+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.EXP)
102+
public Instant getExpiresAt() {
103+
return OAuth2TokenIntrospectionClaimAccessor.super.getExpiresAt();
104+
}
105+
106+
@Override
107+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.IAT)
108+
public Instant getIssuedAt() {
109+
return OAuth2TokenIntrospectionClaimAccessor.super.getIssuedAt();
110+
}
111+
112+
@Override
113+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.NBF)
114+
public Instant getNotBefore() {
115+
return OAuth2TokenIntrospectionClaimAccessor.super.getNotBefore();
116+
}
117+
118+
@Override
119+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.SUB)
120+
public String getSubject() {
121+
return OAuth2TokenIntrospectionClaimAccessor.super.getSubject();
122+
}
123+
124+
@Override
125+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.AUD)
126+
public List<String> getAudience() {
127+
return OAuth2TokenIntrospectionClaimAccessor.super.getAudience();
128+
}
129+
130+
@Override
131+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.ISS)
132+
public URL getIssuer() {
133+
return OAuth2TokenIntrospectionClaimAccessor.super.getIssuer();
134+
}
135+
136+
@Override
137+
@JsonProperty(OAuth2TokenIntrospectionClaimNames.JTI)
138+
public String getId() {
139+
return OAuth2TokenIntrospectionClaimAccessor.super.getId();
140+
}
141+
}

‎springdoc-openapi-security/src/test/resources/results/app10.json

+111-111
Original file line numberDiff line numberDiff line change
@@ -332,14 +332,38 @@
332332
"private": {
333333
"type": "boolean"
334334
},
335-
"keyType": {
336-
"$ref": "#/components/schemas/KeyType"
335+
"algorithm": {
336+
"$ref": "#/components/schemas/Algorithm"
337337
},
338-
"keyUse": {
339-
"$ref": "#/components/schemas/KeyUse"
338+
"x509CertURL": {
339+
"type": "string",
340+
"format": "uri"
340341
},
341-
"keyID": {
342-
"type": "string"
342+
"keyOperations": {
343+
"uniqueItems": true,
344+
"type": "array",
345+
"items": {
346+
"type": "string",
347+
"enum": [
348+
"sign",
349+
"verify",
350+
"encrypt",
351+
"decrypt",
352+
"wrapKey",
353+
"unwrapKey",
354+
"deriveKey",
355+
"deriveBits"
356+
]
357+
}
358+
},
359+
"x509CertThumbprint": {
360+
"$ref": "#/components/schemas/Base64URL"
361+
},
362+
"requiredParams": {
363+
"type": "object",
364+
"additionalProperties": {
365+
"type": "object"
366+
}
343367
},
344368
"parsedX509CertChain": {
345369
"type": "array",
@@ -379,33 +403,6 @@
379403
}
380404
}
381405
},
382-
"sigAlgName": {
383-
"type": "string"
384-
},
385-
"subjectDN": {
386-
"type": "object",
387-
"properties": {
388-
"name": {
389-
"type": "string"
390-
}
391-
}
392-
},
393-
"issuerDN": {
394-
"type": "object",
395-
"properties": {
396-
"name": {
397-
"type": "string"
398-
}
399-
}
400-
},
401-
"notBefore": {
402-
"type": "string",
403-
"format": "date-time"
404-
},
405-
"notAfter": {
406-
"type": "string",
407-
"format": "date-time"
408-
},
409406
"extendedKeyUsage": {
410407
"type": "array",
411408
"items": {
@@ -459,6 +456,33 @@
459456
"type": "boolean"
460457
}
461458
},
459+
"sigAlgName": {
460+
"type": "string"
461+
},
462+
"subjectDN": {
463+
"type": "object",
464+
"properties": {
465+
"name": {
466+
"type": "string"
467+
}
468+
}
469+
},
470+
"issuerDN": {
471+
"type": "object",
472+
"properties": {
473+
"name": {
474+
"type": "string"
475+
}
476+
}
477+
},
478+
"notBefore": {
479+
"type": "string",
480+
"format": "date-time"
481+
},
482+
"notAfter": {
483+
"type": "string",
484+
"format": "date-time"
485+
},
462486
"signature": {
463487
"type": "array",
464488
"items": {
@@ -525,44 +549,20 @@
525549
}
526550
}
527551
},
528-
"requiredParams": {
529-
"type": "object",
530-
"additionalProperties": {
531-
"type": "object"
532-
}
533-
},
534-
"x509CertThumbprint": {
535-
"$ref": "#/components/schemas/Base64URL"
536-
},
537-
"keyOperations": {
538-
"uniqueItems": true,
539-
"type": "array",
540-
"items": {
541-
"type": "string",
542-
"enum": [
543-
"sign",
544-
"verify",
545-
"encrypt",
546-
"decrypt",
547-
"wrapKey",
548-
"unwrapKey",
549-
"deriveKey",
550-
"deriveBits"
551-
]
552-
}
553-
},
554-
"x509CertURL": {
555-
"type": "string",
556-
"format": "uri"
557-
},
558552
"x509CertChain": {
559553
"type": "array",
560554
"items": {
561555
"$ref": "#/components/schemas/Base64"
562556
}
563557
},
564-
"algorithm": {
565-
"$ref": "#/components/schemas/Algorithm"
558+
"keyType": {
559+
"$ref": "#/components/schemas/KeyType"
560+
},
561+
"keyUse": {
562+
"$ref": "#/components/schemas/KeyUse"
563+
},
564+
"keyID": {
565+
"type": "string"
566566
},
567567
"x509CertSHA256Thumbprint": {
568568
"$ref": "#/components/schemas/Base64URL"
@@ -619,73 +619,73 @@
619619
"type": "object"
620620
}
621621
},
622-
"tokenRevocationEndpointAuthenticationMethods": {
622+
"revocation_endpoint_auth_methods_supported": {
623623
"type": "array",
624624
"items": {
625625
"type": "string"
626626
}
627627
},
628-
"tokenIntrospectionEndpointAuthenticationMethods": {
628+
"introspection_endpoint_auth_methods_supported": {
629629
"type": "array",
630630
"items": {
631631
"type": "string"
632632
}
633633
},
634-
"issuer": {
634+
"authorization_endpoint": {
635635
"type": "string",
636636
"format": "url"
637637
},
638-
"scopes": {
639-
"type": "array",
640-
"items": {
641-
"type": "string"
642-
}
643-
},
644-
"authorizationEndpoint": {
638+
"token_endpoint": {
645639
"type": "string",
646640
"format": "url"
647641
},
648-
"tokenEndpoint": {
642+
"revocation_endpoint": {
649643
"type": "string",
650644
"format": "url"
651645
},
652-
"tokenRevocationEndpoint": {
653-
"type": "string",
654-
"format": "url"
655-
},
656-
"jwkSetUrl": {
657-
"type": "string",
658-
"format": "url"
646+
"response_types_supported": {
647+
"type": "array",
648+
"items": {
649+
"type": "string"
650+
}
659651
},
660-
"responseTypes": {
652+
"grant_types_supported": {
661653
"type": "array",
662654
"items": {
663655
"type": "string"
664656
}
665657
},
666-
"grantTypes": {
658+
"code_challenge_methods_supported": {
667659
"type": "array",
668660
"items": {
669661
"type": "string"
670662
}
671663
},
672-
"codeChallengeMethods": {
664+
"jwks_uri": {
665+
"type": "string",
666+
"format": "url"
667+
},
668+
"scopes_supported": {
673669
"type": "array",
674670
"items": {
675671
"type": "string"
676672
}
677673
},
678-
"tokenIntrospectionEndpoint": {
674+
"issuer": {
675+
"type": "string",
676+
"format": "url"
677+
},
678+
"introspection_endpoint": {
679679
"type": "string",
680680
"format": "url"
681681
},
682-
"tokenEndpointAuthenticationMethods": {
682+
"token_endpoint_auth_methods_supported": {
683683
"type": "array",
684684
"items": {
685685
"type": "string"
686686
}
687687
},
688-
"clientRegistrationEndpoint": {
688+
"registration_endpoint": {
689689
"type": "string",
690690
"format": "url"
691691
}
@@ -781,50 +781,50 @@
781781
"type": "object"
782782
}
783783
},
784-
"notBefore": {
784+
"nbf": {
785785
"type": "string",
786786
"format": "date-time"
787787
},
788-
"id": {
788+
"jti": {
789789
"type": "string"
790790
},
791791
"active": {
792792
"type": "boolean"
793793
},
794-
"issuer": {
795-
"type": "string",
796-
"format": "url"
797-
},
798-
"scopes": {
799-
"type": "array",
800-
"items": {
801-
"type": "string"
802-
}
794+
"client_id": {
795+
"type": "string"
803796
},
804797
"username": {
805798
"type": "string"
806799
},
807-
"clientId": {
800+
"iat": {
801+
"type": "string",
802+
"format": "date-time"
803+
},
804+
"exp": {
805+
"type": "string",
806+
"format": "date-time"
807+
},
808+
"token_type": {
808809
"type": "string"
809810
},
810-
"audience": {
811+
"aud": {
811812
"type": "array",
812813
"items": {
813814
"type": "string"
814815
}
815816
},
816-
"issuedAt": {
817-
"type": "string",
818-
"format": "date-time"
817+
"scope": {
818+
"type": "array",
819+
"items": {
820+
"type": "string"
821+
}
819822
},
820-
"expiresAt": {
823+
"iss": {
821824
"type": "string",
822-
"format": "date-time"
823-
},
824-
"tokenType": {
825-
"type": "string"
825+
"format": "url"
826826
},
827-
"subject": {
827+
"sub": {
828828
"type": "string"
829829
}
830830
}

0 commit comments

Comments
 (0)
Please sign in to comment.