使用Keycloak登录并访问后端API

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

我正在尝试使用 Keycloak 作为集中授权服务器将 Vaadin 前端连接到后端 API。

目前我有一个用 FastAPI 编写的 API 服务,可用于提交数据并在数据处理后接收分析结果。结果存储在每个租户/用户组的不同数据库模式中。 该 API 应该用于以多种方式集成服务,例如其他应用程序。

现在我想为 Vaadin 提供一个用户界面,以便非技术用户更容易使用我的 API 功能。我想允许使用 Keycloak 中存储的凭据登录应用程序。 我之前曾在另一个普通 Java 应用程序中使用过 Vaadin,但我对使用 Spring、Spring Security 和 OAuth2/Keycloak 还不熟悉。

我认为流程应该是:

  1. 用户尝试登录 UI。
  2. UI 连接到指定领域的 Keycloak 并尝试对用户进行身份验证。
  3. 如果成功,则用户已登录。
  4. 应用程序现在调用 API 来加载一些数据以使用用户访问令牌进行显示。
  5. API 验证令牌并返回该用户数据。

我设法为关注这些博客的用户实现登录: https://martinelli.ch/vaadin-oauth2-and-keycloak/ https://rene-wilby.de/blog/hilla-oauth-authorization-code-flow-keycloak/

@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {

    private final KeycloakLogoutHandler keycloakLogoutHandler;

    public SecurityConfiguration(KeycloakLogoutHandler keycloakLogoutHandler) {
        this.keycloakLogoutHandler = keycloakLogoutHandler;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeHttpRequests(
                authorize -> authorize.requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll());

        // Icons from the line-awesome addon
        http.authorizeHttpRequests(authorize -> authorize
                .requestMatchers(new AntPathRequestMatcher("/line-awesome/**/*.svg")).permitAll());

        http.oauth2Login(Customizer.withDefaults()).logout( logout ->
                logout.addLogoutHandler(keycloakLogoutHandler)

        );

        super.configure(http);

        setOAuth2LoginPage(http, "/oauth2/authorization/keycloak");
    }

    @Bean
    public GrantedAuthoritiesMapper userAuthoritiesMapperForKeycloak() {
        return authorities -> {
            Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
            var authority = authorities.iterator().next();
            if (authority instanceof OidcUserAuthority oidcUserAuthority) {
                var userInfo = oidcUserAuthority.getUserInfo();
                if (userInfo.hasClaim("realm_access")) {
                    var realmAccess = userInfo.getClaimAsMap("realm_access");
                    var roles = (Collection<String>) realmAccess.get("roles");
                    mappedAuthorities.addAll(roles.stream()
                            .map(role -> new SimpleGrantedAuthority("ROLE_" + role.toUpperCase()))
                            .toList());
                }
            }
            return mappedAuthorities;
        };
    }
}

我收到 OicdUser 并能够访问其信息。但是,OicdUser 仅包含 ID-Token,这不是应该发送到 API 的内容(根据我的理解)。

如何接收访问令牌并使用它向后端 API 发出请求? 这是解决问题的正确方法还是我有一些误解?

提前致谢!

spring-security keycloak vaadin vaadin-flow
1个回答
0
投票

您可以从

OAuth2AuthorizedClientManager
bean 获取访问令牌。

要查询资源服务器,您需要一个 REST 客户端,可能是

RestClient
WebClient
RestTemplate
@FeignClient
之一(最后两个处于维护模式,因此在新集成中应该避免使用) )。所有这些都有自己的与授权客户集成的说明,请参阅您选择的客户的文档。

我刚刚编写的这个入门程序为 OAuth2 授权提供了一些自动配置,包括

RestClient
WebClient
。你可以尝试一下。

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