我是一个Spring Cloud Gateway的新手,我创建了一个简单的SCG应用程序,我的用例是通过http请求头转发我的下游应用程序的认证用户名。我已经创建了一个简单的SCG应用程序,我的用例是通过http请求头将经过验证的用户名转发给我的下游应用程序。
这是我的SpringBoot类
package com.xyz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties.Jwt;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.security.oauth2.gateway.TokenRelayGatewayFilterFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
@SpringBootApplication
public class OracleSSOMultiplexer {
@Autowired
private TokenRelayGatewayFilterFactory filterFactory;
@GetMapping("/")
public String index(Model model,
@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient,
@AuthenticationPrincipal OAuth2User oauth2User) {
model.addAttribute("userName", oauth2User.getName());
model.addAttribute("clientName", authorizedClient.getClientRegistration().getClientName());
model.addAttribute("userAttributes", oauth2User.getAttributes());
return "index";
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
//.route("resource", r -> r.path("/resource")
.route(r -> r.path("/hyperion/**")
.filters(f -> f.filters(filterFactory.apply())
.addRequestHeader("HYPLOGIN", "scott") // I need to pass the authenticated username here instead of hardcoding it
.addResponseHeader("hyp-response", "hyp-response-header-val"))
.uri("http://localhost:8081/")
.id("hyperionModule"))
.build();
}
public static void main(String[] args) {
SpringApplication.run(OracleSSOMultiplexer.class, args);
}
}
而这是我的应用程序.yml
server:
port: 8080
logging:
level:
root: INFO
org.springframework.web: INFO
org.springframework.web.HttpLogging: DEBUG
org.springframework.security: DEBUG
org.springframework.security.oauth2: DEBUG
org.springframework.cloud.gateway: DEBUG
spring:
autoconfigure:
# TODO: remove when fixed https://github.com/spring-projects/spring-security/issues/6314
exclude: org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
thymeleaf:
cache: false
security:
oauth2:
client:
registration:
gateway:
provider: pingfederate
client-id: oidchyperion
client-secret: Lms@12345
authorization-grant-type: authorization_code
redirect-uri: http://localhost:8080/login/oauth2/code/gateway
scope: openid
provider:
pingfederate:
authorization-uri: https://xyz:9035/as/authorization.oauth2
token-uri: https://xyz:9035/as/token.oauth2
user-info-uri: https://xyz:9035/idp/userinfo.openid
user-name-attribute: sub
jwk-set-uri: https://xyz:9035/pf/JWKS
# cloud:
# gateway:
# routes:
# - id: resource
# uri: http://resource:9000
# predicates:
# - Path=/resource
# filters:
# - TokenRelay=
# - RemoveRequestHeader=Cookie
我能够执行OAuth认证,并且能够在index.html中使用Model显示已认证的用户信息。我现在只需要在请求头中传递登录用户的用户名(oauth2user.getName()),但我无法理解。
在这方面的任何帮助是感激的。
谢谢,Thani
package com.likeminds.filter;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import
org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
@Component
public class AuthNUserHeaderFilterFactory extends
AbstractGatewayFilterFactory<AuthNUserHeaderFilterFactory.Config> {
private static final String VALUE = "value";
public AuthNUserHeaderFilterFactory() {
super(Config.class);
}
@Override
public Config newConfig() {
return new Config();
}
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList(VALUE);
}
@Override
public GatewayFilter apply(Config config) {
//Custom Pre Filter. Suppose we can extract JWT and perform
Authentication
return (exchange, chain) -> exchange.getPrincipal()
.map(Principal::getName)
.defaultIfEmpty("Default User")
.map(userName -> {
//adds header to proxied request
System.out.println("Config value ="+config.value);
exchange.getRequest().mutate().header(config.value,
userName).build();
System.out.println("Config First pre header filter" +
exchange.getRequest().getHeaders());
return exchange;
})
.flatMap(chain::filter);
}
public static class Config {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}