ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TypeSpec Java 客户端 OAuth 2.0 凭证实践指南:从 OAuth2Auth 定义到自定义 OAuthTokenCredential

TypeSpec Java 客户端 OAuth 2.0 凭证实践指南:从 OAuth2Auth 定义到自定义 OAuthTokenCredential TypeSpec Java 客户端 OAuth 2.0 凭证实践指南从 OAuth2Auth 定义到自定义 OAuthTokenCredential【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec本文基于 TypeSpec 仓库中 Java 客户端 OAuth 2.0 凭证示例文档 展开讲解如何先在 TypeSpec 规范中以OAuth2Auth声明客户端凭证client credentials流程再为生成的 Java 客户端提供自定义OAuthTokenCredential实现并把它注入生成客户端的 Builder 完成端到端认证。读完后你将掌握 TypeSpec 认证声明到 Java 运行时凭证实现的完整链路并能根据auth_flows参数自行扩展其他 OAuth 流程与错误处理。整体认证链路声明、生成与运行时注入整个方案分三个环节协作声明在 TypeSpec 文件中通过useAuth(OAuth2Auth...)声明服务支持的 OAuth 2.0 流程生成TypeSpec 的 Java 代码生成器http-client-java读取安全方案信息在生成的ClientBuilder中预留credential(OAuthTokenCredential)入口并把安全流程序列化为auth_flowsJSON 参数随请求上下文传给凭证实现运行时开发者提供自定义OAuthTokenCredential实现负责真正向令牌端点换取 access token生成客户端的 HTTP 管道通过OAuthBearerTokenAuthenticationPolicy自动把令牌写入Authorization: Bearer token请求头。从源码结构看auth_flows参数正是生成器在构建 Builder 时注入的TemplateHelper.java 在检测到凭证字段时将安全方案中的 flows 序列化为 JSON 字符串并写入OAuthTokenRequestContext。这就是下面凭证实现中读取request.getParams().get(auth_flows)的来源。第一步在 TypeSpec 中用 OAuth2Auth 定义客户端在 TypeSpec 文件中使用OAuth2Auth模板声明客户端凭证流程并配套service与server修饰符import typespec/http; using TypeSpec.Http; useAuth( OAuth2Auth[ { type: OAuth2FlowType.clientCredentials, tokenUrl: https://tokenUrl, scopes: [scope], } ] ) service(#{ title: Example Server API }) server(https://endpoint, Example Server Endpoint) namespace ExampleServer { model Result { value: string; } // Test API endpoint route(/api/getValue) get op getResult(): Result[]; }各参数的含义可以直接在 auth.tsp 的规范定义中对照OAuth2AuthFlows, Scopes模板接收一个流程数组flows和所有流程共享的默认 scope 列表defaultScopesauth.tsp L114-L123OAuth2FlowType枚举支持四种流程authorizationCode、implicit、password、clientCredentialsauth.tsp L126-L138客户端凭证流程对应ClientCredentialsFlow模型必填字段为tokenUrl可选字段为refreshUrl和scopesauth.tsp L190-L203。上例选择了clientCredentials流程客户端以自身的clientId/clientSecret向令牌端点换取 access token适合服务端到服务端的调用场景无需用户交互。第二步自定义 OAuthTokenCredential 实现生成客户端只约定凭证接口令牌获取逻辑由开发者实现。以下示例实现支持客户端凭证流程使用 Jackson 作为 JSON 库仅作为示例可按项目需要替换public class TestCredential implements OAuthTokenCredential { private String clientId; private String clientSecret; public TestCredential setClientId(String clientId) { this.clientId clientId; return this; } public TestCredential setClientSecret(String clientSecret) { this.clientSecret clientSecret; return this; } Override public AccessToken getToken(OAuthTokenRequestContext request) { // 这里也可以改用 IDP 提供的库。本实现只是执行 OAuth 客户端凭证流程。 try { ObjectMapper mapper new ObjectMapper(); // 取第一个认证流程 ListMapString, String authFlows mapper.readValue((String) request.getParams().get(auth_flows), new TypeReferenceListMapString, String() {}); // 仅使用第一个流程 String tokenUrl authFlows.get(0).get(tokenUrl); String scope authFlows.get(0).get(scopes); HttpClient client getHttpClient(); // 假定环境中已有一条处理客户端池化等事宜的路径 HttpRequest httpRequest HttpRequest.newBuilder() .uri(URI.create(tokenUrl)) .header(Content-Type, application/x-www-form-urlencoded) .POST(HttpRequest.BodyPublishers.ofString(grant_typeclient_credentialsclient_id clientId client_secret clientSecret scope scope)) .build(); HttpResponseString response client.send(httpRequest, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() 200) { MapString, Object responseBody mapper.readValue(response.body(), Map.class); String accessToken (String)responseBody.get(access_token); return new AccessToken(accessToken, OffsetDateTime.now().plusSeconds((Integer)responseBody.get(expires_in))); } else { throw new RuntimeException(Failed to get token: response.body()); } } catch (Exception e) { throw new RuntimeException(Exception occurred while getting token, e); } } }实现要点getToken从OAuthTokenRequestContext的auth_flows参数中拿到 TypeSpec 声明的认证流程JSON 序列化的流程数组从中提取tokenUrl与scopes据此构造grant_typeclient_credentials的表单 POST 请求成功时解析access_token与expires_in构造AccessToken令牌 到期时间expires_in用于让管道在令牌过期前重新取令牌文档明确提示该示例应按实际需求修改包括选择合适的 OAuth 流程、合适的 JSON 库、以及适当的错误处理与日志。关于auth_flows的 JSON 结构需要留意从生成器测试样例 OAuth2ClientBuilder.java 中可以看到实际写入的参数形如[{type:implicit,authorizationUrl:...,scopes:[{value:...}]}]即scopes字段是以对象数组[{value: ...}]呈现的。因此示例中把scopes直接按字符串取用的写法是简化处理接入真实生成的客户端时建议先打印核对auth_flows的实际结构再解析。第三步把凭证注入生成的客户端并发出请求TypeSpec 中声明OAuth2Auth后生成器会为客户端 Builder 生成credential方法。对照样例 OAuth2ClientBuilder.java L183-L186 的credential(OAuthTokenCredential)实现可见Builder 只是保存凭证在构建 HTTP 管道时createHttpPipeline 方法 L233-L252只有当tokenCredential ! null时才会追加OAuthBearerTokenAuthenticationPolicy由该策略负责在每次请求前调用凭证获取令牌并附加认证头。使用示例——通过自定义凭证构建客户端并调用 APITestCredential credential new TestCredential().setClientId(myClientId).setClientSecret(myClientSecret); var client new ExampleServerClientBuilder().credential(credential).build(); client.getResult();其中ExampleServerClientBuilder对应上文 TypeSpec 中的ExampleServer命名空间getResult()对应getResult操作。小结该方案的分工是TypeSpec 负责声明“需要什么认证”OAuth2Auth流程与tokenUrl、scopes生成器负责把声明固化进客户端 Buildercredential入口 auth_flows参数 认证管道策略开发者只负责实现OAuthTokenCredential.getToken中“如何拿到令牌”这一段。切换到授权码、密码等其他流程时只需调整 TypeSpec 声明并在getToken中按对应流程取令牌即可如需更多细节可参考仓库中typespec/http的OAuth2Auth定义auth.tsp以及 Java 生成器模板代码TemplateHelper.java。【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表