# joserfc migration

joserfc is derived from Authlib and provides a cleaner design along with first-class type hints. We strongly recommend using `joserfc` instead of the `authlib.jose` module.

Starting with Authlib 1.7.0, the `authlib.jose` module is deprecated and will emit deprecation warnings. A comprehensive Migrating from Authlib guide is available in the joserfc documentation to help you transition.

The following modules are affected by this upgrade:

- `authlib.oauth2.rfc7523`

- `authlib.oauth2.rfc7591`

- `authlib.oauth2.rfc7592`

- `authlib.oauth2.rfc9068`

- `authlib.oauth2.rfc9101`

- `authlib.oidc.core`

## Breaking Changes

A common breaking change involves the exceptions raised by the affected modules. Since these modules now use `joserfc`, all exceptions are `joserfc`-based. If your code previously caught exceptions from `authlib.jose`, you should update it to catch the corresponding exceptions from `joserfc` instead.

    -from authlib.jose.errors import JoseError
    +from joserfc.errors import JoseError

     try:
         do_something()
     except JoseError:
         pass

### JWTAuthenticationRequest

Starting with v1.7, `authlib.oauth2.rfc9101.JWTAuthenticationRequest` uses only the recommended JWT algorithms by default. If you need to support additional algorithms, you can explicitly include them in `get_server_metadata`:

    class MyJWTAuthenticationRequest(JWTAuthenticationRequest):
        def get_server_metadata(self):
            return {
                ...,
                "request_object_signing_alg_values_supported": ["RS256", ...],
            }

### UserInfoEndpoint

The signing algorithms supported by `authlib.oidc.core.UserInfoEndpoint` are limited to the recommended JWT algorithms. If you need to support additional algorithms, you can explicitly include them in `get_supported_algorithms`:

    class MyUserInfoEndpoint(UserInfoEndpoint):
        def get_supported_algorithms(self):
            return ["RS512"]

## Deprecating Messages

Most deprecation warnings are triggered by how keys are imported. For security reasons, joserfc requires explicit key types. Instead of passing raw strings or bytes as keys, you should return `OctKey`, `RSAKey`, `ECKey`, `OKPKey`, or `KeySet` instances directly.

## `get_jwt_config`

`get_jwt_config` is converted into 3 methods:

1. `resolve_client_private_key`

2. `get_client_claims`

3. `get_client_algorithm`

    # before 1.7
    class OpenIDCode(grants.OpenIDCode):
        def get_jwt_config(self):
            return {
                'key': read_private_key_file(key_path),
                'alg': 'RS512',
                'iss': 'https://example.com',
                'exp': 3600
            }

    # authlib>=1.7
    class OpenIDCode(grants.OpenIDCode):
        def resolve_client_private_key(self, client):
            with open(jwks_file_path) as f:
                data = json.load(f)
            return KeySet.import_key_set(data)

        def get_client_claims(self, client):
            return {
                'iss': 'https://example.com',
            }