当前位置: 首页 > news >正文

java从azure中读取用户信息

以下是用 Java 从 Azure AD 获取用户信息的完整实现方案,使用 Spring Boot 框架和 Microsoft 身份验证库 (MSAL):
 
1. 添加 Maven 依赖

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Azure AD MSAL -->
    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>msal4j</artifactId>
        <version>1.13.3</version>
    </dependency>
    
    <!-- JWT 处理 -->
    <dependency>
        <groupId>com.nimbusds</groupId>
        <artifactId>nimbus-jose-jwt</artifactId>
        <version>9.25</version>
    </dependency>
    
    <!-- HTTP 客户端 -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
</dependencies>
 

2. 配置 Azure AD 参数
在  application.properties  中:

# Azure AD 配置
azure.client-id=your_client_id
azure.client-secret=your_client_secret
azure.tenant-id=your_tenant_id
azure.redirect-uri=https://your-app.com/auth/redirect
azure.scope=openid profile User.Read
 

3. 控制器实现

import com.microsoft.aad.msal4j.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.net.MalformedURLException;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

@RestController
public class AuthController {
    
    @Value("${azure.client-id}")
    private String clientId;
    
    @Value("${azure.client-secret}")
    private String clientSecret;
    
    @Value("${azure.tenant-id}")
    private String tenantId;
    
    @Value("${azure.redirect-uri}")
    private String redirectUri;
    
    @Value("${azure.scope}")
    private String scope;
    
    // 第一步:生成登录URL
    @GetMapping("/login")
    public Map<String, String> login() throws MalformedURLException {
        String authUrl = getAuthUrl();
        return Collections.singletonMap("loginUrl", authUrl);
    }
    
    // 第二步:处理回调
    @GetMapping("/auth/redirect")
    public Map<String, Object> handleRedirect(
            @RequestParam("code") String authCode,
            @RequestParam("state") String state
    ) throws Exception {
        
        // 使用授权码获取令牌
        IAuthenticationResult result = acquireToken(authCode);
        
        // 获取用户信息
        Map<String, Object> userInfo = getUserInfo(result.accessToken());
        
        // 返回用户信息
        Map<String, Object> response = new HashMap<>();
        response.put("id_token_claims", result.idToken());
        response.put("user_info", userInfo);
        
        return response;
    }
    
    // 生成认证URL
    private String getAuthUrl() throws MalformedURLException {
        ConfidentialClientApplication app = ConfidentialClientApplication.builder(
                clientId, ClientCredentialFactory.createFromSecret(clientSecret))
                .authority("https://login.microsoftonline.com/" + tenantId)
                .build();
        
        AuthorizationCodeParameters parameters = AuthorizationCodeParameters.builder(
                authCode, 
                new URI(redirectUri)
            ).scopes(Collections.singleton(scope))
             .build();
        
        String authorizationUrl = app.getAuthorizationRequestUrl(
                AuthorizationRequestUrlParameters
                    .builder(redirectUri, Collections.singleton(scope))
                    .build()
            ).toString();
        
        return authorizationUrl;
    }
    
    // 使用授权码获取令牌
    private IAuthenticationResult acquireToken(String authCode) 
        throws MalformedURLException, ExecutionException, InterruptedException {
        
        ConfidentialClientApplication app = ConfidentialClientApplication.builder(
                clientId, ClientCredentialFactory.createFromSecret(clientSecret))
                .authority("https://login.microsoftonline.com/" + tenantId)
                .build();
        
        AuthorizationCodeParameters parameters = AuthorizationCodeParameters.builder(
                authCode, 
                new URI(redirectUri)
            ).scopes(Collections.singleton(scope))
             .build();
        
        return app.acquireToken(parameters).get();
    }
    
    // 使用访问令牌获取用户信息
    private Map<String, Object> getUserInfo(String accessToken) {
        String graphEndpoint = "https://graph.microsoft.com/v1.0/me";
        
        // 使用HttpClient调用Graph API
        // 实际实现需要添加错误处理和JSON解析
        return fetchUserDataFromGraph(graphEndpoint, accessToken);
    }
    
