88import java .net .http .HttpRequest ;
99import java .net .http .HttpResponse .BodyHandlers ;
1010import java .security .PublicKey ;
11+ import java .util .HashSet ;
1112import java .util .Set ;
1213import java .util .function .Consumer ;
1314
@@ -52,8 +53,7 @@ public HttpAccessManager(final String host, final String realm) {
5253
5354 @ Override
5455 public void manage (final Handler handler , final Context ctx , final Set <Role > permittedRoles ) throws Exception {
55- checkAccess (ctx , permittedRoles ,
56- ((HttpServer ) ctx .attribute (Attribute .JAVALIN_SERVER )).getUserAccessInterceptor ());
56+ checkAccess (ctx , permittedRoles );
5757 handler .handle (ctx );
5858 }
5959
@@ -101,10 +101,9 @@ private void initPublicKey() {
101101 }
102102 }
103103
104- private void checkAccess (final Context ctx , final Set <Role > permittedRoles ,
105- final Consumer <UserDataJson > userAccessInterceptor ) {
104+ private void checkAccess (final Context ctx , final Set <Role > permittedRoles ) {
106105 try {
107- TokenVerifier <AccessToken > tokenVerifier = persistUserInfoInContext (ctx , userAccessInterceptor );
106+ TokenVerifier <AccessToken > tokenVerifier = persistUserInfoInContext (ctx );
108107
109108 if (permittedRoles .isEmpty () || permittedRoles .contains (DefaultRole .OPEN ) && permittedRoles .size () == 1 )
110109 return ;
@@ -146,8 +145,7 @@ private boolean hasPermittedRole(final Context ctx, final Set<Role> permittedRol
146145 return false ;
147146 }
148147
149- private TokenVerifier <AccessToken > persistUserInfoInContext (final Context ctx ,
150- final Consumer <UserDataJson > userAccessInterceptor ) {
148+ private TokenVerifier <AccessToken > persistUserInfoInContext (final Context ctx ) {
151149 String authorizationHeader = ctx .header (HttpHeader .AUTHORIZATION .asString ());
152150
153151 if (authorizationHeader == null || authorizationHeader .isBlank ())
@@ -171,24 +169,32 @@ private TokenVerifier<AccessToken> persistUserInfoInContext(final Context ctx,
171169 ctx .attribute (Attribute .USER_EMAIL_VERIFIED , token .getEmailVerified ());
172170 ctx .attribute (Attribute .USER_REALM_ROLES , token .getRealmAccess ().getRoles ());
173171
172+ String tenant = (String ) token .getOtherClaims ().get ("tenant" );
173+ ctx .attribute (Attribute .USER_CLIENT_ATTRIBUTE_TENANT , tenant );
174+ ctx .attribute (Attribute .USER_TENANT_SET , createTenantSetFrom (tenant ));
175+
174176 Set <String > clientRoles = Set .of ();
175177 String key = token .getIssuedFor ();
176178 if (token .getResourceAccess ().containsKey (key ))
177179 clientRoles = token .getResourceAccess ().get (key ).getRoles ();
178180 ctx .attribute (Attribute .USER_CLIENT_ROLES , clientRoles );
179181
180- userAccessInterceptor .accept (UserDataJson .builder ()
181- .userName (userName )
182- .givenName (token .getGivenName ())
183- .client (token .getIssuedFor ())
184- .familyName (token .getFamilyName ())
185- .email (token .getEmail ())
186- .emailVerified (token .getEmailVerified ())
187- .realmRoles (token .getRealmAccess ().getRoles ())
188- .clientRoles (clientRoles )
189- .isActive (token .isActive ())
190- .isBearer (token .getType ().equalsIgnoreCase ("bearer" ))
191- .build ());
182+ Consumer <UserDataJson > userAccessInterceptor = ((HttpServer ) ctx .attribute (Attribute .JAVALIN_SERVER ))
183+ .getUserAccessInterceptor ();
184+ if (userAccessInterceptor != null )
185+ userAccessInterceptor .accept (UserDataJson .builder ()
186+ .userName (userName )
187+ .givenName (token .getGivenName ())
188+ .client (token .getIssuedFor ())
189+ .familyName (token .getFamilyName ())
190+ .email (token .getEmail ())
191+ .emailVerified (token .getEmailVerified ())
192+ .realmRoles (token .getRealmAccess ().getRoles ())
193+ .tenant (tenant )
194+ .clientRoles (clientRoles )
195+ .isActive (token .isActive ())
196+ .isBearer (token .getType ().equalsIgnoreCase ("bearer" ))
197+ .build ());
192198
193199 if (!token .isActive ()) {
194200 setTokenRejectionReason (ctx , "Token is inactive." );
@@ -211,6 +217,20 @@ private TokenVerifier<AccessToken> persistUserInfoInContext(final Context ctx,
211217 }
212218 }
213219
220+ private Object createTenantSetFrom (final String tenant ) {
221+ Set <String > tenantSet = new HashSet <>();
222+ if (tenant == null || tenant .isBlank ())
223+ return tenantSet ;
224+
225+ String [] tenants = tenant .split ("," );
226+ for (String t : tenants ) {
227+ if (t .isBlank ())
228+ continue ;
229+ tenantSet .add (t .trim ());
230+ }
231+ return tenantSet ;
232+ }
233+
214234 private void setTokenRejectionReason (final Context ctx , final String reason ) {
215235 ctx .attribute (Attribute .KEYCLOAK_TOKEN_REJECTION_REASON , reason );
216236 }
0 commit comments