Skip to content

Commit 5c8e55d

Browse files
committed
closes #296
1 parent b0f9401 commit 5c8e55d

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package org.lognet.springboot.grpc.auth;
2+
3+
4+
import io.grpc.*;
5+
import io.grpc.examples.*;
6+
import io.grpc.examples.custom.Custom;
7+
import io.grpc.examples.custom.CustomServiceGrpc;
8+
import io.grpc.stub.StreamObserver;
9+
import org.hamcrest.Matchers;
10+
import org.junit.Test;
11+
import org.junit.runner.RunWith;
12+
import org.lognet.springboot.grpc.GRpcService;
13+
import org.lognet.springboot.grpc.GrpcServerTestBase;
14+
import org.lognet.springboot.grpc.demo.DemoApp;
15+
import org.lognet.springboot.grpc.security.*;
16+
import org.springframework.beans.factory.annotation.Autowired;
17+
import org.springframework.boot.test.context.SpringBootTest;
18+
import org.springframework.boot.test.context.TestConfiguration;
19+
import org.springframework.context.annotation.Bean;
20+
import org.springframework.context.annotation.Import;
21+
import org.springframework.security.core.userdetails.User;
22+
import org.springframework.security.core.userdetails.UserDetails;
23+
import org.springframework.security.core.userdetails.UserDetailsService;
24+
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
25+
import org.springframework.test.context.junit4.SpringRunner;
26+
27+
import java.util.concurrent.ExecutionException;
28+
29+
import static org.hamcrest.MatcherAssert.assertThat;
30+
import static org.hamcrest.Matchers.notNullValue;
31+
import static org.junit.Assert.*;
32+
import static org.lognet.springboot.grpc.auth.ExcludeMethodAuthTest.TestCfg.pwd;
33+
34+
35+
@SpringBootTest(classes = DemoApp.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
36+
@RunWith(SpringRunner.class)
37+
@Import({ExcludeMethodAuthTest.TestCfg.class})
38+
public class ExcludeMethodAuthTest extends GrpcServerTestBase {
39+
40+
41+
@TestConfiguration
42+
static class TestCfg extends GrpcSecurityConfigurerAdapter {
43+
44+
@GRpcService
45+
static class CustomService extends CustomServiceGrpc.CustomServiceImplBase {
46+
47+
@Override
48+
public void custom(Custom.CustomRequest request, StreamObserver<Custom.CustomReply> responseObserver) {
49+
responseObserver.onNext(Custom.CustomReply.newBuilder().build());
50+
responseObserver.onCompleted();
51+
}
52+
@Override
53+
public void anotherCustom(Custom.CustomRequest request, StreamObserver<Custom.CustomReply> responseObserver) {
54+
responseObserver.onNext(Custom.CustomReply.newBuilder().build());
55+
responseObserver.onCompleted();
56+
}
57+
}
58+
59+
static final String pwd = "strongPassword1";
60+
61+
@Bean
62+
public static UserDetailsService userDetailsService() {
63+
return new InMemoryUserDetailsManager(user(), admin());
64+
}
65+
66+
@Bean
67+
public static UserDetails user() {
68+
return User.withDefaultPasswordEncoder()
69+
.username("user")
70+
.password(pwd)
71+
.authorities("ROLE_user")
72+
.build();
73+
}
74+
75+
@Bean
76+
public static UserDetails admin() {
77+
return User.withDefaultPasswordEncoder()
78+
.username("admin")
79+
.password(pwd)
80+
.authorities("ROLE_admin")
81+
.build();
82+
}
83+
84+
85+
@Override
86+
public void configure(GrpcSecurity builder) throws Exception {
87+
builder
88+
.authorizeRequests()
89+
.methods(CustomServiceGrpc.getCustomMethod()).hasAnyRole("admin")
90+
.anyMethodExcluding(CustomServiceGrpc.getCustomMethod()).hasAnyRole("user");
91+
92+
}
93+
94+
95+
}
96+
97+
@Autowired
98+
private UserDetails user;
99+
@Autowired
100+
private UserDetails admin;
101+
102+
@Test
103+
public void userAuthTest() {
104+
105+
106+
Channel userChannel = authChannel(getChannel(),user);
107+
final CustomServiceGrpc.CustomServiceBlockingStub userStub = CustomServiceGrpc.newBlockingStub(userChannel);
108+
Custom.CustomReply reply = userStub.anotherCustom(Custom.CustomRequest.newBuilder().build());
109+
assertNotNull("Reply should not be null", reply);
110+
111+
final StatusRuntimeException statusRuntimeException = assertThrows(StatusRuntimeException.class, () -> {
112+
userStub.custom(Custom.CustomRequest.newBuilder().build());
113+
});
114+
assertThat(statusRuntimeException.getStatus().getCode(), Matchers.is(Status.Code.PERMISSION_DENIED));
115+
116+
}
117+
118+
@Test
119+
public void adminAuthTest() {
120+
121+
Channel adminChannel = authChannel(getChannel(),admin);
122+
final CustomServiceGrpc.CustomServiceBlockingStub userStub = CustomServiceGrpc.newBlockingStub(adminChannel);
123+
Custom.CustomReply reply = userStub.custom(Custom.CustomRequest.newBuilder().build());
124+
assertNotNull("Reply should not be null", reply);
125+
126+
final StatusRuntimeException statusRuntimeException = assertThrows(StatusRuntimeException.class, () -> {
127+
userStub.anotherCustom(Custom.CustomRequest.newBuilder().build());
128+
});
129+
assertThat(statusRuntimeException.getStatus().getCode(), Matchers.is(Status.Code.PERMISSION_DENIED));
130+
131+
}
132+
133+
@Override
134+
protected GreeterGrpc.GreeterFutureStub beforeGreeting(GreeterGrpc.GreeterFutureStub stub) {
135+
AuthCallCredentials callCredentials = new AuthCallCredentials(AuthHeader.builder().basic(user.getUsername(), pwd.getBytes()));
136+
return stub.withCallCredentials(callCredentials);
137+
}
138+
139+
protected Channel authChannel(Channel channel, UserDetails user) {
140+
141+
final AuthClientInterceptor interceptor = new AuthClientInterceptor(AuthHeader.builder()
142+
.basic(user.getUsername(), pwd.getBytes())
143+
.binaryFormat(true)
144+
);
145+
return ClientInterceptors.intercept(super.getChannel(), interceptor);
146+
}
147+
148+
149+
}

grpc-spring-boot-starter-demo/src/test/proto/custom.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ option java_package = "io.grpc.examples.custom";
77
// Custom service definition.
88
service CustomService {
99
rpc Custom ( CustomRequest) returns ( CustomReply) {}
10+
rpc AnotherCustom ( CustomRequest) returns ( CustomReply) {}
1011
rpc CustomStream (stream CustomRequest) returns (stream CustomReply) {}
1112
}
1213

0 commit comments

Comments
 (0)