We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
OCI Registry Blueprint port ignored
**Describe the bug**
When I try to load blueprints from a registry running on a custom port (e.g. port 5050) the connection fails.

**To Reproduce**
Steps to reproduce the behavior:

1. Go to `Costomization > Blueprints`
2. Create a new `OCI Registry` Blueprint with a non default Port
3. Example `oci://larsl.dev:5050/larsl-net/authentik-config/blueprints/larsl-stages-base:latest`
4. A connection error occurs

**Expected behavior**
authentik connects on the port specified in the URL (5050). What happens according to the error message is that authentik uses port 443.

**Logs**
```
HTTPSConnectionPool(host='larsl.dev', port=443): Max retries exceeded with url: /v2/larsl-net/authentik-config/blueprints/larsl-stages-base/manifests/latest (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f2e26efa690>: Failed to establish a new connection: [Errno 111] Connection refused'))
```

**Version and Deployment (please complete the following information):**

-   authentik version: 2023.5.1
-   Deployment: docker-compose


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `authentik/blueprints/v1/oci.py`
Content:
```
1 """OCI Client"""
2 from typing import Any
3 from urllib.parse import ParseResult, urlparse
4 
5 from opencontainers.distribution.reggie import (
6     NewClient,
7     WithDebug,
8     WithDefaultName,
9     WithDigest,
10     WithReference,
11     WithUserAgent,
12     WithUsernamePassword,
13 )
14 from requests.exceptions import RequestException
15 from structlog import get_logger
16 from structlog.stdlib import BoundLogger
17 
18 from authentik.lib.sentry import SentryIgnoredException
19 from authentik.lib.utils.http import authentik_user_agent
20 
21 OCI_MEDIA_TYPE = "application/vnd.goauthentik.blueprint.v1+yaml"
22 
23 
24 class OCIException(SentryIgnoredException):
25     """OCI-related errors"""
26 
27 
28 class BlueprintOCIClient:
29     """Blueprint OCI Client"""
30 
31     url: ParseResult
32     sanitized_url: str
33     logger: BoundLogger
34     ref: str
35     client: NewClient
36 
37     def __init__(self, url: str) -> None:
38         self._parse_url(url)
39         self.logger = get_logger().bind(url=self.sanitized_url)
40 
41         self.ref = "latest"
42         path = self.url.path[1:]
43         if ":" in self.url.path:
44             path, _, self.ref = path.partition(":")
45         self.client = NewClient(
46             f"https://{self.url.hostname}",
47             WithUserAgent(authentik_user_agent()),
48             WithUsernamePassword(self.url.username, self.url.password),
49             WithDefaultName(path),
50             WithDebug(True),
51         )
52 
53     def _parse_url(self, url: str):
54         self.url = urlparse(url)
55         netloc = self.url.netloc
56         if "@" in netloc:
57             netloc = netloc[netloc.index("@") + 1 :]
58         self.sanitized_url = self.url._replace(netloc=netloc).geturl()
59 
60     def fetch_manifests(self) -> dict[str, Any]:
61         """Fetch manifests for ref"""
62         self.logger.info("Fetching OCI manifests for blueprint")
63         manifest_request = self.client.NewRequest(
64             "GET",
65             "/v2/<name>/manifests/<reference>",
66             WithReference(self.ref),
67         ).SetHeader("Accept", "application/vnd.oci.image.manifest.v1+json")
68         try:
69             manifest_response = self.client.Do(manifest_request)
70             manifest_response.raise_for_status()
71         except RequestException as exc:
72             raise OCIException(exc) from exc
73         manifest = manifest_response.json()
74         if "errors" in manifest:
75             raise OCIException(manifest["errors"])
76         return manifest
77 
78     def fetch_blobs(self, manifest: dict[str, Any]):
79         """Fetch blob based on manifest info"""
80         blob = None
81         for layer in manifest.get("layers", []):
82             if layer.get("mediaType", "") == OCI_MEDIA_TYPE:
83                 blob = layer.get("digest")
84                 self.logger.debug("Found layer with matching media type", blob=blob)
85         if not blob:
86             raise OCIException("Blob not found")
87 
88         blob_request = self.client.NewRequest(
89             "GET",
90             "/v2/<name>/blobs/<digest>",
91             WithDigest(blob),
92         )
93         try:
94             blob_response = self.client.Do(blob_request)
95             blob_response.raise_for_status()
96             return blob_response.text
97         except RequestException as exc:
98             raise OCIException(exc) from exc
99
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/authentik/blueprints/v1/oci.py b/authentik/blueprints/v1/oci.py
--- a/authentik/blueprints/v1/oci.py
+++ b/authentik/blueprints/v1/oci.py
@@ -39,11 +39,16 @@
         self.logger = get_logger().bind(url=self.sanitized_url)
 
         self.ref = "latest"
+        # Remove the leading slash of the path to convert it to an image name
         path = self.url.path[1:]
-        if ":" in self.url.path:
+        if ":" in path:
+            # if there's a colon in the path, use everything after it as a ref
             path, _, self.ref = path.partition(":")
+        base_url = f"https://{self.url.hostname}"
+        if self.url.port:
+            base_url += f":{self.url.port}"
         self.client = NewClient(
-            f"https://{self.url.hostname}",
+            base_url,
             WithUserAgent(authentik_user_agent()),
             WithUsernamePassword(self.url.username, self.url.password),
             WithDefaultName(path),

{"golden_diff": "diff --git a/authentik/blueprints/v1/oci.py b/authentik/blueprints/v1/oci.py\n--- a/authentik/blueprints/v1/oci.py\n+++ b/authentik/blueprints/v1/oci.py\n@@ -39,11 +39,16 @@\n         self.logger = get_logger().bind(url=self.sanitized_url)\n \n         self.ref = \"latest\"\n+        # Remove the leading slash of the path to convert it to an image name\n         path = self.url.path[1:]\n-        if \":\" in self.url.path:\n+        if \":\" in path:\n+            # if there's a colon in the path, use everything after it as a ref\n             path, _, self.ref = path.partition(\":\")\n+        base_url = f\"https://{self.url.hostname}\"\n+        if self.url.port:\n+            base_url += f\":{self.url.port}\"\n         self.client = NewClient(\n-            f\"https://{self.url.hostname}\",\n+            base_url,\n             WithUserAgent(authentik_user_agent()),\n             WithUsernamePassword(self.url.username, self.url.password),\n             WithDefaultName(path),\n", "issue": "OCI Registry Blueprint port ignored\n**Describe the bug**\r\nWhen I try to load blueprints from a registry running on a custom port (e.g. port 5050) the connection fails.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n\r\n1. Go to `Costomization > Blueprints`\r\n2. Create a new `OCI Registry` Blueprint with a non default Port\r\n3. Example `oci://larsl.dev:5050/larsl-net/authentik-config/blueprints/larsl-stages-base:latest`\r\n4. A connection error occurs\r\n\r\n**Expected behavior**\r\nauthentik connects on the port specified in the URL (5050). What happens according to the error message is that authentik uses port 443.\r\n\r\n**Logs**\r\n```\r\nHTTPSConnectionPool(host='larsl.dev', port=443): Max retries exceeded with url: /v2/larsl-net/authentik-config/blueprints/larsl-stages-base/manifests/latest (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f2e26efa690>: Failed to establish a new connection: [Errno 111] Connection refused'))\r\n```\r\n\r\n**Version and Deployment (please complete the following information):**\r\n\r\n-   authentik version: 2023.5.1\r\n-   Deployment: docker-compose\r\n\n", "before_files": [{"content": "\"\"\"OCI Client\"\"\"\nfrom typing import Any\nfrom urllib.parse import ParseResult, urlparse\n\nfrom opencontainers.distribution.reggie import (\n    NewClient,\n    WithDebug,\n    WithDefaultName,\n    WithDigest,\n    WithReference,\n    WithUserAgent,\n    WithUsernamePassword,\n)\nfrom requests.exceptions import RequestException\nfrom structlog import get_logger\nfrom structlog.stdlib import BoundLogger\n\nfrom authentik.lib.sentry import SentryIgnoredException\nfrom authentik.lib.utils.http import authentik_user_agent\n\nOCI_MEDIA_TYPE = \"application/vnd.goauthentik.blueprint.v1+yaml\"\n\n\nclass OCIException(SentryIgnoredException):\n    \"\"\"OCI-related errors\"\"\"\n\n\nclass BlueprintOCIClient:\n    \"\"\"Blueprint OCI Client\"\"\"\n\n    url: ParseResult\n    sanitized_url: str\n    logger: BoundLogger\n    ref: str\n    client: NewClient\n\n    def __init__(self, url: str) -> None:\n        self._parse_url(url)\n        self.logger = get_logger().bind(url=self.sanitized_url)\n\n        self.ref = \"latest\"\n        path = self.url.path[1:]\n        if \":\" in self.url.path:\n            path, _, self.ref = path.partition(\":\")\n        self.client = NewClient(\n            f\"https://{self.url.hostname}\",\n            WithUserAgent(authentik_user_agent()),\n            WithUsernamePassword(self.url.username, self.url.password),\n            WithDefaultName(path),\n            WithDebug(True),\n        )\n\n    def _parse_url(self, url: str):\n        self.url = urlparse(url)\n        netloc = self.url.netloc\n        if \"@\" in netloc:\n            netloc = netloc[netloc.index(\"@\") + 1 :]\n        self.sanitized_url = self.url._replace(netloc=netloc).geturl()\n\n    def fetch_manifests(self) -> dict[str, Any]:\n        \"\"\"Fetch manifests for ref\"\"\"\n        self.logger.info(\"Fetching OCI manifests for blueprint\")\n        manifest_request = self.client.NewRequest(\n            \"GET\",\n            \"/v2/<name>/manifests/<reference>\",\n            WithReference(self.ref),\n        ).SetHeader(\"Accept\", \"application/vnd.oci.image.manifest.v1+json\")\n        try:\n            manifest_response = self.client.Do(manifest_request)\n            manifest_response.raise_for_status()\n        except RequestException as exc:\n            raise OCIException(exc) from exc\n        manifest = manifest_response.json()\n        if \"errors\" in manifest:\n            raise OCIException(manifest[\"errors\"])\n        return manifest\n\n    def fetch_blobs(self, manifest: dict[str, Any]):\n        \"\"\"Fetch blob based on manifest info\"\"\"\n        blob = None\n        for layer in manifest.get(\"layers\", []):\n            if layer.get(\"mediaType\", \"\") == OCI_MEDIA_TYPE:\n                blob = layer.get(\"digest\")\n                self.logger.debug(\"Found layer with matching media type\", blob=blob)\n        if not blob:\n            raise OCIException(\"Blob not found\")\n\n        blob_request = self.client.NewRequest(\n            \"GET\",\n            \"/v2/<name>/blobs/<digest>\",\n            WithDigest(blob),\n        )\n        try:\n            blob_response = self.client.Do(blob_request)\n            blob_response.raise_for_status()\n            return blob_response.text\n        except RequestException as exc:\n            raise OCIException(exc) from exc\n", "path": "authentik/blueprints/v1/oci.py"}], "after_files": [{"content": "\"\"\"OCI Client\"\"\"\nfrom typing import Any\nfrom urllib.parse import ParseResult, urlparse\n\nfrom opencontainers.distribution.reggie import (\n    NewClient,\n    WithDebug,\n    WithDefaultName,\n    WithDigest,\n    WithReference,\n    WithUserAgent,\n    WithUsernamePassword,\n)\nfrom requests.exceptions import RequestException\nfrom structlog import get_logger\nfrom structlog.stdlib import BoundLogger\n\nfrom authentik.lib.sentry import SentryIgnoredException\nfrom authentik.lib.utils.http import authentik_user_agent\n\nOCI_MEDIA_TYPE = \"application/vnd.goauthentik.blueprint.v1+yaml\"\n\n\nclass OCIException(SentryIgnoredException):\n    \"\"\"OCI-related errors\"\"\"\n\n\nclass BlueprintOCIClient:\n    \"\"\"Blueprint OCI Client\"\"\"\n\n    url: ParseResult\n    sanitized_url: str\n    logger: BoundLogger\n    ref: str\n    client: NewClient\n\n    def __init__(self, url: str) -> None:\n        self._parse_url(url)\n        self.logger = get_logger().bind(url=self.sanitized_url)\n\n        self.ref = \"latest\"\n        # Remove the leading slash of the path to convert it to an image name\n        path = self.url.path[1:]\n        if \":\" in path:\n            # if there's a colon in the path, use everything after it as a ref\n            path, _, self.ref = path.partition(\":\")\n        base_url = f\"https://{self.url.hostname}\"\n        if self.url.port:\n            base_url += f\":{self.url.port}\"\n        self.client = NewClient(\n            base_url,\n            WithUserAgent(authentik_user_agent()),\n            WithUsernamePassword(self.url.username, self.url.password),\n            WithDefaultName(path),\n            WithDebug(True),\n        )\n\n    def _parse_url(self, url: str):\n        self.url = urlparse(url)\n        netloc = self.url.netloc\n        if \"@\" in netloc:\n            netloc = netloc[netloc.index(\"@\") + 1 :]\n        self.sanitized_url = self.url._replace(netloc=netloc).geturl()\n\n    def fetch_manifests(self) -> dict[str, Any]:\n        \"\"\"Fetch manifests for ref\"\"\"\n        self.logger.info(\"Fetching OCI manifests for blueprint\")\n        manifest_request = self.client.NewRequest(\n            \"GET\",\n            \"/v2/<name>/manifests/<reference>\",\n            WithReference(self.ref),\n        ).SetHeader(\"Accept\", \"application/vnd.oci.image.manifest.v1+json\")\n        try:\n            manifest_response = self.client.Do(manifest_request)\n            manifest_response.raise_for_status()\n        except RequestException as exc:\n            raise OCIException(exc) from exc\n        manifest = manifest_response.json()\n        if \"errors\" in manifest:\n            raise OCIException(manifest[\"errors\"])\n        return manifest\n\n    def fetch_blobs(self, manifest: dict[str, Any]):\n        \"\"\"Fetch blob based on manifest info\"\"\"\n        blob = None\n        for layer in manifest.get(\"layers\", []):\n            if layer.get(\"mediaType\", \"\") == OCI_MEDIA_TYPE:\n                blob = layer.get(\"digest\")\n                self.logger.debug(\"Found layer with matching media type\", blob=blob)\n        if not blob:\n            raise OCIException(\"Blob not found\")\n\n        blob_request = self.client.NewRequest(\n            \"GET\",\n            \"/v2/<name>/blobs/<digest>\",\n            WithDigest(blob),\n        )\n        try:\n            blob_response = self.client.Do(blob_request)\n            blob_response.raise_for_status()\n            return blob_response.text\n        except RequestException as exc:\n            raise OCIException(exc) from exc\n", "path": "authentik/blueprints/v1/oci.py"}]}