    // 调用Microsoft Graph API的实现
    private Map<String, Object> fetchUserDataFromGraph(String endpoint, String accessToken) {
        // 这里使用HttpClient简化实现
        // 实际项目使用RestTemplate或WebClient
        
        HttpGet request = new HttpGet(endpoint);
        request.setHeader("Authorization", "Bearer " + accessToken);
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault();
             CloseableHttpResponse response = httpClient.execute(request)) {
            
            String json = EntityUtils.toString(response.getEntity());
            return new Gson().fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
            
        } catch (Exception e) {
            throw new RuntimeException("Failed to fetch user info", e);
        }
    }
}
 

4. 安全配置类 (可选)

import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.jwk.source.RemoteJWKSet;
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
import com.nimbusds.jose.proc.SecurityContext;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.proc.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.MalformedURLException;
import java.net.URL;

@Configuration
public class SecurityConfig {

    @Value("${azure.tenant-id}")
    private String tenantId;
    
    // 配置JWT验证器
    @Bean
    public ConfigurableJWTProcessor<SecurityContext> jwtProcessor() 
        throws MalformedURLException {
        
        // Azure AD JWKS端点
        String jwksUrl = String.format(
            "https://login.microsoftonline.com/%s/discovery/v2.0/keys", 
            tenantId
        );
        
        // 设置JWT处理器
        DefaultJWTProcessor<SecurityContext> jwtProcessor = 
            new DefaultJWTProcessor<>();
        
        // 配置JWK来源
        JWKSource<SecurityContext> keySource = 
            new RemoteJWKSet<>(new URL(jwksUrl));
        
        // 配置签名验证
        JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;
        JWSVerificationKeySelector<SecurityContext> keySelector = 
            new JWSVerificationKeySelector<>(expectedJWSAlg, keySource);
        
        jwtProcessor.setJWSKeySelector(keySelector);
        
        // 设置JWT声明验证器
        jwtProcessor.setJWTClaimsSetVerifier(new DefaultJWTClaimsVerifier<>(
            new JWTClaimsSet.Builder().build(),
            new HashSet<>(Arrays.asList("sub", "aud", "exp", "iat"))));
        
        return jwtProcessor;
    }
}
 

 

http://www.lqws.cn/news/121915.html

相关文章:

  • Docker 常用命令详解
  • docker生命周期
  • Elasticsearch的搜索流程描述
  • 微软的新系统Windows12未来有哪些新特性
  • Python 隐藏法宝:双下划线 _ _Dunder_ _
  • stripe支付测试,ngrok无法使用?免费vscode端口转发,轻松简单!
  • Java Lombok @Data 注解用法详解
  • 打卡Day44
  • 吴恩达机器学习讲义概述
  • 泛型编程技巧——使用std::enable_if实现按类型进行条件编译​
  • 《Coevolutionary computation and its application》协同演化及其应用中文对照·第一章
  • [杰理]蓝牙状态机设计与实现详解
  • unix/linux,sudo,其高级使用
  • AI助力Java开发:减少70%重复编码,实战效能提升解析
  • [Harmony]颜色初始化
  • 【Linux】网络--传输层--深入理解TCP协议
  • 【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录
  • Flutter面试题
  • 【Linux】centos软件安装
  • 卫星在轨姿态控制技术详解:从自旋稳定到高精度闭环控制
  • 各个布局的区别以及示例
  • 【学习笔记】Circuit Tracing: Revealing Computational Graphs in Language Models
  • R语言基础| 下载、安装
  • 豆瓣图书评论数据分析与可视化
  • Nginx+Tomcat负载均衡与动静分离架构
  • 夏普比率(Sharpe ratio)​
  • MySQL EXPLAIN 命令详解
  • 【Python金融笔记】加载数据与可视化
  • MCP客户端Client开发流程
  • 0. MySQL在Centos 7环境安装