Spring Boot后端无需用户认证查询Azure AD用户启用状态
解决方案
1. 配置Azure AD应用权限
在Azure门户的应用注册中,为你的Spring Boot应用添加应用权限:
- 权限类型:应用权限
- 选择
Microsoft Graph→User.Read.All - 点击"授予管理员同意"(必须完成此步骤,否则应用无法查询用户状态)
2. 配置Spring Boot的OAuth2客户端凭证流
在application.properties中补充客户端凭证相关配置:
# 客户端凭证流配置 spring.security.oauth2.client.registration.azure-client.client-id=${azure.client-id} spring.security.oauth2.client.registration.azure-client.client-secret=${azure.client-secret} spring.security.oauth2.client.registration.azure-client.authorization-grant-type=client_credentials spring.security.oauth2.client.provider.azure-client.token-uri=https://login.microsoftonline.com/${azure.tenant-id}/oauth2/v2.0/token spring.security.oauth2.client.provider.azure-client.jwk-set-uri=https://login.microsoftonline.com/${azure.tenant-id}/discovery/v2.0/keys
3. 实现Azure AD用户状态查询服务
创建服务类,用于获取客户端凭证令牌并调用Microsoft Graph API查询用户启用状态:
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.util.List; import java.util.Map; @Service public class AzureADUserStatusService { private final OAuth2AuthorizedClientService authorizedClientService; private final ClientRegistration clientRegistration; private final RestTemplate restTemplate; public AzureADUserStatusService(OAuth2AuthorizedClientService authorizedClientService, ClientRegistrationRepository clientRegistrationRepository) { this.authorizedClientService = authorizedClientService; this.clientRegistration = clientRegistrationRepository.findByRegistrationId("azure-client"); this.restTemplate = new RestTemplate(); } // 获取客户端凭证模式的访问令牌 private String getClientCredentialsToken() { OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient( clientRegistration.getRegistrationId(), "client-credentials" ); if (authorizedClient == null || authorizedClient.getAccessToken().isExpired()) { authorizedClient = authorizedClientService.authorizeClient(clientRegistration, null); } return authorizedClient.getAccessToken().getTokenValue(); } // 通过邮箱查询用户是否启用 public boolean isUserEnabled(String userEmail) { String token = getClientCredentialsToken(); String graphApiUrl = String.format( "https://graph.microsoft.com/v1.0/users?$filter=mail eq '%s'&$select=accountEnabled", userEmail ); org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders(); headers.setBearerAuth(token); org.springframework.http.HttpEntity<String> entity = new org.springframework.http.HttpEntity<>(headers); Map<String, Object> response = restTemplate.exchange( graphApiUrl, org.springframework.http.HttpMethod.GET, entity, Map.class ).getBody(); if (response != null && response.containsKey("value")) { List<Map<String, Object>> users = (List<Map<String, Object>>) response.get("value"); if (!users.isEmpty()) { return (boolean) users.get(0).get("accountEnabled"); } } return false; } }
4. 实现定时检查清理任务
创建定时任务类,每24小时执行一次用户状态检查,删除禁用用户的凭证:
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class UserCredentialCleanupTask { private final AzureADUserStatusService azureADUserStatusService; private final UserCredentialRepository userCredentialRepository; // 替换为你的凭证仓储类 public UserCredentialCleanupTask(AzureADUserStatusService azureADUserStatusService, UserCredentialRepository userCredentialRepository) { this.azureADUserStatusService = azureADUserStatusService; this.userCredentialRepository = userCredentialRepository; } // 每24小时执行一次(cron表达式:0 0 0 * * ?) @Scheduled(cron = "0 0 0 * * ?") public void cleanupDisabledUserCredentials() { userCredentialRepository.findAll().forEach(credential -> { boolean isEnabled = azureADUserStatusService.isUserEnabled(credential.getUserEmail()); if (!isEnabled) { userCredentialRepository.delete(credential); } }); } }
5. 启用Spring定时任务
在Spring Boot启动类上添加@EnableScheduling注解:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
关键说明
- 客户端凭证流:让应用以自身身份向Azure AD请求令牌,无需用户参与认证,适合后台定时任务场景。
- 权限说明:
User.Read.All应用权限是查询所有用户状态的必要条件,必须完成管理员授权。 - API优化:通过
$filter和$select参数精准过滤数据,减少不必要的网络传输。
内容的提问来源于stack exchange,提问作者p0w3rs
相关产品推荐
相关产品推荐

