当前位置: 首页 > 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;
    }
}
 

 

相关文章:

  • 【Pandas】pandas DataFrame sample
  • 微软重磅发布Magentic UI,交互式AI Agent助手实测!
  • mybatis 参数绑定错误示范(1)
  • AWS DocumentDB vs MongoDB:数据库的技术抉择
  • PostgreSQL的扩展 pg_buffercache
  • 第5篇《中间件负载均衡与连接池管理机制设计》
  • 银行用户评分规则 深度学习
  • Linux容器篇、第一章_01Linux系统下 Docker 安装与镜像部署全攻略
  • 分布式爬虫代理IP使用技巧
  • C++性能优化指南
  • go的工具库:github.com/expr-lang/expr
  • 突破数据孤岛:StarRocks联邦查询实战指南
  • 【发布实录】云原生+AI,助力企业全球化业务创新
  • Java设计模式:责任链模式
  • Linux 特殊权限位详解:SetUID, SetGID, Sticky Bit
  • 数据结构第一章
  • 【RAG优化】rag整体优化建议
  • [ Qt ] | 与系统相关的操作(二):键盘、定时器、窗口移动和大小
  • 跟着deepseek浅学分布式事务(2) - 两阶段提交(2PC)
  • yum更换阿里云的镜像源
  • 做网站图片自动切换/网络营销模式有哪几种
  • 想搭网站做软件首先要学设么/今日新闻摘抄十条简短
  • mac可以做网站服务器吗/信息如何优化上百度首页公司
  • 做网站推广业务怎么样/推广获客
  • 网站硬件建设方案/智能搜索引擎
  • 网站推广营销应该怎么做/网络seo公司