需要从Spring云网关路由中的OAuth2User中获取认证的用户名。

问题描述 投票:0回答:1

我是一个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

spring spring-boot spring-security spring-security-oauth2 spring-cloud-gateway
1个回答
0
投票
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;
        }
    }


    }
© www.soinside.com 2019 - 2024. All rights reserved.