20
20
import com .google .common .util .concurrent .Futures ;
21
21
import com .google .common .util .concurrent .ListenableFuture ;
22
22
import com .google .common .util .concurrent .MoreExecutors ;
23
-
24
23
import io .grpc .Attributes ;
25
24
import io .grpc .Internal ;
26
25
import io .grpc .Metadata ;
32
31
import io .grpc .ServerInterceptor ;
33
32
import io .grpc .Status ;
34
33
import io .grpc .internal .GrpcAttributes ;
35
-
36
34
import java .util .concurrent .CancellationException ;
37
35
import java .util .concurrent .ConcurrentHashMap ;
38
36
import java .util .concurrent .ExecutionException ;
@@ -57,11 +55,10 @@ private BinderTransportSecurity() {}
57
55
* Install a security policy on an about-to-be created server.
58
56
*
59
57
* @param serverBuilder The ServerBuilder being used to create the server.
60
- * @param executor The executor in which the authorization result will be handled.
61
58
*/
62
59
@ Internal
63
- public static void installAuthInterceptor (ServerBuilder <?> serverBuilder , Executor executor ) {
64
- serverBuilder .intercept (new ServerAuthInterceptor (executor ));
60
+ public static void installAuthInterceptor (ServerBuilder <?> serverBuilder ) {
61
+ serverBuilder .intercept (new ServerAuthInterceptor ());
65
62
}
66
63
67
64
/**
@@ -71,14 +68,18 @@ public static void installAuthInterceptor(ServerBuilder<?> serverBuilder, Execut
71
68
* @param builder The {@link Attributes.Builder} for the transport being created.
72
69
* @param remoteUid The remote UID of the transport.
73
70
* @param serverPolicyChecker The policy checker for this transport.
71
+ * @param executor used for calling into the application. Must outlive the transport.
74
72
*/
75
73
@ Internal
76
74
public static void attachAuthAttrs (
77
- Attributes .Builder builder , int remoteUid , ServerPolicyChecker serverPolicyChecker ) {
75
+ Attributes .Builder builder ,
76
+ int remoteUid ,
77
+ ServerPolicyChecker serverPolicyChecker ,
78
+ Executor executor ) {
78
79
builder
79
80
.set (
80
81
TRANSPORT_AUTHORIZATION_STATE ,
81
- new TransportAuthorizationState (remoteUid , serverPolicyChecker ))
82
+ new TransportAuthorizationState (remoteUid , serverPolicyChecker , executor ))
82
83
.set (GrpcAttributes .ATTR_SECURITY_LEVEL , SecurityLevel .PRIVACY_AND_INTEGRITY );
83
84
}
84
85
@@ -88,25 +89,20 @@ public static void attachAuthAttrs(
88
89
*/
89
90
private static final class ServerAuthInterceptor implements ServerInterceptor {
90
91
91
- private final Executor executor ;
92
-
93
- ServerAuthInterceptor (Executor executor ) {
94
- this .executor = executor ;
95
- }
96
-
97
92
@ Override
98
93
public <ReqT , RespT > ServerCall .Listener <ReqT > interceptCall (
99
94
ServerCall <ReqT , RespT > call , Metadata headers , ServerCallHandler <ReqT , RespT > next ) {
95
+ TransportAuthorizationState transportAuthState =
96
+ call .getAttributes ().get (TRANSPORT_AUTHORIZATION_STATE );
100
97
ListenableFuture <Status > authStatusFuture =
101
- call .getAttributes ()
102
- .get (TRANSPORT_AUTHORIZATION_STATE )
103
- .checkAuthorization (call .getMethodDescriptor ());
98
+ transportAuthState .checkAuthorization (call .getMethodDescriptor ());
104
99
105
100
// Most SecurityPolicy will have synchronous implementations that provide an
106
101
// immediately-resolved Future. In that case, short-circuit to avoid unnecessary allocations
107
102
// and asynchronous code if the authorization result is already present.
108
103
if (!authStatusFuture .isDone ()) {
109
- return newServerCallListenerForPendingAuthResult (authStatusFuture , call , headers , next );
104
+ return newServerCallListenerForPendingAuthResult (
105
+ authStatusFuture , transportAuthState .executor , call , headers , next );
110
106
}
111
107
112
108
Status authStatus ;
@@ -130,31 +126,33 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
130
126
}
131
127
132
128
private <ReqT , RespT > ServerCall .Listener <ReqT > newServerCallListenerForPendingAuthResult (
133
- ListenableFuture <Status > authStatusFuture ,
134
- ServerCall <ReqT , RespT > call ,
135
- Metadata headers ,
136
- ServerCallHandler <ReqT , RespT > next ) {
129
+ ListenableFuture <Status > authStatusFuture ,
130
+ Executor executor ,
131
+ ServerCall <ReqT , RespT > call ,
132
+ Metadata headers ,
133
+ ServerCallHandler <ReqT , RespT > next ) {
137
134
PendingAuthListener <ReqT , RespT > listener = new PendingAuthListener <>();
138
135
Futures .addCallback (
139
- authStatusFuture ,
140
- new FutureCallback <Status >() {
141
- @ Override
142
- public void onSuccess (Status authStatus ) {
143
- if (!authStatus .isOk ()) {
144
- call .close (authStatus , new Metadata ());
145
- return ;
146
- }
147
-
148
- listener .startCall (call , headers , next );
149
- }
150
-
151
- @ Override
152
- public void onFailure (Throwable t ) {
153
- call .close (
154
- Status .INTERNAL .withCause (t ).withDescription ("Authorization future failed" ),
155
- new Metadata ());
156
- }
157
- }, executor );
136
+ authStatusFuture ,
137
+ new FutureCallback <Status >() {
138
+ @ Override
139
+ public void onSuccess (Status authStatus ) {
140
+ if (!authStatus .isOk ()) {
141
+ call .close (authStatus , new Metadata ());
142
+ return ;
143
+ }
144
+
145
+ listener .startCall (call , headers , next );
146
+ }
147
+
148
+ @ Override
149
+ public void onFailure (Throwable t ) {
150
+ call .close (
151
+ Status .INTERNAL .withCause (t ).withDescription ("Authorization future failed" ),
152
+ new Metadata ());
153
+ }
154
+ },
155
+ executor );
158
156
return listener ;
159
157
}
160
158
}
@@ -167,10 +165,16 @@ private static final class TransportAuthorizationState {
167
165
private final int uid ;
168
166
private final ServerPolicyChecker serverPolicyChecker ;
169
167
private final ConcurrentHashMap <String , ListenableFuture <Status >> serviceAuthorization ;
168
+ private final Executor executor ;
170
169
171
- TransportAuthorizationState (int uid , ServerPolicyChecker serverPolicyChecker ) {
170
+ /**
171
+ * @param executor used for calling into the application. Must outlive the transport.
172
+ */
173
+ TransportAuthorizationState (
174
+ int uid , ServerPolicyChecker serverPolicyChecker , Executor executor ) {
172
175
this .uid = uid ;
173
176
this .serverPolicyChecker = serverPolicyChecker ;
177
+ this .executor = executor ;
174
178
serviceAuthorization = new ConcurrentHashMap <>(8 );
175
179
}
176
180
0 commit comments