Skip to content

Security OAuth2 Plugin

对应模块: io.gitee.lcgyl:lcgyl-security-oauth2-plugin

企业级第三方登录集成方案。

✨ 特性

  • 多源支持 - 内置微信、钉钉、GitHub、标准 OAuth2 支持
  • 统一接口 - 屏蔽不同平台的协议差异
  • 自动绑定 - 支持第三方账号与本地账号自动绑定
  • 声明式客户端 - v2.2.0 基于 @HttpClient 重构

🚀 快速开始

依赖引入

gradle
implementation 'io.gitee.lcgyl:lcgyl-security-oauth2-plugin:2.2.0'

配置

yaml
lcgyl:
  security:
    oauth2:
      providers:
        # GitHub 登录
        github:
          client-id: your-github-client-id
          client-secret: your-github-client-secret
          scope: user:email
        
        # 微信登录
        wechat:
          client-id: your-wechat-appid
          client-secret: your-wechat-secret
          scope: snsapi_login
        
        # 钉钉登录
        dingtalk:
          client-id: your-dingtalk-appid
          client-secret: your-dingtalk-secret

登录入口

java
@RestController
@RequestMapping("/oauth2")
public class OAuth2Controller {
    
    @Inject
    private OAuth2AuthorizationService authService;
    
    // 获取授权跳转 URL
    @GetMapping("/authorize/{provider}")
    public RedirectView authorize(@PathVariable String provider) {
        String authUrl = authService.getAuthorizationUrl(provider);
        return new RedirectView(authUrl);
    }
    
    // OAuth2 回调处理
    @GetMapping("/callback/{provider}")
    public TokenResponse callback(
            @PathVariable String provider,
            @RequestParam String code,
            @RequestParam(required = false) String state) {
        
        // 1. 用授权码换取 access_token
        OAuth2AccessToken accessToken = authService.getAccessToken(provider, code);
        
        // 2. 获取用户信息
        OAuth2User oauth2User = authService.getUserInfo(provider, accessToken);
        
        // 3. 查找或创建本地用户
        User user = userService.findOrCreateByOAuth2(provider, oauth2User);
        
        // 4. 签发本地 JWT Token
        String jwtToken = jwtTokenProvider.createToken(user);
        
        return new TokenResponse(jwtToken);
    }
}

统一用户信息模型

java
public interface OAuth2User {
    String getId();           // 第三方平台用户 ID
    String getUsername();     // 用户名
    String getNickname();     // 昵称
    String getAvatar();       // 头像 URL
    String getEmail();        // 邮箱(可能为空)
    Map<String, Object> getAttributes();  // 原始属性
}

用户绑定服务

java
@Service
public class OAuth2UserService {
    
    @Inject
    private UserRepository userRepository;
    
    @Inject
    private OAuth2BindingRepository bindingRepository;
    
    public User findOrCreateByOAuth2(String provider, OAuth2User oauth2User) {
        // 查找已绑定的用户
        OAuth2Binding binding = bindingRepository.findByProviderAndExternalId(
            provider, oauth2User.getId());
        
        if (binding != null) {
            return userRepository.findById(binding.getUserId()).orElse(null);
        }
        
        // 创建新用户并绑定
        User user = new User();
        user.setUsername(generateUsername(oauth2User));
        user.setNickname(oauth2User.getNickname());
        user.setAvatar(oauth2User.getAvatar());
        user = userRepository.save(user);
        
        // 保存绑定关系
        OAuth2Binding newBinding = new OAuth2Binding();
        newBinding.setUserId(user.getId());
        newBinding.setProvider(provider);
        newBinding.setExternalId(oauth2User.getId());
        bindingRepository.save(newBinding);
        
        return user;
    }
}

自定义 OAuth2 Provider

java
@Component
public class CustomOAuth2Provider implements OAuth2Provider {
    
    @Override
    public String getName() {
        return "custom";
    }
    
    @Override
    public String getAuthorizationUrl(OAuth2Config config, String state) {
        return UriComponentsBuilder.fromUriString(config.getAuthorizationUri())
            .queryParam("client_id", config.getClientId())
            .queryParam("redirect_uri", config.getRedirectUri())
            .queryParam("state", state)
            .queryParam("scope", config.getScope())
            .build().toUriString();
    }
    
    @Override
    public OAuth2AccessToken getAccessToken(OAuth2Config config, String code) {
        // 实现 token 获取逻辑
    }
    
    @Override
    public OAuth2User getUserInfo(OAuth2Config config, OAuth2AccessToken token) {
        // 实现用户信息获取逻辑
    }
}

Released under the Apache License 2.0