You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Vaadin应用中集成Steam OAuth 2登录遇阻,求经验指导

在Vaadin应用中集成Steam OAuth2登录的分步指南

1. Steam开发者平台前置配置

  • 登录Steam开发者后台创建应用,生成API Key
  • 配置回调URL,必须与应用实际地址一致,本地开发示例:http://localhost:8080/login/oauth2/code/steam;生产环境必须用HTTPS,Steam不允许HTTP回调
  • 记录API Key,后续配置会用到

2. 依赖与配置文件设置

2.1 Maven依赖(Spring Boot + Vaadin)

在pom.xml中添加OAuth2客户端核心依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>

2.2 application.yml 核心配置

Steam基于OpenID 2.0兼容OAuth2,配置需注意特殊规则:

spring:
  security:
    oauth2:
      client:
        registration:
          steam:
            client-id: 你的Steam API Key
            client-secret: ""  # Steam OAuth2不需要client-secret,留空即可
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/steam"
            scope: openid  # Steam固定scope为openid
        provider:
          steam:
            authorization-uri: https://steamcommunity.com/openid/login
            token-uri: https://steamcommunity.com/openid/login
            user-info-uri: https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/
            user-name-attribute: steamid

3. Spring Security + Vaadin 安全配置类

继承VaadinWebSecurity,保证Flow应用与OAuth2登录兼容:

import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends VaadinWebSecurity {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 开放OAuth2相关端点权限
        http.authorizeHttpRequests(auth -> auth
                .requestMatchers("/login/oauth2/**", "/oauth2/**").permitAll()
                .anyRequest().authenticated()
        );

        // 配置OAuth2登录流程
        http.oauth2Login(oauth2 -> oauth2
                .loginPage("/login")
                .defaultSuccessUrl("/", true)
                .userInfoEndpoint(userInfo -> userInfo.userService(new SteamOAuth2UserService()))
        );

        // 启用Vaadin默认安全规则
        super.configure(http);
        setLoginView(LoginView.class);
    }
}

4. 自定义Vaadin登录视图

创建带Steam登录按钮的页面:

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import static com.vaadin.flow.component.orderedlayout.Alignment.CENTER;
import static com.vaadin.flow.component.orderedlayout.JustifyContentMode.CENTER;

@Route("login")
public class LoginView extends VerticalLayout {

    public LoginView() {
        Button steamLoginBtn = new Button("用Steam登录", e -> 
            getUI().ifPresent(ui -> ui.navigate("/oauth2/authorization/steam"))
        );
        
        add(steamLoginBtn);
        setSizeFull();
        setAlignItems(CENTER);
        setJustifyContentMode(CENTER);
    }
}

5. 修复Steam用户信息获取问题

Spring OAuth2默认无法正确解析Steam用户信息接口返回格式,需自定义用户服务:

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

public class SteamOAuth2UserService extends DefaultOAuth2UserService {

    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2User baseUser = super.loadUser(userRequest);
        String steamId = baseUser.getAttribute("steamid");
        String apiKey = userRequest.getClientRegistration().getClientId();

        // 调用Steam API拉取用户详情
        String apiUrl = String.format(
            "https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=%s&steamids=%s",
            apiKey, steamId
        );
        Map<String, Object> apiResponse = restTemplate.getForObject(apiUrl, HashMap.class);
        Map<String, Object> playerData = ((Map<String, Object>) 
            ((Map<String, Object>) apiResponse.get("response")).get("players")).get("0");

        // 合并用户属性
        Map<String, Object> mergedAttributes = new HashMap<>(baseUser.getAttributes());
        mergedAttributes.putAll(playerData);
        return new org.springframework.security.oauth2.core.user.DefaultOAuth2User(
            baseUser.getAuthorities(), mergedAttributes, "steamid"
        );
    }
}

6. 常见安全与故障修复

  • 回调URL不匹配:Steam后台配置的回调地址必须与redirect-uri完全一致,包括协议、端口
  • CSRF报错:调试阶段可临时开放OAuth端点的CSRF豁免:http.csrf(csrf -> csrf.ignoringRequestMatchers("/login/oauth2/**", "/oauth2/**")),生产环境建议保留CSRF保护
  • 用户信息为空:检查Steam API Key是否有权限调用GetPlayerSummaries接口,确认用户登录时已授权
  • 登录后无跳转:验证defaultSuccessUrl指向的路由存在且已配置权限

内容的提问来源于stack exchange,提问作者Fedox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 20:22:53