1- package com .clerk .backend_api .helpers .jwks ;
2-
3- import io .jsonwebtoken .Claims ;
4- import io .jsonwebtoken .impl .DefaultClaims ;
1+ package com .clerk .backend_api .helpers .security ;
2+
3+ import com .clerk .backend_api .helpers .security .models .AuthErrorReason ;
4+ import com .clerk .backend_api .helpers .security .models .AuthenticateRequestOptions ;
5+ import com .clerk .backend_api .helpers .security .models .RequestState ;
6+ import com .clerk .backend_api .helpers .security .models .TokenType ;
7+ import com .clerk .backend_api .helpers .security .models .TokenVerificationException ;
8+ import com .clerk .backend_api .helpers .security .models .TokenVerificationResponse ;
9+ import com .clerk .backend_api .helpers .security .models .VerifyTokenOptions ;
10+ import java .io .IOException ;
511import java .net .HttpCookie ;
6- import java .util .ArrayList ;
712import java .util .HashMap ;
813import java .util .List ;
914import java .util .Map ;
1015import java .util .concurrent .TimeUnit ;
1116
17+ import static com .clerk .backend_api .helpers .security .util .TokenTypeHelper .getTokenType ;
18+
1219/**
1320 * AuthenticateRequest - Helper methods to authenticate requests.
1421 */
@@ -34,58 +41,29 @@ private AuthenticateRequest() {
3441 * WARNING: authenticateRequest is applicable in the context of Backend
3542 * APIs only.
3643 */
37- public static final RequestState authenticateRequest (Map <String , List <String >> requestHeaders , AuthenticateRequestOptions options ) {
44+ public static RequestState authenticateRequest (Map <String , List <String >> requestHeaders , AuthenticateRequestOptions options ) {
3845
3946 String sessionToken = getSessionToken (requestHeaders );
4047 if (sessionToken == null ) {
41- return RequestState .signedOut (AuthErrorReason .SESSION_TOKEN_MISSING );
42- }
48+ return RequestState .signedOut (AuthErrorReason .SESSION_TOKEN_MISSING ); }
4349
44- VerifyTokenOptions verifyTokenOptions ;
4550
46- if (options .jwtKey ().isPresent ()) {
47- verifyTokenOptions = VerifyTokenOptions //
48- .jwtKey (options .jwtKey ().get ()) //
49- .audience (options .audience ()) //
50- .authorizedParties (options .authorizedParties ()) //
51- .clockSkew (options .clockSkewInMs (), TimeUnit .MILLISECONDS ) //
52- .build ();
53- } else if (options .secretKey ().isPresent ()) {
54- verifyTokenOptions = VerifyTokenOptions //
55- .secretKey (options .secretKey ().get ()) //
56- .audience (options .audience ()) //
57- .authorizedParties (options .authorizedParties ()) //
58- .clockSkew (options .clockSkewInMs (), TimeUnit .MILLISECONDS ) //
59- .build ();
60- } else {
61- return RequestState .signedOut (AuthErrorReason .SECRET_KEY_MISSING );
51+ List <String > acceptsTokens = options .acceptsToken ();
52+ TokenType tokenType = getTokenType (sessionToken );
53+
54+ if (!acceptsTokens .contains (tokenType .getType ()) && !acceptsTokens .contains ("any" )) {
55+ return RequestState .signedOut (AuthErrorReason .TOKEN_TYPE_NOT_SUPPORTED );
6256 }
6357
64- try {
65- Claims claims = VerifyToken .verifyToken (sessionToken , verifyTokenOptions );
66- Map <String , Object > updatedClaimsMap = new HashMap <>(claims );
67-
68- if ("2" .equals (String .valueOf (claims .get ("v" )))) {
69- Object orgObject = claims .get ("o" );
70- if (orgObject instanceof Map ) {
71- @ SuppressWarnings ("unchecked" )
72- Map <String , Object > orgClaims = (Map <String , Object >) orgObject ;
73-
74- updatedClaimsMap .put ("org_id" , orgClaims .get ("id" ));
75- updatedClaimsMap .put ("org_slug" , orgClaims .get ("slg" ));
76- updatedClaimsMap .put ("org_role" , orgClaims .get ("rol" ));
77-
78- List <String > orgPermissions = computeOrgPermissions (claims );
79- if (!orgPermissions .isEmpty ()) {
80- updatedClaimsMap .put ("org_permissions" , orgPermissions );
81- }
82- }
83- }
58+ VerifyTokenOptions verifyTokenOptions = buildVerifyTokenOptions (options );
8459
85- Claims updatedClaims = new DefaultClaims (updatedClaimsMap );
86- return RequestState .signedIn (sessionToken , updatedClaims );
60+ try {
61+ TokenVerificationResponse <?> tokenVerificationResponse = VerifyToken .verifyToken (sessionToken , verifyTokenOptions );
62+ return RequestState .signedIn (sessionToken , tokenVerificationResponse );
8763 } catch (TokenVerificationException e ) {
8864 return RequestState .signedOut (e .reason ());
65+ } catch (IOException | InterruptedException e ) {
66+ return RequestState .signedOut (AuthErrorReason .INTERNAL_ERROR );
8967 }
9068
9169 }
@@ -120,42 +98,26 @@ private static String getSessionToken(Map<String, List<String>> requestHeaders)
12098 return null ;
12199 }
122100
123- @ SuppressWarnings ("unchecked" )
124- private static List <String > computeOrgPermissions (Claims claims ) {
125- String featuresStr = (String ) claims .get ("fea" );
126- if (featuresStr == null ) {
127- return new ArrayList <>();
128- }
129- String permissionsStr = (String ) ((Map <String , Object >) claims .get ("o" )).get ("per" );
130- String mappingsStr = (String ) ((Map <String , Object >) claims .get ("o" )).get ("fpm" );
131101
132- String [] features = featuresStr .split ("," );
133- String [] permissions = permissionsStr .split ("," );
134- String [] mappings = mappingsStr .split ("," );
135102
136- List <String > orgPermissions = new ArrayList <>();
137-
138- for (int idx = 0 ; idx < mappings .length ; idx ++) {
139- String mapping = mappings [idx ];
140- String [] featureParts = features [idx ].split (":" );
141- if (featureParts .length != 2 ) continue ;
142-
143- String scope = featureParts [0 ];
144- String feature = featureParts [1 ];
145-
146- if (!scope .contains ("o" )) continue ;
147-
148- String binary = Integer .toBinaryString (Integer .parseInt (mapping )).replaceAll ("^0+" , "" );
149- String reversedBinary = new StringBuilder (binary ).reverse ().toString ();
150-
151- for (int i = 0 ; i < reversedBinary .length (); i ++) {
152- if (reversedBinary .charAt (i ) == '1' && i < permissions .length ) {
153- orgPermissions .add ("org:" + feature + ":" + permissions [i ]);
154- }
155- }
103+ private static VerifyTokenOptions buildVerifyTokenOptions (AuthenticateRequestOptions options ) {
104+ if (options .jwtKey ().isPresent ()) {
105+ return VerifyTokenOptions //
106+ .jwtKey (options .jwtKey ().get ()) //
107+ .audience (options .audience ()) //
108+ .authorizedParties (options .authorizedParties ()) //
109+ .clockSkew (options .clockSkewInMs (), TimeUnit .MILLISECONDS ) //
110+ .build ();
111+ } else if (options .secretKey ().isPresent ()) {
112+ return VerifyTokenOptions //
113+ .secretKey (options .secretKey ().get ()) //
114+ .audience (options .audience ()) //
115+ .authorizedParties (options .authorizedParties ()) //
116+ .clockSkew (options .clockSkewInMs (), TimeUnit .MILLISECONDS ) //
117+ .build ();
118+ } else {
119+ return new VerifyTokenOptions .Builder ().build ();
156120 }
157-
158- return orgPermissions ;
159121 }
160122
161123}
0 commit comments