java从azure中读取用户信息

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


   
   
        org.springframework.boot
        spring-boot-starter-web
   

    
   
   
        com.microsoft.azure
        msal4j
        1.13.3
   

    
   
   
        com.nimbusds
        nimbus-jose-jwt
        9.25
   

    
   
   
        org.apache.httpcomponents
        httpclient
        4.5.13
   


 

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 login() throws MalformedURLException {
        String authUrl = getAuthUrl();
        return Collections.singletonMap("loginUrl", authUrl);
    }
    
    // 第二步:处理回调
    @GetMapping("/auth/redirect")
    public Map handleRedirect(
            @RequestParam("code") String authCode,
            @RequestParam("state") String state
    ) throws Exception {
        
        // 使用授权码获取令牌
        IAuthenticationResult result = acquireToken(authCode);
        
        // 获取用户信息
        Map userInfo = getUserInfo(result.accessToken());
        
        // 返回用户信息
        Map 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 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 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>(){}.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 jwtProcessor() 
        throws MalformedURLException {
        
        // Azure AD JWKS端点
        String jwksUrl = String.format(
            "https://login.microsoftonline.com/%s/discovery/v2.0/keys", 
            tenantId
        );
        
        // 设置JWT处理器
        DefaultJWTProcessor jwtProcessor = 
            new DefaultJWTProcessor<>();
        
        // 配置JWK来源
        JWKSource keySource = 
            new RemoteJWKSet<>(new URL(jwksUrl));
        
        // 配置签名验证
        JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;
        JWSVerificationKeySelector 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;
    }
}
 

 

你可能感兴趣的:(java)