如何使用Scala通过Graph API生成令牌并发送邮件通知
Scala实现Microsoft Graph API令牌生成(客户端凭证模式)
以下是对应你提供的Python代码的Scala版本,实现相同的客户端凭证模式获取Graph API访问令牌功能,提供两种常用实现方式:
方式一:使用Java HttpClient(依赖少,Scala兼容)
这种方式无需额外的Scala HTTP库,直接使用Java标准库的HttpClient,搭配轻量JSON解析库ujson:
import java.net.URI import java.net.http.{HttpClient, HttpRequest, HttpResponse} import java.nio.charset.StandardCharsets import scala.jdk.CollectionConverters._ object GraphTokenGenerator { private val TOKEN_URL = "https://login.microsoftonline.com/bgd57sd-dsd-4b9d-b9c5-0f64b6755421/oauth2/token" def getAccessToken(url: String): String = { // 从环境变量读取客户端ID和密钥 val clientId = sys.env("AD_APP_ID") val clientSecret = sys.env("AD_APP_SECRET") // 构造URL编码的表单参数 val formData = Map( "client_id" -> clientId, "client_secret" -> clientSecret, "grant_type" -> "client_credentials", "resource" -> "https://graph.microsoft.com" ).map { case (key, value) => s"$key=${java.net.URLEncoder.encode(value, StandardCharsets.UTF_8.name())}" }.mkString("&") // 创建并发送POST请求 val client = HttpClient.newHttpClient() val request = HttpRequest.newBuilder() .uri(URI.create(url)) .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(formData)) .build() // 解析响应JSON,提取access_token val response = client.send(request, HttpResponse.BodyHandlers.ofString()) val json = ujson.read(response.body()) json("access_token").str } def main(args: Array[String]): Unit = { val accessToken = getAccessToken(TOKEN_URL) println(accessToken) } }
依赖配置(build.sbt)
libraryDependencies += "com.lihaoyi" %% "ujson" % "3.1.2"
方式二:使用Akka HTTP(Scala异步HTTP库)
如果你的项目已经使用Akka生态,推荐用这种异步实现:
import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.ActorMaterializer import scala.concurrent.{ExecutionContextExecutor, Future} import scala.util.{Failure, Success} object GraphTokenAkka { private val TOKEN_URL = "https://login.microsoftonline.com/bgd57sd-dsd-4b9d-b9c5-0f64b6755421/oauth2/token" def main(args: Array[String]): Unit = { implicit val system: ActorSystem = ActorSystem("GraphTokenSystem") implicit val materializer: ActorMaterializer = ActorMaterializer() implicit val executionContext: ExecutionContextExecutor = system.dispatcher val clientId = sys.env("AD_APP_ID") val clientSecret = sys.env("AD_APP_SECRET") // 构造表单数据 val formData = FormData( "client_id" -> clientId, "client_secret" -> clientSecret, "grant_type" -> "client_credentials", "resource" -> "https://graph.microsoft.com" ) // 构建HTTP请求 val request = HttpRequest( method = HttpMethods.POST, uri = TOKEN_URL, entity = formData.toEntity(HttpCharsets.`UTF-8`) ) // 发送异步请求并处理响应 val responseFuture: Future[HttpResponse] = Http().singleRequest(request) responseFuture.onComplete { case Success(response) => Unmarshal(response.entity).to[String].map { body => val json = ujson.read(body) val accessToken = json("access_token").str println(accessToken) system.terminate() } case Failure(ex) => println(s"请求失败: ${ex.getMessage}") system.terminate() } } }
依赖配置(build.sbt)
libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-http" % "10.2.10", "com.typesafe.akka" %% "akka-stream" % "2.6.20", "com.lihaoyi" %% "ujson" % "3.1.2" )
注意事项
- 确保环境变量
AD_APP_ID和AD_APP_SECRET已正确设置 - 两种实现均遵循原Python代码的逻辑,使用客户端凭证授权模式
- 若偏好其他JSON解析库,可将ujson替换为Play JSON、Circe等
内容的提问来源于stack exchange,提问作者venkat
相关产品推荐
相关产品推荐

