You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/05/16 03:22:05 UTC
[servicecomb-samples] 01/02: add method security support
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-samples.git
commit 79409fb0d66c20c93645fa5e48d392d4a6b4078d
Author: liubao <ba...@huawei.com>
AuthorDate: Mon May 13 15:47:46 2019 +0800
add method security support
---
...onServer.java => AuthenticationServerMain.java} | 2 +-
.../{Client.java => AuthenticationClientMain.java} | 2 +-
.../authentication/AuthenticationTestCase.java | 52 +++++++++++++++
.../authentication/BootEventListener.java | 4 ++
.../servicecomb/authentication/TestEndpoint.java | 12 ++--
.../apache/servicecomb/authentication/TestMgr.java | 13 ++++
...wayMain.java => AuthenticationGatewayMain.java} | 2 +-
...ResourceServer.java => ResourceServerMain.java} | 2 +-
...eptionExceptionToProducerResponseConverter.java | 39 +++++++++++
.../resource/MethodSecurityConfiguration.java | 36 ++++++++++
.../resource/PreMethodAuthEndpoint.java | 2 +-
.../resource/ResourceAuthHandler.java | 16 ++++-
.../resource/SimpleAuthentication.java | 77 ++++++++++++++++++++++
....exception.ExceptionToProducerResponseConverter | 18 +++++
14 files changed, 267 insertions(+), 10 deletions(-)
diff --git a/authentication/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServer.java b/authentication/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServerMain.java
similarity index 96%
rename from authentication/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServer.java
rename to authentication/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServerMain.java
index f38125a..35b239d 100644
--- a/authentication/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServer.java
+++ b/authentication/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationServerMain.java
@@ -19,7 +19,7 @@ package org.apache.servicecomb.authentication;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
-public class AuthenticationServer {
+public class AuthenticationServerMain {
public static void main(String[] args) {
try {
BeanUtils.init();
diff --git a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/Client.java b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationClientMain.java
similarity index 96%
rename from authentication/Client/src/main/java/org/apache/servicecomb/authentication/Client.java
rename to authentication/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationClientMain.java
index 4ba1070..ce9c356 100644
--- a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/Client.java
+++ b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationClientMain.java
@@ -19,7 +19,7 @@ package org.apache.servicecomb.authentication;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
-public class Client {
+public class AuthenticationClientMain {
public static void main(String[] args) {
try {
BeanUtils.init();
diff --git a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
index 1bae5c3..61ba97f 100644
--- a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
+++ b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
@@ -30,6 +30,12 @@ import org.springframework.web.client.HttpClientErrorException;
public class AuthenticationTestCase implements TestCase {
@Override
public void run() {
+ testHanlderAuth();
+ testMethodAuth();
+ }
+
+
+ private void testHanlderAuth() {
// get token
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("userName", "admin");
@@ -75,4 +81,50 @@ public class AuthenticationTestCase implements TestCase {
TestMgr.check(null, name);
}
+
+ private void testMethodAuth() {
+ // get token
+ MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
+ map.add("userName", "admin");
+ map.add("password", "changeMyPassword");
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+ Token token =
+ BootEventListener.gateEndpoint.postForObject("/v1/auth/login",
+ new HttpEntity<>(map, headers),
+ Token.class);
+ TestMgr.check("bearer", token.getToken_type());
+ TestMgr.check(true, token.getAccess_token().length() > 10);
+
+ // get resources
+ headers = new HttpHeaders();
+ headers.add("Authorization", "Bearer " + token.getAccess_token());
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ String name;
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/everyoneSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/adminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/guestOrAdminSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ TestMgr.check("Hi", name);
+
+ name = null;
+ try {
+ name = BootEventListener.resouceServerMethodAuthEndpoint.postForObject("/guestSayHello?name=Hi",
+ new HttpEntity<>(headers),
+ String.class);
+ } catch (HttpClientErrorException e) {
+ TestMgr.check(403, e.getStatusCode().value());
+ }
+ TestMgr.check(null, name);
+ }
}
diff --git a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/BootEventListener.java b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/BootEventListener.java
index 2af0a55..5512f8c 100644
--- a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/BootEventListener.java
+++ b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/BootEventListener.java
@@ -25,6 +25,8 @@ public class BootEventListener implements BootListener {
public static GateRestTemplate authenticationServerAuthenticationEndpoint;
public static GateRestTemplate gateEndpoint;
public static GateRestTemplate resouceServerHandlerAuthEndpoint;
+ public static GateRestTemplate resouceServerMethodAuthEndpoint;
+
@Override
public void onBootEvent(BootEvent event) {
if (EventType.AFTER_REGISTRY.equals(event.getEventType())) {
@@ -34,6 +36,8 @@ public class BootEventListener implements BootListener {
GateRestTemplate.createEdgeRestTemplate("gateway", null, null).init();
resouceServerHandlerAuthEndpoint =
GateRestTemplate.createEdgeRestTemplate("gateway", "resource-server", "HandlerAuthEndpoint").init();
+ resouceServerMethodAuthEndpoint =
+ GateRestTemplate.createEdgeRestTemplate("gateway", "resource-server", "PreMethodAuthEndpoint").init();
}
}
diff --git a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
index 04c3927..19b0af1 100644
--- a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
+++ b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
@@ -29,19 +29,23 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class TestEndpoint {
@Autowired
private List<TestCase> tests;
-
+
@GetMapping(path = "/start")
public String start() {
tests.forEach(test -> test.run());
-
+
List<Throwable> errors = TestMgr.errors();
- if (errors.isEmpty()) {
- return "success";
+ if (TestMgr.isSuccess()) {
+ return TestMgr.successMessage();
} else {
+ TestMgr.summary();
+
StringBuilder sb = new StringBuilder();
sb.append("Failed count : " + errors.size());
sb.append("\n");
errors.forEach(t -> sb.append(t.getMessage() + "\n"));
+
+ TestMgr.reset();
return sb.toString();
}
}
diff --git a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
index 6b53045..030bb4c 100644
--- a/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
+++ b/authentication/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.authentication;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,6 +32,8 @@ public class TestMgr {
private static String msg = "";
+ private static AtomicLong checksCount = new AtomicLong();
+
public static void setMsg(String msg) {
TestMgr.msg = msg;
}
@@ -44,6 +47,7 @@ public class TestMgr {
}
public static void check(Object expect, Object real, Throwable error) {
+ checksCount.incrementAndGet();
if (expect == real) {
return;
}
@@ -90,6 +94,15 @@ public class TestMgr {
}
}
+ public static void reset() {
+ errorList.clear();
+ checksCount.set(0);
+ }
+
+ public static String successMessage() {
+ return "Success. Checkes = " + checksCount.get();
+ }
+
public static List<Throwable> errors() {
return errorList;
}
diff --git a/authentication/Gateway/src/main/java/org/apache/servicecomb/authentication/gateway/GatewayMain.java b/authentication/Gateway/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationGatewayMain.java
similarity index 96%
rename from authentication/Gateway/src/main/java/org/apache/servicecomb/authentication/gateway/GatewayMain.java
rename to authentication/Gateway/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationGatewayMain.java
index 862e6c3..be15a24 100644
--- a/authentication/Gateway/src/main/java/org/apache/servicecomb/authentication/gateway/GatewayMain.java
+++ b/authentication/Gateway/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationGatewayMain.java
@@ -19,7 +19,7 @@ package org.apache.servicecomb.authentication.gateway;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
-public class GatewayMain {
+public class AuthenticationGatewayMain {
public static void main(String[] args) throws Exception {
BeanUtils.init();
}
diff --git a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/ResourceServer.java b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/ResourceServerMain.java
similarity index 96%
rename from authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/ResourceServer.java
rename to authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/ResourceServerMain.java
index f2653ab..5aae72f 100644
--- a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/ResourceServer.java
+++ b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/ResourceServerMain.java
@@ -19,7 +19,7 @@ package org.apache.servicecomb.authentication;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
-public class ResourceServer {
+public class ResourceServerMain {
public static void main(String[] args) {
try {
BeanUtils.init();
diff --git a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AccessDeniedExceptionExceptionToProducerResponseConverter.java b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AccessDeniedExceptionExceptionToProducerResponseConverter.java
new file mode 100644
index 0000000..c2decce
--- /dev/null
+++ b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AccessDeniedExceptionExceptionToProducerResponseConverter.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
+import org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.security.access.AccessDeniedException;
+
+public class AccessDeniedExceptionExceptionToProducerResponseConverter
+ implements ExceptionToProducerResponseConverter<AccessDeniedException> {
+
+ @Override
+ public Class<AccessDeniedException> getExceptionClass() {
+ return AccessDeniedException.class;
+ }
+
+ @Override
+ public Response convert(SwaggerInvocation swaggerInvocation, AccessDeniedException e) {
+ return Response.failResp(new InvocationException(403, "forbidden", "not authenticated"));
+ }
+
+}
diff --git a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/MethodSecurityConfiguration.java b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/MethodSecurityConfiguration.java
new file mode 100644
index 0000000..58df6a9
--- /dev/null
+++ b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/MethodSecurityConfiguration.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
+import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
+
+@Configuration
+@EnableGlobalMethodSecurity(
+ prePostEnabled = true)
+public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
+ @Override
+ protected MethodSecurityExpressionHandler createExpressionHandler() {
+ DefaultMethodSecurityExpressionHandler h = (DefaultMethodSecurityExpressionHandler) super.createExpressionHandler();
+ h.setDefaultRolePrefix("");
+ return h;
+ }
+}
diff --git a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/PreMethodAuthEndpoint.java b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/PreMethodAuthEndpoint.java
index e07745b..668f774 100644
--- a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/PreMethodAuthEndpoint.java
+++ b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/PreMethodAuthEndpoint.java
@@ -38,7 +38,7 @@ public class PreMethodAuthEndpoint {
}
@PostMapping(path = "/guestOrAdminSayHello")
- @PreAuthorize("hasRole('USER,ADMIN')")
+ @PreAuthorize("hasAnyRole('USER','ADMIN')")
public String guestOrAdminSayHello(String name) {
return name;
}
diff --git a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
index 800e52d..37de72d 100644
--- a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
+++ b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
@@ -17,6 +17,7 @@
package org.apache.servicecomb.authentication.resource;
+import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
@@ -28,6 +29,12 @@ import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
@@ -80,7 +87,14 @@ public class ResourceAuthHandler implements Handler {
}
// pre method authentiation
- invocation.addLocalContext(Constants.CONTEXT_HEADER_CLAIMS, jwt.getClaims());
+ Set<GrantedAuthority> grantedAuthorities = new HashSet<>(claims.getAuthorities().size());
+ claims.getAuthorities().forEach(v -> grantedAuthorities.add(new SimpleGrantedAuthority(v)));
+ SecurityContext sc = new SecurityContextImpl();
+ Authentication authentication = new SimpleAuthentication(true, grantedAuthorities);
+ sc.setAuthentication(authentication);
+ SecurityContextHolder.setContext(sc);
+
+ // next
invocation.next(asyncResponse);
}
diff --git a/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/SimpleAuthentication.java b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/SimpleAuthentication.java
new file mode 100644
index 0000000..a23404c
--- /dev/null
+++ b/authentication/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/SimpleAuthentication.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.authentication.resource;
+
+import java.util.Collection;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+
+public class SimpleAuthentication implements Authentication {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6077733273349249822L;
+
+ private boolean authenticated;
+
+ private Collection<? extends GrantedAuthority> authorities;
+
+ public SimpleAuthentication(boolean authenticated, Collection<? extends GrantedAuthority> authorities) {
+ this.authenticated = authenticated;
+ this.authorities = authorities;
+ }
+
+
+ @Override
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<? extends GrantedAuthority> getAuthorities() {
+ return this.authorities;
+ }
+
+ @Override
+ public Object getCredentials() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getDetails() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAuthenticated() {
+ return this.authenticated;
+ }
+
+ @Override
+ public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/authentication/ResourceServer/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter b/authentication/ResourceServer/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter
new file mode 100644
index 0000000..e6ad477
--- /dev/null
+++ b/authentication/ResourceServer/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.authentication.resource.AccessDeniedExceptionExceptionToProducerResponseConverter
\ No newline at end of file