我们有一个openid connect的实现,该实现返回一个编码的id令牌,这个方法运行良好并且已经运行了一段时间。但是,我们尝试在aws中使用cognito连接到它,经过一番尝试和错误之后,我们发现我们缺少一个.well-known / openid-configuration文件。
此文件旨在包含有关对我们拥有的openid-connect服务器的调用的信息,包括JWK密钥。
我不了解JWK密钥,这意味着: 1.如何生成它们 2.一旦产生了对它们的处理? 3.我们用于openid-connect的现有代码是否需要更改和使用JWK密钥? 4.有什么方法可以验证openid-connect配置吗?
我前段时间曾问过类似的问题,但没有回头。
谢谢 凯文
我已经尝试过的方法: 曾在这里:https://mkjwk.org/,然后单击“新密钥”,它返回了我认为是Web密钥的信息。但是不知道我要用它做什么或其他选项卡的含义。
预期结果: 希望AWS Cognito能够继续并允许其连接到我们的开放ID Connect实现。目前,关于丢失的众所周知的配置文件,您只会得到一个错误。
答案 0 :(得分:1)
您拥有的openid连接服务器生成的ID令牌为JWS。 这些令牌使用私钥(EC,RSA或OKP)签名。
众所周知的/ openid-configuration应该包含一个JSON对象,该对象指示使用什么算法来对令牌进行签名,以及url以获取与用于对令牌进行签名的私钥相关联的公钥。
例如,Google Account server configuration表示可以在https://www.googleapis.com/oauth2/v3/certs(jwks_uri
参数)处找到公钥。
在此URL上,您将找到以JWK(JSON Web密钥)格式设置的密钥(JWKSet)列表。这些格式(JWK和JWKSet)是JWT上下文中使用的密钥和密钥集的标准表示(请参见RFC7517)。
- 如何生成它们
通常,您已经至少有一个私钥来对令牌进行签名,因此您不必生成新的私钥。
- 一旦产生了对它们的处理?
您拥有的私钥应该是PEM(以------ PRIVATE RSA KEY -----
或类似开头)或DER密钥。
您只需要将此密钥转换为JWK。
我创建了a small PHAR application (PHP),它将有助于转换您的密钥。该应用是Web Token Framework的一部分,但可以作为独立应用安装。确保已安装PHP 7.1,OpenSSL和JSON扩展。 安装该应用程序后,您可以执行以下命令:
jose key:convert:public $(jose key:load:key PATH_TO_YOUR_KEY)
此命令会将私钥转换为JWK,然后将其从私钥转换为公共。 可以通过jwks_uri端点共享结果。
- 我们为openid-connect提供的现有代码是否需要更改并使用JWK密钥?
不。构建令牌的方式并不意味着您必须进行任何更改。
- 有什么方法可以验证openid-connect配置?
据我所知,没有工具可以验证配置对象。您必须参考OpenID Connect规范。
答案 1 :(得分:0)
尽管Florent回答了公钥的用法,但我想向您指出定义JWK内容和特定实现细节的规范。
OpenID Connect discovery 定义发现文档。在那里,您找到jwks_uri
URL作为元数据的一部分,它指向JSON Web Key Set
wks_uri
必填。 OP的JSON Web密钥集[JWK]文档的URL。这个 包含RP用于验证签名的签名密钥 OP
现在,这指向RFC7517 - JSON Web Key (JWK)。您可以在此处找到JSON有效负载每个字段的确切详细信息。请参阅其样本和附录部分以查看样本内容。并且您的实现必须遵循由此定义的规范要求。
对于编码,如果您使用的是JAVA,建议您使用 Nimbus JOSE + JWT库。可以从此link中找到示例。
例如,如果您已经加载X509Certificate
,则以下是生成JWK的简约代码。它被嵌入到Servlet [Full source]中。
import Common.CertificateLoader;
import Common.Exceptions.FrameworkUncheckedException;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.JWK;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.cert.X509Certificate;
@WebServlet(urlPatterns = "/openid-configuration/jwks_uri")
public class JWKDocument extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// NOTE - LOAD YOUR CERTIFICATE HERE
final X509Certificate certificate = CertificateLoader.getCertificateLoader().getX509Certificate();
final JWK jwk;
try {
jwk = JWK.parse(certificate);
} catch (JOSEException e) {
throw new FrameworkUncheckedException("Error while loading to JWK", e);
}
resp.getOutputStream().print(jwk.toJSONString());
}
}