9
9
import java .net .http .HttpResponse .BodyHandlers ;
10
10
import java .security .PublicKey ;
11
11
import java .util .Set ;
12
+ import java .util .function .Consumer ;
12
13
13
14
import org .eclipse .jetty .http .HttpHeader ;
14
15
import org .keycloak .TokenVerifier ;
18
19
19
20
import com .fasterxml .jackson .databind .ObjectMapper ;
20
21
22
+ import info .unterrainer .commons .httpserver .HttpServer ;
21
23
import info .unterrainer .commons .httpserver .enums .Attribute ;
22
24
import info .unterrainer .commons .httpserver .exceptions .ForbiddenException ;
23
25
import info .unterrainer .commons .httpserver .exceptions .GatewayTimeoutException ;
24
26
import info .unterrainer .commons .httpserver .exceptions .UnauthorizedException ;
27
+ import info .unterrainer .commons .httpserver .jsons .UserDataJson ;
25
28
import io .javalin .core .security .AccessManager ;
26
29
import io .javalin .core .security .Role ;
27
30
import io .javalin .http .Context ;
@@ -49,7 +52,8 @@ public HttpAccessManager(final String host, final String realm) {
49
52
50
53
@ Override
51
54
public void manage (final Handler handler , final Context ctx , final Set <Role > permittedRoles ) throws Exception {
52
- checkAccess (ctx , permittedRoles );
55
+ checkAccess (ctx , permittedRoles ,
56
+ ((HttpServer ) ctx .attribute (Attribute .JAVALIN_SERVER )).getUserAccessInterceptor ());
53
57
handler .handle (ctx );
54
58
}
55
59
@@ -79,10 +83,13 @@ private void initPublicKey() {
79
83
}
80
84
return response .body ();
81
85
}).thenAccept (body -> {
82
- if (body == null )
86
+ if (body == null ) {
87
+ log .warn ("Received empty body." );
83
88
return ;
89
+ }
84
90
try {
85
91
publicKey = objectMapper .readValue (body , PublishedRealmRepresentation .class ).getPublicKey ();
92
+ log .info ("Public key received." );
86
93
} catch (IOException e ) {
87
94
log .error ("Error parsing answer from keycloak." );
88
95
throw new UncheckedIOException (e );
@@ -94,9 +101,10 @@ private void initPublicKey() {
94
101
}
95
102
}
96
103
97
- private void checkAccess (final Context ctx , final Set <Role > permittedRoles ) {
104
+ private void checkAccess (final Context ctx , final Set <Role > permittedRoles ,
105
+ final Consumer <UserDataJson > userAccessInterceptor ) {
98
106
try {
99
- TokenVerifier <AccessToken > tokenVerifier = persistUserInfoInContext (ctx );
107
+ TokenVerifier <AccessToken > tokenVerifier = persistUserInfoInContext (ctx , userAccessInterceptor );
100
108
101
109
if (permittedRoles .isEmpty () || permittedRoles .contains (DefaultRole .OPEN ) && permittedRoles .size () == 1 )
102
110
return ;
@@ -137,7 +145,8 @@ private boolean hasPermittedRole(final Context ctx, final Set<Role> permittedRol
137
145
return false ;
138
146
}
139
147
140
- private TokenVerifier <AccessToken > persistUserInfoInContext (final Context ctx ) {
148
+ private TokenVerifier <AccessToken > persistUserInfoInContext (final Context ctx ,
149
+ final Consumer <UserDataJson > userAccessInterceptor ) {
141
150
String authorizationHeader = ctx .header (HttpHeader .AUTHORIZATION .asString ());
142
151
143
152
if (authorizationHeader == null || authorizationHeader .isBlank ())
@@ -167,6 +176,19 @@ private TokenVerifier<AccessToken> persistUserInfoInContext(final Context ctx) {
167
176
clientRoles = token .getResourceAccess ().get (key ).getRoles ();
168
177
ctx .attribute (Attribute .USER_CLIENT_ROLES , clientRoles );
169
178
179
+ userAccessInterceptor .accept (UserDataJson .builder ()
180
+ .userName (userName )
181
+ .givenName (token .getGivenName ())
182
+ .client (token .getIssuedFor ())
183
+ .familyName (token .getFamilyName ())
184
+ .email (token .getEmail ())
185
+ .emailVerified (token .getEmailVerified ())
186
+ .realmRoles (token .getRealmAccess ().getRoles ())
187
+ .clientRoles (clientRoles )
188
+ .isActive (token .isActive ())
189
+ .isBearer (token .getType ().equalsIgnoreCase ("bearer" ))
190
+ .build ());
191
+
170
192
if (!token .isActive ()) {
171
193
setTokenRejectionReason (ctx , "Token is inactive." );
172
194
return null ;
0 commit comments