1

我正在评估 Authlib 以设置 OpenID 连接和 Oauth2.0 授权服务器。到目前为止,它对我来说效果很好。我试图查看是否可以轻松发布众所周知的 url,以便我可以让用 SpringBoot 编写的应用程序与 Authlib 服务器发出的 JWT 一起工作。

https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver

我找不到太多关于如何发布知名 url 端点的文档或示例。在这方面的任何指导,将不胜感激。

4

2 回答 2

1

我也找不到这个问题的答案,所以复制谷歌的知名回复。希望能帮助到你。

def openid_configuration():
    return dict(
        issuer=current_app.config['BACKEND_URL'],
        authorization_endpoint=f"{current_app.config['FRONTEND_URL']}/authorize",
        device_authorization_endpoint=None,
        token_endpoint=f"{current_app.config['BACKEND_URL']}/api/token",
        userinfo_endpoint=None,
        revocation_endpoint=None,
        jwks_uri=f"{current_app.config['BACKEND_URL']}/api/public-key",
        response_types_supported=["code"],
        subject_types_supported=[],
        id_token_signing_alg_values_supported=["RS256"],
        scopes_supported=["openid", "email", "actions", "meta"],
        token_endpoint_auth_methods_supported=["client_secret_post"],
        claims_supported=["email", "iat", "iss", "name", "sub"],
        code_challenge_methods_supported=[],
        grant_types_supported=["authorization_code"]
    )

于 2020-04-10T17:19:15.440 回答
0

我能够使用此处理程序扩展 oidc 烧瓶示例

@bp.route("/.well-known/openid-configuration")
def well_known_openid_configuration():
    def external_url(function_name):
        return url_for(function_name, _external=True)
    
    return jsonify({
        "authorization_endpoint": external_url('.authorize_endpoint'),
        "token_endpoint": external_url('.token_endpoint'),
        "userinfo_endpoint": external_url('.userinfo_endpoint'),
        "jwks_uri": external_url('.jwks_endpoint'),
        # Do I even need this one?
        # IMO the OIDC server doesn't have a concept of a user being still logged in? --mh
        # "end_session_endpoint": "http://oidc:4000/openid/end-session",
        "id_token_signing_alg_values_supported": [
            "HS256",
            "RS256"
        ],
        "issuer": JWT_CONFIG['iss'],
        "response_types_supported": [
            "code",
            # TODO check what it takes to support these too
            # "id_token",
            # "id_token token",
            # "code token",
            # "code id_token",
            # "code id_token token"
        ],
        "subject_types_supported": [
            "public"
        ],
        "token_endpoint_auth_methods_supported": [
            # TODO is supporting both a good idea? --mh
            "client_secret_post",
            "client_secret_basic"
        ],
    })

事实证明,实现jwks_uri端点并不难,它的工作原理大致如下:


def load_public_keys():
    public_key_path = Path("etc") / "public.pem"
    public_key = JsonWebKey.import_key(public_key_path.read_bytes())
    public_key["use"] = "sig"
    public_key["alg"] = "RS256"    
    return KeySet([public_key])

@bp.route("/oauth/jwks")
def jwks_endpoint():
    return jsonify(load_public_keys().as_dict())

要让 authlib 使用私钥设置密钥 id ( kid),在JWT_CONFIG

JWT_CONFIG = {
    "key": "secret-key",
    "alg": "RS256",
    "iss": "https://sntl-publishing.com",
    "exp": 3600,
}
private_key_path = Path('etc') / 'private.pem'
private_key = JsonWebKey.import_key(private_key_path.read_text())
JWT_CONFIG['key'] = KeySet([private_key]).as_dict()

它似乎在 repo 的主版本中已修复,但在当前发布的版本中,您需要as_dict()调用KeySet- 否则kid不是生成的 id 令牌的一部分,客户端将无法使用来自的信息验证它jwks_uri端点。

于 2021-08-10T16:03:15.850 回答