sources/oauth: migrate twitter to oauth2 (#2893)
This commit is contained in:
parent
538c2ca4d3
commit
75b0fb3393
|
@ -11,6 +11,7 @@ from structlog.stdlib import get_logger
|
||||||
from authentik.sources.oauth.clients.base import BaseOAuthClient
|
from authentik.sources.oauth.clients.base import BaseOAuthClient
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
SESSION_OAUTH_PKCE = "oauth_pkce"
|
||||||
|
|
||||||
|
|
||||||
class OAuth2Client(BaseOAuthClient):
|
class OAuth2Client(BaseOAuthClient):
|
||||||
|
@ -69,6 +70,8 @@ class OAuth2Client(BaseOAuthClient):
|
||||||
"code": code,
|
"code": code,
|
||||||
"grant_type": "authorization_code",
|
"grant_type": "authorization_code",
|
||||||
}
|
}
|
||||||
|
if SESSION_OAUTH_PKCE in self.request.session:
|
||||||
|
args["code_verifier"] = self.request.session[SESSION_OAUTH_PKCE]
|
||||||
try:
|
try:
|
||||||
access_token_url = self.source.type.access_token_url or ""
|
access_token_url = self.source.type.access_token_url or ""
|
||||||
if self.source.type.urls_customizable and self.source.access_token_url:
|
if self.source.type.urls_customizable and self.source.access_token_url:
|
||||||
|
|
|
@ -4,88 +4,8 @@ from django.test import TestCase
|
||||||
from authentik.sources.oauth.models import OAuthSource
|
from authentik.sources.oauth.models import OAuthSource
|
||||||
from authentik.sources.oauth.types.twitter import TwitterOAuthCallback
|
from authentik.sources.oauth.types.twitter import TwitterOAuthCallback
|
||||||
|
|
||||||
# https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/ \
|
# https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me
|
||||||
# api-reference/get-account-verify_credentials
|
TWITTER_USER = {"data": {"id": "2244994945", "name": "TwitterDev", "username": "Twitter Dev"}}
|
||||||
TWITTER_USER = {
|
|
||||||
"contributors_enabled": True,
|
|
||||||
"created_at": "Sat May 09 17:58:22 +0000 2009",
|
|
||||||
"default_profile": False,
|
|
||||||
"default_profile_image": False,
|
|
||||||
"description": "I taught your phone that thing you like.",
|
|
||||||
"favourites_count": 588,
|
|
||||||
"follow_request_sent": None,
|
|
||||||
"followers_count": 10625,
|
|
||||||
"following": None,
|
|
||||||
"friends_count": 1181,
|
|
||||||
"geo_enabled": True,
|
|
||||||
"id": 38895958,
|
|
||||||
"id_str": "38895958",
|
|
||||||
"is_translator": False,
|
|
||||||
"lang": "en",
|
|
||||||
"listed_count": 190,
|
|
||||||
"location": "San Francisco",
|
|
||||||
"name": "Sean Cook",
|
|
||||||
"notifications": None,
|
|
||||||
"profile_background_color": "1A1B1F",
|
|
||||||
"profile_background_image_url": "",
|
|
||||||
"profile_background_image_url_https": "",
|
|
||||||
"profile_background_tile": True,
|
|
||||||
"profile_image_url": "",
|
|
||||||
"profile_image_url_https": "",
|
|
||||||
"profile_link_color": "2FC2EF",
|
|
||||||
"profile_sidebar_border_color": "181A1E",
|
|
||||||
"profile_sidebar_fill_color": "252429",
|
|
||||||
"profile_text_color": "666666",
|
|
||||||
"profile_use_background_image": True,
|
|
||||||
"protected": False,
|
|
||||||
"screen_name": "theSeanCook",
|
|
||||||
"show_all_inline_media": True,
|
|
||||||
"status": {
|
|
||||||
"contributors": None,
|
|
||||||
"coordinates": {"coordinates": [-122.45037293, 37.76484123], "type": "Point"},
|
|
||||||
"created_at": "Tue Aug 28 05:44:24 +0000 2012",
|
|
||||||
"favorited": False,
|
|
||||||
"geo": {"coordinates": [37.76484123, -122.45037293], "type": "Point"},
|
|
||||||
"id": 240323931419062272,
|
|
||||||
"id_str": "240323931419062272",
|
|
||||||
"in_reply_to_screen_name": "messl",
|
|
||||||
"in_reply_to_status_id": 240316959173009410,
|
|
||||||
"in_reply_to_status_id_str": "240316959173009410",
|
|
||||||
"in_reply_to_user_id": 18707866,
|
|
||||||
"in_reply_to_user_id_str": "18707866",
|
|
||||||
"place": {
|
|
||||||
"attributes": {},
|
|
||||||
"bounding_box": {
|
|
||||||
"coordinates": [
|
|
||||||
[
|
|
||||||
[-122.45778216, 37.75932999],
|
|
||||||
[-122.44248216, 37.75932999],
|
|
||||||
[-122.44248216, 37.76752899],
|
|
||||||
[-122.45778216, 37.76752899],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"type": "Polygon",
|
|
||||||
},
|
|
||||||
"country": "United States",
|
|
||||||
"country_code": "US",
|
|
||||||
"full_name": "Ashbury Heights, San Francisco",
|
|
||||||
"id": "866269c983527d5a",
|
|
||||||
"name": "Ashbury Heights",
|
|
||||||
"place_type": "neighborhood",
|
|
||||||
"url": "http://api.twitter.com/1/geo/id/866269c983527d5a.json",
|
|
||||||
},
|
|
||||||
"retweet_count": 0,
|
|
||||||
"retweeted": False,
|
|
||||||
"source": "Twitter for iPhone",
|
|
||||||
"text": "@messl congrats! So happy for all 3 of you.",
|
|
||||||
"truncated": False,
|
|
||||||
},
|
|
||||||
"statuses_count": 2609,
|
|
||||||
"time_zone": "Pacific Time (US & Canada)",
|
|
||||||
"url": None,
|
|
||||||
"utc_offset": -28800,
|
|
||||||
"verified": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TestTypeGitHub(TestCase):
|
class TestTypeGitHub(TestCase):
|
||||||
|
@ -104,6 +24,6 @@ class TestTypeGitHub(TestCase):
|
||||||
def test_enroll_context(self):
|
def test_enroll_context(self):
|
||||||
"""Test Twitter Enrollment context"""
|
"""Test Twitter Enrollment context"""
|
||||||
ak_context = TwitterOAuthCallback().get_user_enroll_context(TWITTER_USER)
|
ak_context = TwitterOAuthCallback().get_user_enroll_context(TWITTER_USER)
|
||||||
self.assertEqual(ak_context["username"], TWITTER_USER["screen_name"])
|
self.assertEqual(ak_context["username"], TWITTER_USER["data"]["username"])
|
||||||
self.assertEqual(ak_context["email"], TWITTER_USER.get("email", None))
|
self.assertEqual(ak_context["email"], None)
|
||||||
self.assertEqual(ak_context["name"], TWITTER_USER["name"])
|
self.assertEqual(ak_context["name"], TWITTER_USER["data"]["name"])
|
||||||
|
|
|
@ -1,21 +1,46 @@
|
||||||
"""Twitter OAuth Views"""
|
"""Twitter OAuth Views"""
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from authentik.lib.generators import generate_id
|
||||||
|
from authentik.sources.oauth.clients.oauth2 import SESSION_OAUTH_PKCE
|
||||||
|
from authentik.sources.oauth.types.azure_ad import AzureADClient
|
||||||
from authentik.sources.oauth.types.manager import MANAGER, SourceType
|
from authentik.sources.oauth.types.manager import MANAGER, SourceType
|
||||||
from authentik.sources.oauth.views.callback import OAuthCallback
|
from authentik.sources.oauth.views.callback import OAuthCallback
|
||||||
|
from authentik.sources.oauth.views.redirect import OAuthRedirect
|
||||||
|
|
||||||
|
|
||||||
|
class TwitterOAuthRedirect(OAuthRedirect):
|
||||||
|
"""Twitter OAuth2 Redirect"""
|
||||||
|
|
||||||
|
def get_additional_parameters(self, source): # pragma: no cover
|
||||||
|
self.request.session[SESSION_OAUTH_PKCE] = generate_id()
|
||||||
|
return {
|
||||||
|
"scope": ["users.read", "tweet.read"],
|
||||||
|
"code_challenge": self.request.session[SESSION_OAUTH_PKCE],
|
||||||
|
"code_challenge_method": "plain",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TwitterOAuthCallback(OAuthCallback):
|
class TwitterOAuthCallback(OAuthCallback):
|
||||||
"""Twitter OAuth2 Callback"""
|
"""Twitter OAuth2 Callback"""
|
||||||
|
|
||||||
|
# Twitter has the same quirk as azure and throws an error if the access token
|
||||||
|
# is set via query parameter, so we re-use the azure client
|
||||||
|
# see https://github.com/goauthentik/authentik/issues/1910
|
||||||
|
client_class = AzureADClient
|
||||||
|
|
||||||
|
def get_user_id(self, info: dict[str, str]) -> str:
|
||||||
|
return info.get("data", {}).get("id", "")
|
||||||
|
|
||||||
def get_user_enroll_context(
|
def get_user_enroll_context(
|
||||||
self,
|
self,
|
||||||
info: dict[str, Any],
|
info: dict[str, Any],
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
|
data = info.get("data", {})
|
||||||
return {
|
return {
|
||||||
"username": info.get("screen_name"),
|
"username": data.get("username"),
|
||||||
"email": info.get("email", None),
|
"email": None,
|
||||||
"name": info.get("name"),
|
"name": data.get("name"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,10 +49,10 @@ class TwitterType(SourceType):
|
||||||
"""Twitter Type definition"""
|
"""Twitter Type definition"""
|
||||||
|
|
||||||
callback_view = TwitterOAuthCallback
|
callback_view = TwitterOAuthCallback
|
||||||
|
redirect_view = TwitterOAuthRedirect
|
||||||
name = "Twitter"
|
name = "Twitter"
|
||||||
slug = "twitter"
|
slug = "twitter"
|
||||||
|
|
||||||
request_token_url = "https://api.twitter.com/oauth/request_token" # nosec
|
authorization_url = "https://twitter.com/i/oauth2/authorize"
|
||||||
authorization_url = "https://api.twitter.com/oauth/authenticate"
|
access_token_url = "https://api.twitter.com/2/oauth2/token" # nosec
|
||||||
access_token_url = "https://api.twitter.com/oauth/access_token" # nosec
|
profile_url = "https://api.twitter.com/2/users/me"
|
||||||
profile_url = "https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true"
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ from sys import platform
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
from unittest.case import skipUnless
|
from unittest.case import skipUnless
|
||||||
from unittest.mock import Mock, patch
|
|
||||||
|
|
||||||
from docker.models.containers import Container
|
from docker.models.containers import Container
|
||||||
from docker.types import Healthcheck
|
from docker.types import Healthcheck
|
||||||
|
@ -18,20 +17,38 @@ from authentik.core.models import User
|
||||||
from authentik.flows.models import Flow
|
from authentik.flows.models import Flow
|
||||||
from authentik.lib.generators import generate_id, generate_key
|
from authentik.lib.generators import generate_id, generate_key
|
||||||
from authentik.sources.oauth.models import OAuthSource
|
from authentik.sources.oauth.models import OAuthSource
|
||||||
from authentik.sources.oauth.types.manager import SourceType
|
from authentik.sources.oauth.types.manager import MANAGER, SourceType
|
||||||
from authentik.sources.oauth.types.twitter import TwitterOAuthCallback
|
from authentik.sources.oauth.views.callback import OAuthCallback
|
||||||
from authentik.stages.identification.models import IdentificationStage
|
from authentik.stages.identification.models import IdentificationStage
|
||||||
from tests.e2e.utils import SeleniumTestCase, apply_migration, object_manager, retry
|
from tests.e2e.utils import SeleniumTestCase, apply_migration, object_manager, retry
|
||||||
|
|
||||||
CONFIG_PATH = "/tmp/dex.yml" # nosec
|
CONFIG_PATH = "/tmp/dex.yml" # nosec
|
||||||
|
|
||||||
|
|
||||||
class OAUth1Type(SourceType):
|
class OAUth1Callback(OAuthCallback):
|
||||||
"""Twitter Type definition"""
|
"""OAuth1 Callback with custom getters"""
|
||||||
|
|
||||||
callback_view = TwitterOAuthCallback
|
def get_user_id(self, info: dict[str, str]) -> str:
|
||||||
name = "Twitter"
|
return info.get("id")
|
||||||
slug = "twitter"
|
|
||||||
|
def get_user_enroll_context(
|
||||||
|
self,
|
||||||
|
info: dict[str, Any],
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"username": info.get("screen_name"),
|
||||||
|
"email": info.get("email"),
|
||||||
|
"name": info.get("name"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@MANAGER.type()
|
||||||
|
class OAUth1Type(SourceType):
|
||||||
|
"""OAuth1 Type definition"""
|
||||||
|
|
||||||
|
callback_view = OAUth1Callback
|
||||||
|
name = "OAuth1"
|
||||||
|
slug = "oauth1"
|
||||||
|
|
||||||
request_token_url = "http://localhost:5000/oauth/request_token" # nosec
|
request_token_url = "http://localhost:5000/oauth/request_token" # nosec
|
||||||
access_token_url = "http://localhost:5000/oauth/access_token" # nosec
|
access_token_url = "http://localhost:5000/oauth/access_token" # nosec
|
||||||
|
@ -40,9 +57,6 @@ class OAUth1Type(SourceType):
|
||||||
urls_customizable = False
|
urls_customizable = False
|
||||||
|
|
||||||
|
|
||||||
SOURCE_TYPE_MOCK = Mock(return_value=OAUth1Type)
|
|
||||||
|
|
||||||
|
|
||||||
@skipUnless(platform.startswith("linux"), "requires local docker")
|
@skipUnless(platform.startswith("linux"), "requires local docker")
|
||||||
class TestSourceOAuth2(SeleniumTestCase):
|
class TestSourceOAuth2(SeleniumTestCase):
|
||||||
"""test OAuth Source flow"""
|
"""test OAuth Source flow"""
|
||||||
|
@ -256,7 +270,7 @@ class TestSourceOAuth1(SeleniumTestCase):
|
||||||
slug=self.source_slug,
|
slug=self.source_slug,
|
||||||
authentication_flow=authentication_flow,
|
authentication_flow=authentication_flow,
|
||||||
enrollment_flow=enrollment_flow,
|
enrollment_flow=enrollment_flow,
|
||||||
provider_type="twitter",
|
provider_type="oauth1",
|
||||||
consumer_key=self.client_id,
|
consumer_key=self.client_id,
|
||||||
consumer_secret=self.client_secret,
|
consumer_secret=self.client_secret,
|
||||||
)
|
)
|
||||||
|
@ -269,10 +283,6 @@ class TestSourceOAuth1(SeleniumTestCase):
|
||||||
@apply_migration("authentik_flows", "0011_flow_title")
|
@apply_migration("authentik_flows", "0011_flow_title")
|
||||||
@apply_migration("authentik_flows", "0009_source_flows")
|
@apply_migration("authentik_flows", "0009_source_flows")
|
||||||
@apply_migration("authentik_crypto", "0002_create_self_signed_kp")
|
@apply_migration("authentik_crypto", "0002_create_self_signed_kp")
|
||||||
@patch(
|
|
||||||
"authentik.sources.oauth.types.manager.SourceTypeManager.find_type",
|
|
||||||
SOURCE_TYPE_MOCK,
|
|
||||||
)
|
|
||||||
@object_manager
|
@object_manager
|
||||||
def test_oauth_enroll(self):
|
def test_oauth_enroll(self):
|
||||||
"""test OAuth Source With With OIDC"""
|
"""test OAuth Source With With OIDC"""
|
||||||
|
|
|
@ -30,7 +30,7 @@ from authentik.core.models import User
|
||||||
from authentik.core.tests.utils import create_test_admin_user
|
from authentik.core.tests.utils import create_test_admin_user
|
||||||
from authentik.managed.manager import ObjectManager
|
from authentik.managed.manager import ObjectManager
|
||||||
|
|
||||||
RETRIES = int(environ.get("RETRIES", "5"))
|
RETRIES = int(environ.get("RETRIES", "3"))
|
||||||
|
|
||||||
|
|
||||||
def get_docker_tag() -> str:
|
def get_docker_tag() -> str:
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,6 +5,10 @@ slug: "2022.5"
|
||||||
|
|
||||||
## Breaking changes
|
## Breaking changes
|
||||||
|
|
||||||
|
- Twitter Source has been migrated to OAuth2
|
||||||
|
|
||||||
|
This requires some reconfiguration on both Twitter's and authentik's side. Check out the new Twitter integration docs [here](../../integrations/sources/twitter/)
|
||||||
|
|
||||||
## New features
|
## New features
|
||||||
|
|
||||||
- LDAP Outpost cached binding
|
- LDAP Outpost cached binding
|
||||||
|
|
|
@ -50,7 +50,7 @@ The following placeholders will be used:
|
||||||
|
|
||||||
## authentik
|
## authentik
|
||||||
|
|
||||||
20. Under _Resources -> Sources_ Click **Create Apple OAuth Source**
|
20. Under _Directory -> Federation & Social login_ Click **Create Apple OAuth Source**
|
||||||
|
|
||||||
21. **Name**: `Apple`
|
21. **Name**: `Apple`
|
||||||
22. **Slug**: `apple`
|
22. **Slug**: `apple`
|
||||||
|
|
|
@ -30,21 +30,20 @@ The following placeholders will be used:
|
||||||
|
|
||||||
Here is an example of a completed OAuth2 screen for Discord.
|
Here is an example of a completed OAuth2 screen for Discord.
|
||||||
|
|
||||||
![Example Screen](discord4.png)
|
![](discord4.png)
|
||||||
|
|
||||||
## authentik
|
## authentik
|
||||||
|
|
||||||
8. Under _Resources -> Sources_ Click **Create Discord OAuth Source**
|
8. Under _Directory -> Federation & Social login_ Click **Create Discord OAuth Source**
|
||||||
|
|
||||||
9. **Name:** Choose a name (For the example I used Discord)
|
9. **Name:** Choose a name (For the example I used Discord)
|
||||||
10. **Slug:** discord (You can choose a different slug, if you do you will need to update the Discord redirect URLand point it to the correct slug.)
|
10. **Slug:** discord (You can choose a different slug, if you do you will need to update the Discord redirect URLand point it to the correct slug.)
|
||||||
11. **Consumer Key:** Client ID from step 4
|
11. **Consumer Key:** Client ID from step 4
|
||||||
12. **Consumer Secret:** Client Secret from step 5
|
12. **Consumer Secret:** Client Secret from step 5
|
||||||
13. **Provider type:** Discord
|
|
||||||
|
|
||||||
Here is an example of a complete authentik Discord OAuth Source
|
Here is an example of a complete authentik Discord OAuth Source
|
||||||
|
|
||||||
![Example Screen](discord5.png)
|
![](discord5.png)
|
||||||
|
|
||||||
Save, and you now have Discord as a source.
|
Save, and you now have Discord as a source.
|
||||||
|
|
||||||
|
|
|
@ -24,24 +24,23 @@ The following placeholders will be used:
|
||||||
|
|
||||||
Example screenshot
|
Example screenshot
|
||||||
|
|
||||||
![Example Screen](githubdeveloperexample.png)
|
![](githubdeveloperexample.png)
|
||||||
|
|
||||||
6. Copy the **Client ID** and _save it for later_
|
6. Copy the **Client ID** and _save it for later_
|
||||||
7. Click **Generate a new client secret** and _save it for later_ You will not be able to see the secret again, so be sure to copy it now.
|
7. Click **Generate a new client secret** and _save it for later_ You will not be able to see the secret again, so be sure to copy it now.
|
||||||
|
|
||||||
## authentik
|
## authentik
|
||||||
|
|
||||||
8. Under _Resources -> Sources_ Click **Create Github OAuth Source**
|
8. Under _Directory -> Federation & Social login_ Click **Create Github OAuth Source**
|
||||||
|
|
||||||
9. **Name**: Choose a name (For the example I use Github)
|
9. **Name**: Choose a name (For the example I use Github)
|
||||||
10. **Slug**: github (If you choose a different slug the URLs will need to be updated to reflect the change)
|
10. **Slug**: github (If you choose a different slug the URLs will need to be updated to reflect the change)
|
||||||
11. **Consumer Key:** Client ID from step 6
|
11. **Consumer Key:** Client ID from step 6
|
||||||
12. **Consumer Secret:** Client Secret from step 7
|
12. **Consumer Secret:** Client Secret from step 7
|
||||||
13. **Provider Type:** Github
|
|
||||||
|
|
||||||
Here is an example of a complete authentik Github OAuth Source
|
Here is an example of a complete authentik Github OAuth Source
|
||||||
|
|
||||||
![Example Screen](githubexample2.png)
|
![](githubexample2.png)
|
||||||
|
|
||||||
Save, and you now have Github as a source.
|
Save, and you now have Github as a source.
|
||||||
|
|
||||||
|
|
|
@ -17,23 +17,23 @@ You will need to create a new project, and OAuth credentials in the Google Devel
|
||||||
1. Visit https://console.developers.google.com/ to create a new project
|
1. Visit https://console.developers.google.com/ to create a new project
|
||||||
2. Create a New project.
|
2. Create a New project.
|
||||||
|
|
||||||
![Example Screen](googledeveloper1.png)
|
![](googledeveloper1.png)
|
||||||
|
|
||||||
3. **Project Name**: Choose a name
|
3. **Project Name**: Choose a name
|
||||||
4. **Organization**: Leave as default if unsure
|
4. **Organization**: Leave as default if unsure
|
||||||
5. **Location**: Leave as default if unsure
|
5. **Location**: Leave as default if unsure
|
||||||
|
|
||||||
![Example Screen](googledeveloper2.png)
|
![](googledeveloper2.png)
|
||||||
|
|
||||||
6. Click **Create**
|
6. Click **Create**
|
||||||
7. Choose your project from the drop down at the top
|
7. Choose your project from the drop down at the top
|
||||||
8. Click the **Credentials** menu item on the left. It looks like a key.
|
8. Click the **Credentials** menu item on the left. It looks like a key.
|
||||||
|
|
||||||
![Example Screen](googledeveloper3.png)
|
![](googledeveloper3.png)
|
||||||
|
|
||||||
9. Click on **Configure Consent Screen**
|
9. Click on **Configure Consent Screen**
|
||||||
|
|
||||||
![Example Screen](googledeveloper4.png)
|
![](googledeveloper4.png)
|
||||||
|
|
||||||
10. **User Type:** If you do not have a Google Workspace (GSuite) account choose _External_. If you do have a Google Workspace (Gsuite) account and want to limit access to only users inside of your organization choose _Internal_
|
10. **User Type:** If you do not have a Google Workspace (GSuite) account choose _External_. If you do have a Google Workspace (Gsuite) account and want to limit access to only users inside of your organization choose _Internal_
|
||||||
|
|
||||||
|
@ -50,30 +50,29 @@ _I'm only going to list the mandatory/important fields to complete._
|
||||||
19. Click **Create Credentials** on the top of the screen
|
19. Click **Create Credentials** on the top of the screen
|
||||||
20. Choose **OAuth Client ID**
|
20. Choose **OAuth Client ID**
|
||||||
|
|
||||||
![Example Screen](googledeveloper5.png)
|
![](googledeveloper5.png)
|
||||||
|
|
||||||
21. **Application Type:** Web Application
|
21. **Application Type:** Web Application
|
||||||
22. **Name:** Choose a name
|
22. **Name:** Choose a name
|
||||||
23. **Authorized redirect URIs:** `https://authenik.company/source/oauth/callback/google/`
|
23. **Authorized redirect URIs:** `https://authenik.company/source/oauth/callback/google/`
|
||||||
|
|
||||||
![Example Screen](googledeveloper6.png)
|
![](googledeveloper6.png)
|
||||||
|
|
||||||
24. Click **Create**
|
24. Click **Create**
|
||||||
25. Copy and store _Your Client ID_ and _Your Client Secret_ for later
|
25. Copy and store _Your Client ID_ and _Your Client Secret_ for later
|
||||||
|
|
||||||
## authentik
|
## authentik
|
||||||
|
|
||||||
26. Under _Resources -> Sources_ Click **Create Google OAuth Source**
|
26. Under _Directory -> Federation & Social login_ Click **Create Google OAuth Source**
|
||||||
|
|
||||||
27. **Name**: Choose a name (For the example I use Google)
|
27. **Name**: Choose a name (For the example I use Google)
|
||||||
28. **Slug**: google (If you choose a different slug the URLs will need to be updated to reflect the change)
|
28. **Slug**: google (If you choose a different slug the URLs will need to be updated to reflect the change)
|
||||||
29. **Consumer Key:** Your Client ID from step 25
|
29. **Consumer Key:** Your Client ID from step 25
|
||||||
30. **Consumer Secret:** Your Client Secret from step 25
|
30. **Consumer Secret:** Your Client Secret from step 25
|
||||||
31. **Provider Type:** Google
|
|
||||||
|
|
||||||
Here is an example of a complete authentik Google OAuth Source
|
Here is an example of a complete authentik Google OAuth Source
|
||||||
|
|
||||||
![Example Screen](authentiksource.png)
|
![](authentiksource.png)
|
||||||
|
|
||||||
Save, and you now have Google as a source.
|
Save, and you now have Google as a source.
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ The following placeholders will be used:
|
||||||
|
|
||||||
Here is an example of a complete authentik Mailcow OAuth Source
|
Here is an example of a complete authentik Mailcow OAuth Source
|
||||||
|
|
||||||
![Example Screen](mailcow5.png)
|
![](mailcow5.png)
|
||||||
|
|
||||||
Save, and you now have Mailcow as a source.
|
Save, and you now have Mailcow as a source.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
title: Twitter
|
||||||
|
---
|
||||||
|
|
||||||
|
Allows users to authenticate using their twitter credentials
|
||||||
|
|
||||||
|
## Preparation
|
||||||
|
|
||||||
|
The following placeholders will be used:
|
||||||
|
|
||||||
|
- `authentik.company` is the FQDN of the authentik install.
|
||||||
|
|
||||||
|
## Twitter
|
||||||
|
|
||||||
|
You will need to create a new project, and OAuth credentials in the Twitter Developer console.
|
||||||
|
|
||||||
|
1. Visit https://developer.twitter.com/ to create a new App
|
||||||
|
2. Select an environment fitting to your use-case
|
||||||
|
3. Give the app a name, for example _authentik_
|
||||||
|
4. Finish setting up the app by clicking **App settings**. Any of the API keys on this screen are not used by authentik.
|
||||||
|
5. Click the **Set up** button
|
||||||
|
|
||||||
|
![](./twitter1.png)
|
||||||
|
|
||||||
|
6. Enable **OAuth 2.0**
|
||||||
|
7. Set **Type of App** to _Web_
|
||||||
|
8. Set **Callback URI / Redirect URL** to `https://authenik.company/source/oauth/callback/twitter/`
|
||||||
|
9. Set **Website URL** to `https://authentik.company`
|
||||||
|
|
||||||
|
![](./twitter2.png)
|
||||||
|
|
||||||
|
10. Confirm with **Save**
|
||||||
|
11. Copy and store **Client ID** and **Client Secret** for later
|
||||||
|
|
||||||
|
## authentik
|
||||||
|
|
||||||
|
1. Under _Directory -> Federation & Social login_ Click **Create Twitter OAuth Source**
|
||||||
|
|
||||||
|
2. **Name**: Choose a name (For the example I use Google)
|
||||||
|
3. **Slug**: twitter (If you choose a different slug the URLs will need to be updated to reflect the change)
|
||||||
|
4. **Consumer Key:** Your Client ID from step 25
|
||||||
|
5. **Consumer Secret:** Your Client Secret from step 25
|
||||||
|
|
||||||
|
:::note
|
||||||
|
For more details on how-to have the new source display on the Login Page see [here](../).
|
||||||
|
:::
|
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
|
@ -37,8 +37,8 @@ module.exports = {
|
||||||
"services/rocketchat/index",
|
"services/rocketchat/index",
|
||||||
"services/roundcube/index",
|
"services/roundcube/index",
|
||||||
"services/sentry/index",
|
"services/sentry/index",
|
||||||
"services/sssd/index",
|
|
||||||
"services/sonarr/index",
|
"services/sonarr/index",
|
||||||
|
"services/sssd/index",
|
||||||
"services/tautulli/index",
|
"services/tautulli/index",
|
||||||
"services/ubuntu-landscape/index",
|
"services/ubuntu-landscape/index",
|
||||||
"services/uptime-kuma/index",
|
"services/uptime-kuma/index",
|
||||||
|
@ -70,6 +70,7 @@ module.exports = {
|
||||||
"sources/oauth/index",
|
"sources/oauth/index",
|
||||||
"sources/plex/index",
|
"sources/plex/index",
|
||||||
"sources/saml/index",
|
"sources/saml/index",
|
||||||
|
"sources/twitter/index",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Reference in New Issue