跳到主内容

Spring Cloud Gateway

casdoor-springcloud-gateway-example是一个示例,说明如何在Spring Cloud Gateway中使用casdoor-spring-boot-starter作为OAuth2插件。 以下是使用它的步骤描述。

步骤1:部署Casdoor

Deploy Casdoor in production mode. See Server installation. Ensure the server is reachable and you can sign in at the login page (e.g. admin / 123).

步骤2:初始化一个Spring Cloud Gateway

Use the example code as-is or adapt it to your application.

您需要一个网关服务和至少一个业务服务。 在这个例子中,casdoor-gateway 是网关服务,casdoor-api 是业务服务。

步骤3:包含依赖项

casdoor-spring-boot-starter 依赖项添加到您的 Spring Cloud Gateway 项目中。

对于Apache Maven:

/casdoor-gateway/pom.xml
<!-- https://mvnrepository.com/artifact/org.casbin/casdoor-spring-boot-starter -->
<dependency>
<groupId>org.casbin</groupId>
<artifactId>casdoor-spring-boot-starter</artifactId>
<version>1.x.y</version>
</dependency>

对于Gradle:

// https://mvnrepository.com/artifact/org.casbin/casdoor-spring-boot-starter
implementation group: 'org.casbin', name: 'casdoor-spring-boot-starter', version: '1.x.y'

步骤4:配置您的属性

初始化需要6个参数,所有这些参数都是字符串类型。

名称(按顺序排列)需要描述
endpointCasdoor 服务器 URL,例如 http://localhost:8000
clientIdApplication.client_id
clientSecretApplication.client_secret
certificateApplication.certificate
organizationNameApplication.organization
applicationNameApplication.name

Initialize these parameters via Java properties or YAML.

对于属性:

casdoor.endpoint=http://localhost:8000
casdoor.clientId=<client-id>
casdoor.clientSecret=<client-secret>
casdoor.certificate=<certificate>
casdoor.organizationName=built-in
casdoor.applicationName=app-built-in

对于YAML:

casdoor:
endpoint: http://localhost:8000
client-id: <client-id>
client-secret: <client-secret>
certificate: <certificate>
organization-name: built-in
application-name: app-built-in

Configure gateway routing as well. 对于YAML:

spring:
application:
name: casdoor-gateway
cloud:
gateway:
routes:
- id: api-route
uri: http://localhost:9091
predicates:
- Path=/api/**

步骤5:添加CasdoorAuthFilter

在网关中添加GlobalFilter接口的实现类,用于身份验证,例如本例中使用的CasdoorAuthFilter。

如果身份验证失败,它将返回401状态码给前端,以重定向他们到登录界面。

@Component
public class CasdoorAuthFilter implements GlobalFilter, Ordered {

private static final Logger LOGGER = LoggerFactory.getLogger(CasdoorAuthFilter.class);

@Override public int getOrder() {
return 0;
}

@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return exchange.getSession().flatMap(webSession -> {
CasdoorUser user = webSession.getAttribute("casdoorUser");
if (user != null) {
return chain.filter(exchange);
}
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json");
return response.setComplete();
});
}
}

步骤6:获取服务并使用它

现在提供5项服务:CasdoorAuthServiceCasdoorUserServiceCasdoorEmailServiceCasdoorSmsService,以及CasdoorResourceService

Create them in the Gateway project as follows.

@Resource
private CasdoorAuthService casdoorAuthService;

When the app requires authentication, redirect to Casdoor's login page with the target URL.

Add the callback URL (e.g. http://localhost:9090/callback) to the Casdoor application in advance.

@RequestMapping("login")
public Mono<String> login() {
return Mono.just("redirect:" + casdoorAuthService.getSigninUrl("http://localhost:9090/callback"));
}

After Casdoor verifies the user, the app is redirected back with a code and state; use the code and getOAuthToken to obtain the JWT.

CasdoorUser holds the user info from Casdoor; use it to establish the session in your app.

@RequestMapping("callback")
public Mono<String> callback(String code, String state, ServerWebExchange exchange) {
String token = "";
CasdoorUser user = null;
try {
token = casdoorAuthService.getOAuthToken(code, state);
user = casdoorAuthService.parseJwtToken(token);
} catch(CasdoorAuthException e) {
e.printStackTrace();
}
CasdoorUser finalUser = user;
return exchange.getSession().flatMap(session -> {
session.getAttributes().put("casdoorUser", finalUser);
return Mono.just("redirect:/");
});
}

以下是API的示例。

  • CasdoorAuthService
    • String token = casdoorAuthService.getOAuthToken(code, "app-built-in");
    • CasdoorUser casdoorUser = casdoorAuthService.parseJwtToken(token);
  • CasdoorUserService
    • CasdoorUser casdoorUser = casdoorUserService.getUser("admin");
    • CasdoorUser casdoorUser = casdoorUserService.getUserByEmail("admin@example.com");
    • CasdoorUser[] casdoorUsers = casdoorUserService.getUsers();
    • CasdoorUser[] casdoorUsers = casdoorUserService.getSortedUsers("created_time", 5);
    • int count = casdoorUserService.getUserCount("0");
    • CasdoorResponse response = casdoorUserService.addUser(user);
    • CasdoorResponse response = casdoorUserService.updateUser(user);
    • CasdoorResponse response = casdoorUserService.deleteUser(user);
  • CasdoorEmailService
    • CasdoorResponse response = casdoorEmailService.sendEmail(title, content, sender, receiver);
  • CasdoorSmsService
    • CasdoorResponse response = casdoorSmsService.sendSms(randomCode(), receiver);
  • CasdoorResourceService
    • CasdoorResponse response = casdoorResourceService.uploadResource(user, tag, parent, fullFilePath, file);
    • CasdoorResponse response = casdoorResourceService.deleteResource(file.getName());

步骤7:重启项目

After starting the project, open your favorite browser and visit http://localhost:9090. 然后点击任何请求来自casdoor-api的资源的按钮。

index

The gateway triggers auth; unauthenticated users are redirected to the login page. Click Login.

toLogin

The Casdoor login page is shown.

login

After login, you are redirected to the main interface; you can proceed to use the app.

index-ok

更多内容

For more on Java integration, see the following projects and docs.