DjangoのSECRET_KEYをGitの管理対象外にする

 
カテゴリー Python   タグ

DjangoのSECRET_KEY

A secret key for a particular Django installation. This is used to provide cryptographic signing, and should be set to a unique, unpredictable value.

django-admin startproject automatically adds a randomly-generated SECRET_KEY to each new project.

SECRET_KEYは暗号署名のために一意で予測不能な値にする必要がある。
django-admin startprojectで自動的にsetting.pySECRET_KEYにランダムな値が追加される。

The secret key is used for:

  • All sessions if you are using any other session backend than django.contrib.sessions.backends.cache, or are using the default get_session_auth_hash().
  • All messages if you are using CookieStorage or FallbackStorage.
  • All PasswordResetView tokens.
  • Any usage of cryptographic signing, unless a different key is provided.

If you rotate your secret key, all of the above will be invalidated. Secret keys are not used for passwords of users and key rotation will not affect them.

  • Sessions
    • django.contrib.sessions.backends.cache以外のセッションバックエンドを使用する場合
    • get_session_auth_hash()を使用する場合
  • messages
    • CookieStorageかFallbackStorageを使用する場合
  • PasswordResetView Tokens
  • Cryptographic signing
    • 異なる鍵が提供されない場合

setting.pyからSECRET_KEYの値を外だしする

GitリポジトリにSECRET_KEYをPushしないように、setting.pyに埋め込まれたSECRET_KEYを環境変数にして管理する。

1
2
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ['SECRET_KEY']

.envファイルで環境変数を管理している場合は以下のように設定。

1
SECRET_KEY=e=+g9j8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@k8wj0&

コメント・シェア

Django REST framework

 
カテゴリー Python   タグ

django REST framework

  • The Web browsable API is a huge usability win for your developers.
  • Authentication policies including packages for OAuth1a and OAuth2.
  • Serialization that supports both ORM and non-ORM data sources.
  • Customizable all the way down - just use regular function-based views if you don’t need the more powerful features.
  • Extensive documentation, and great community support.
  • Used and trusted by internationally recognised companies including Mozilla, Red Hat, Heroku, and Eventbrite.
  • Webブラウジング可能なAPIによるユーザビリティ
  • OAuth1aとOuth2のための認証ポリシーを含む
  • ORMとnon-ORMの各データソースのシリアライズをサポート
  • 端から端までカスタマイズ可能
  • 広範囲のドキュメントとコミュニティサポート
  • さまざまな国際的企業で利用されている

Django REST framework width=640

BLACK LIVES MATTERやってる(2020/6/18)

Requirements

REST framework requires the following:

Python (3.5, 3.6, 3.7, 3.8)
Django (1.11, 2.0, 2.1, 2.2, 3.0)
We highly recommend and only officially support the latest patch release of each Python and Django series.

The following packages are optional:

coreapi (1.32.0+) - Schema generation support.
Markdown (3.0.0+) - Markdown support for the browsable API.
Pygments (2.4.0+) - Add syntax highlighting to Markdown processing.
django-filter (1.0.1+) - Filtering support.
django-guardian (1.1.1+) - Object level permissions support.

これを元にrequirement.txtを作成。

1
djangorestframework

Django REST frameworkのインストール

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ pip install -r requirements.txt
Collecting djangorestframework
Downloading djangorestframework-3.11.0-py3-none-any.whl (911 kB)
|████████████████████████████████| 911 kB 3.2 MB/s
Collecting django>=1.11
Downloading Django-3.0.7-py3-none-any.whl (7.5 MB)
|████████████████████████████████| 7.5 MB 10.5 MB/s
Collecting sqlparse>=0.2.2
Downloading sqlparse-0.3.1-py2.py3-none-any.whl (40 kB)
|████████████████████████████████| 40 kB 7.7 MB/s
Collecting asgiref~=3.2
Downloading asgiref-3.2.9-py3-none-any.whl (19 kB)
Requirement already satisfied: pytz in /usr/local/lib/python3.8/site-packages (from django>=1.11->djangorestframework->-r requirements.txt (line 1)) (2019.3)
Installing collected packages: sqlparse, asgiref, django, djangorestframework
Successfully installed asgiref-3.2.9 django-3.0.7 djangorestframework-3.11.0 sqlparse-0.3.1

Exampleで基本的な動作を見る

プロジェクト作成

  1. django-adminコマンドでexampleプロジェクトを作成
  2. manage.py migrateを実行
  3. manage.py createsuperuserでrootアカウント作成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ django-admin startproject example .
$ tree .
.
├── README.md
├── docker-compose.yml
├── example
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt

1 directory, 9 files

$ ./manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK
$ ./manage.py createsuperuser
Username (leave blank to use 'root'):
Email address:
Password: ********
Password (again): ********
Superuser created successfully.

settings.pyのカスタマイズ

INSTALLED_APPSrest_frameworkを追加し、REST_FRAMEWORKで基本設定を行う。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
]

REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}

url.pyのカスタマイズ

Example用のAPIをカスタマイズ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import serializers, viewsets, routers

# Serializers define the API representation.
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['url', 'username', 'email', 'is_staff']


# ViewSets define the view behavior.
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer


# Routers provide a way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)


# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

APIのテスト

1
2
3
4
5
6
7
8
9
10
11
$ ./manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
June 17, 2020 - 15:50:19
Django version 3.0.7, using settings 'example.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[17/Jun/2020 15:50:42] "GET / HTTP/1.1" 200 47
[17/Jun/2020 15:50:49] "GET /users/ HTTP/1.1" 200 138

作成済のrootアカウントを閲覧できるか確認する。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ curl -H 'Accept: application/json; indent=4' -u root:rootroot http://127.0.0.1:8000/
{
"users": "http://127.0.0.1:8000/users/"
}
$ curl -H 'Accept: application/json; indent=4' -u root:rootroot http://127.0.0.1:8000/users/
[
{
"url": "http://127.0.0.1:8000/users/1/",
"username": "root",
"email": "",
"is_staff": true
}
]

ユーザを追加する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ curl -X POST -d username=new -d email=new@example.com -d is_staff=false -H 'Accept: application/json; indent=4' -u root:rootroot http://127.0.0.1:8000/users/
{
"url": "http://127.0.0.1:8000/users/2/",
"username": "new",
"email": "new@example.com",
"is_staff": false
}
$ curl -H 'Accept: application/json; indent=4' -u root:rootroot http://127.0.0.1:8000/users/
[
{
"url": "http://127.0.0.1:8000/users/1/",
"username": "root",
"email": "",
"is_staff": true
},
{
"url": "http://127.0.0.1:8000/users/2/",
"username": "new",
"email": "new@example.com",
"is_staff": false
}
]

runserverは127.0.0.1で待ち受けるので、コンテナ外からアクセスできるように0.0.0.0で待ち受ける。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ ./manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
June 17, 2020 - 16:12:22
Django version 3.0.7, using settings 'example.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
[17/Jun/2020 16:12:38] "GET / HTTP/1.1" 200 5322
[17/Jun/2020 16:12:38] "GET /static/rest_framework/css/bootstrap-tweaks.css HTTP/1.1" 200 3385
[17/Jun/2020 16:12:38] "GET /static/rest_framework/js/csrf.js HTTP/1.1" 200 1719
[17/Jun/2020 16:12:38] "GET /static/rest_framework/css/prettify.css HTTP/1.1" 200 817
[17/Jun/2020 16:12:38] "GET /static/rest_framework/js/prettify-min.js HTTP/1.1" 200 13632
[17/Jun/2020 16:12:38] "GET /static/rest_framework/css/bootstrap.min.css HTTP/1.1" 200 121457
[17/Jun/2020 16:12:38] "GET /static/rest_framework/css/default.css HTTP/1.1" 200 1131
[17/Jun/2020 16:12:38] "GET /static/rest_framework/js/bootstrap.min.js HTTP/1.1" 200 39680
[17/Jun/2020 16:12:38] "GET /static/rest_framework/js/ajax-form.js HTTP/1.1" 200 3597
[17/Jun/2020 16:12:38] "GET /static/rest_framework/js/default.js HTTP/1.1" 200 1268
[17/Jun/2020 16:12:38] "GET /static/rest_framework/js/jquery-3.4.1.min.js HTTP/1.1" 200 88145
[17/Jun/2020 16:12:39] "GET / HTTP/1.1" 200 5322
[17/Jun/2020 16:12:39] "GET /static/rest_framework/img/grid.png HTTP/1.1" 200 1458
Not Found: /favicon.ico
[17/Jun/2020 16:12:39] "GET /favicon.ico HTTP/1.1" 404 3137
[17/Jun/2020 16:13:02] "GET /users/ HTTP/1.1" 200 5886
[17/Jun/2020 16:13:03] "GET /static/rest_framework/css/bootstrap-tweaks.css HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/css/default.css HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/css/bootstrap.min.css HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/css/prettify.css HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/js/jquery-3.4.1.min.js HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/js/csrf.js HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/js/ajax-form.js HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/js/default.js HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/js/prettify-min.js HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/js/bootstrap.min.js HTTP/1.1" 304 0
[17/Jun/2020 16:13:03] "GET /static/rest_framework/img/grid.png HTTP/1.1" 304 0

Django REST framework example width=640

Django REST framework example width=640

管理画面

from django.contrib import adminでインポートし、urlpatternsにpath('admin/', admin.site.urls),を追加する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from django.contrib import admin
#from django.urls import path

#urlpatterns = [
# path('admin/', admin.site.urls),
#]

from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import serializers, viewsets, routers

…中略…

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

http://localhost:8000/admin/から管理機能にアクセスできる。

Django REST framework example width=640

Django REST framework example width=640

コメント・シェア

Sleepが安定しない…勝手に復帰してしまう

 
カテゴリー Windows   タグ

スリープが安定しない

PCをスリープさせて眠ろうとしたら……起動
再度スリープさせても……起動

解除しているデバイスは何か

管理者モードでコマンドプロンプトを起動して、powercfg -lastwakeで確認することができる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
C:\Windows\system32>powercfg -lastwake
スリープ状態の解除履歴カウント - 1
スリープ状態の解除履歴 [0]
スリープ状態の解除元カウント - 1
スリープ状態の解除元 [0]
種類: デバイス
インスタンス パス: USB\VID_XXXX&PID_XXXX\7&XXXXXXXXXXXXXXX
フレンドリ名:
説明: USB Composite Device
製造元: (標準 USB ホスト コントローラー)

C:\Windows\system32>powercfg -devicequery wake_armed
HID 準拠マウス
HID キーボード デバイス
HID キーボード デバイス (001)

イベントビューアーで確認する

Windowsログ -> システムでソースがPower-Troubleshooterのものを確認。

1
2
3
4
5
6
システムは低電力状態から再開しました。

スリープ時間: ‎2020‎-‎06‎-‎16T16:27:38.675253100Z
スリープ解除時間: ‎2020‎-‎06‎-‎16T16:28:02.205399800Z

スリープ状態の解除元: デバイス -USB Composite Device
1
2
3
4
5
6
システムは低電力状態から再開しました。

スリープ時間: ‎2020‎-‎06‎-‎16T16:39:26.214154100Z
スリープ解除時間: ‎2020‎-‎06‎-‎16T16:39:57.242369700Z

スリープ状態の解除元: デバイス -USB Composite Device

マウスは操作していないがUSB Composite Deviceによって30秒ぐらいでスリープ解除されている。

正常にスリープして復帰した場合は以下の様にスリープ時間~解除時間までは長い。

1
2
3
4
5
6
システムは低電力状態から再開しました。

スリープ時間: ‎2020‎-‎06‎-‎16T16:41:13.952273900Z
スリープ解除時間: ‎2020‎-‎06‎-‎16T22:51:34.244904400Z

スリープ状態の解除元: デバイス -USB Composite Device

スリープを邪魔しているものは

そもそもうまくスリープ後にすぐに復帰してしまう状態なので、何かが邪魔をしてスリープしないわけではない。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
C:\Windows\system32>powercfg -requests
DISPLAY:
なし。

SYSTEM:
なし。

AWAYMODE:
なし。

実行:
[SERVICE] \Device\HarddiskVolume3\Windows\System32\svchost.exe (UsoSvc)
Universal Orchestrator

PERFBOOST:
なし。

ACTIVELOCKSCREEN:
なし。

Universal OrchestratorでWindowsUpdateのためにスリープ解除する事例は多いが、今回は違う。

解決方法1: スリープ解除タイマーを無効化する

WindowsUpdateのためにスリープ解除する事例の対策でよくある、スリープ解除タイマーの無効化。
電源オプションの詳細設定でスリープ -> スリープ解除タイマーの許可 -> 設定: 無効にする。

Disable sleep awake width=480

なぜかこれで解消してしまった。

解決方法2: マウスのスリープ解除を無効化する

デバイスマネージャーでマウスとほかのポインティングデバイス -> HID準拠マウスのプロパティで設定する。
このデバイスで、コンピューターのスタンバイ状態を解除できるようにするのチェックを外す。

Disable sleep awake width=480

こちらが本命だったが、これを設定してもマウスを動かすとスリープ解除してしまう……

コメント・シェア

Atuh0で多要素認証(MFA)を使う

 
カテゴリー SaaS   タグ

Multi-factor Authentication

Multi-factor Authenticationを有効化(One-time Password)

Security -> Multi-factor Authenticationで有効化。

Auth0 MFA width=640

One-time PasswordはGoogle Authenticatorなどのアプリケーションを使用する。
多要素認証(MFA)はRuleを使用して適用する条件を設定できるが、ここではテストのために、Require Multi-factor AuthAlwaysにして常に使用するように設定する。

Auth0 MFA width=640

Continueをクリック。

Auth0 MFA width=640

多要素認証のテスト

QRコードが表示されるので、Google Authenticatorで読み込む。

Auth0 MFA width=640

リカバリーコードが表示されるので保存しておく。

Auth0 MFA width=640

多要素認証(MFA)の登録完了。

Auth0 MFA width=640

ログイン。

Auth0 MFA width=640

複数の要素を有効化する(One-time Password + Email)

もうひとつの要素としてEmailを有効化。Email is not available as an authentication factor when using the Classic Universal Login experienceという警告が表示されており、デフォルトのClassic Universla Loginでは利用できない。

Auth0 MFA width=640

Branding -> Universla LoginをClassicからNewに変更する。

Auth0 MFA width=640

ログイン画面が赤基調から青基調に変わっている。

Auth0 MFA width=640

GitHubアカウントでログイン。

Auth0 MFA width=640

One-time Passwordの登録が優先されている。

Auth0 MFA width=640

ログイン。

Auth0 MFA width=640

改めて再ログインを試みる。登録したOne-time Passwordの入力を促されるが、最下部のTry another methodを選択。

Auth0 MFA width=640

Emailを選択。

Auth0 MFA width=640

E-Mailアドレスにコードが送られ、コードの入力画面になる。

Auth0 MFA width=640

コメント・シェア

Atuh0でソーシャルログインする

 
カテゴリー SaaS   タグ

Social Connections

Auth0はさまざまなソーシャルログイン連携をSocial Connectionsとして提供している。
これを有効化するだけで、ソーシャルログイン機能を利用することができる。

Social Connectionsの有効化

Authentication -> Socialから連携するサービスをONにする。デフォルトでGoogleが有効になっている。

Auth0 SocialConnections width=640

連携先としてGitHubを追加する。GitHubを選択すると、連携に関する設定が表示される。連携のためには各プロバイダー(Social Identity Providers)のクライアントID(Client ID)とシークレット(Client Secret)が必要だが、テストの場合指定しなくても使用することができる。

Auth0 SocialConnections width=640

Attributesとして取得する属性の値を選択する。

Auth0 SocialConnections width=640

ここではEmail Addressread userを選択した。

Auth0 SocialConnections width=640

Social Connectionsはアプリケーション毎に有効化するかどうかを選択できる。
デフォルトのDefault Appとチュートリアルで作成したtestappが表示されている。

Auth0 SocialConnections width=640

ソーシャルログインのテスト1

Default Appからログインする。画面にSign in with GitHubが現れている。

Auth0 SocialConnections width=640

Auth0自身にGitHubアカウントでログインしているので、認証プロセスは省略され、Auth0に対する認可の確認画面が表示される。Email addresses (read-only)profile information (read-only)を許可するかどうかが問われる。

Auth0 SocialConnections width=640

Authrorize auth0を選択するとログイン後のページが表示される。

Auth0 SocialConnections width=640

ソーシャルログインのテスト2

testappからログインする。

Auth0 SocialConnections width=640

同じGitHubユーザで一度ログインしているのでAuth0に対する認可画面はない。

Auth0 SocialConnections width=640

アプリに対する認可の画面が表示される。

Auth0 SocialConnections width=640

認可するとログイン後のページが表示される。

Auth0 SocialConnections width=640

Client IDとClient Secretを取得する

ログインできることを確認できたので、GitHubのクライアントID(Client ID)とシークレット(Client Secret)を取得する。

Client IDとClient Secretの発行で必要になるドメイン名を確認する。Settings -> Custom Domainsで確認。

Auth0 SocialConnections width=640

GitHubのSettings -> Developer settingsOAuth AppsRegister a new application

Auth0 SocialConnections width=640

Auth0 SocialConnections width=640

指定の情報を入力してRegister applicationで、Client IDとClient Secretを発行。

  • Homepage URLhttps://YOUR_DOMAIN
  • Authorization callback URLhttps://YOUR_DOMAIN/login/callback

Auth0 SocialConnections width=640

登録されたOAuth appの画面からClient IDとClient Secretを取得することができる。この画面上でこの連携を経由して連携されたユーザの数が表示されている。このGitHubアカウント以外のGitHubアカウントも連携することができる。

Auth0 SocialConnections width=640

連携時の認可画面で表示するアイコンを設定することができる。

Auth0 SocialConnections width=640

Auth0 SocialConnections width=640

Auth0 SocialConnections width=640

Client IDとClient SecretをAuth0に登録する

Client IDとClient Secretを設定していない場合、!が表示されている。

Auth0 SocialConnections width=640

Client IDとClient Secretを設定し、追加でpublic_repoを連携する。

Auth0 SocialConnections width=640

!が表示されなくなる。

Auth0 SocialConnections width=640

ソーシャルログインのテスト3

Default Appから再度ログインする。一度ログイン済のため、ログイン画面は表示されず、先ほど追加したpublic_repoを含めた認可の画面が表示される。Auth0のアイコンはGitHubで設定したアイコンに変わっている。

Auth0 SocialConnections width=640

認可後は同じ。

Auth0 SocialConnections width=640

ソーシャルログインのテスト4

testappからログインする。

Auth0 SocialConnections width=640

こんどは新しいGitHubアカウントでログインする。

Auth0 SocialConnections width=640

設定したアイコンが表示されている。

Auth0 SocialConnections width=640

GitHubで認証すると、Auth0に対する認可画面が表示される。

Auth0 SocialConnections width=640

アプリに対する認可の画面が表示される。

Auth0 SocialConnections width=640

新しいアカウントでログインしたため2アカウントが表示されている。

Auth0 SocialConnections width=640

コメント・シェア

Auth0のDjangoチュートリアル

 
カテゴリー Python SaaS Tutorial   タグ

チュートリアルの開始

Getting StartedからIntegrate Auth0 into your applicationへ。Create Applicationからチュートリアルを開始。

Auth0 Django Tutorial width=640

testappとして、Regular Web Applicationを選択。

Auth0 Django Tutorial width=640

Django選択。

Auth0 Django Tutorial width=640

作成されたアプリケーションのページ。

Auth0 Django Tutorial width=640

GitHubからサンプルをfork。

Auth0 Django Tutorial width=640

python-social-auth/social-app-django

Python Social Auth is an easy to setup social authentication/registration mechanism with support for several frameworks and auth providers.
This is the Django component of the python-social-auth ecosystem, it implements the needed functionality to integrate social-auth-core in a Django based project.

Djangoプロジェクトにソーシャル認証を組み込み、OAuthによる認証認可を行うことができる。サンプルアプリ側ではこれを利用してauth0の認証を行っている。

Get Your Application Keys

When you signed up for Auth0, a new application was created for you, or you could have created a new one.

新しアプリケーションを作成すると、以下が発行されるので、Settingsから取得する。

  • Domain
  • Client ID
  • Client Secret

Configure Callback URLs

A callback URL is a URL in your application where Auth0 redirects the user after they have authenticated.
The callback URL for your app must be whitelisted in the Allowed Callback URLs field in your Application Settings. If this field is not set, users will be unable to log in to the application and will get an error.

認証後のリダイレクト先。Settingsでホワイトリスト登録する必要がある。

Configure Logout URLs

A logout URL is a URL in your application that Auth0 can return to after the user has been logged out of the authorization server. This is specified in the returnTo query parameter.
The logout URL for your app must be whitelisted in the Allowed Logout URLs field in your Application Settings. If this field is not set, users will be unable to log out from the application and will get an error.

ログアウト後のリダイレクト先。Settingsでホワイトリスト登録する必要がある。

Django Settings

サンプルアプリはほぼ設定済で、環境変数のみ.envに設定すればOK。

1
2
3
AUTH0_CLIENT_ID={CLIENT_ID}
AUTH0_DOMAIN={DOMAIN}
AUTH0_CLIENT_SECRET={CLIENT_SECRET}

Install the Dependencies

pip install -r requirements.txtでインストール。チュートリアルのDockerイメージはビルドの中でこれらもインストールされる。

1
2
3
4
django~=2.1
social-auth-app-django~=3.1
python-jose~=3.0
python-dotenv~=0.9

以下のDockerfileが用意されており、サンプルアプリを利用可能な状態になっている。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FROM python:3.6

WORKDIR /home/app

#If we add the requirements and install dependencies first, docker can use cache if requirements don't change
ADD requirements.txt /home/app
RUN pip install --no-cache-dir -r requirements.txt

ADD . /home/app

# Migrate the database
RUN python manage.py migrate

CMD python manage.py runserver 0.0.0.0:3000

EXPOSE 3000

docker-composeで操作したいので、docker-compose.ymlを作成する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3'

services:
auth0:
container_name: auth0-django
build:
context: .
dockerfile: Dockerfile
tty: true
ports:
- "3000:3000"
environment:
AUTH0_CLIENT_ID: ${AUTH0_CLIENT_ID}
AUTH0_DOMAIN: ${AUTH0_DOMAIN}
AUTH0_CLIENT_SECRET: ${AUTH0_CLIENT_SECRET}
1
2
3
$ docker-compose up -d
Creating network "01-login_default" with the default driver
Creating auth0-django ... done

サンプルアプリへのログイン

【GET /】http://localhost:3000にアクセス。

Auth0 Django Tutorial width=640

【GET /login/auth0】auth0のユニバーサルログインページに転送され、ログインすると…

Auth0 Django Tutorial width=640

【GET /dashboard】属性情報を表示されるアプリに転送され、渡されたユーザデータが表示される。

Auth0 Django Tutorial width=640

アプリサイドのログ

この時のサーバログは以下の内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Creating network "01-login_default" with the default driver
Creating auth0-django ... done
Attaching to auth0-django
auth0-django | Watching for file changes with StatReloader
auth0-django | Performing system checks...
auth0-django |
auth0-django | System check identified no issues (0 silenced).
auth0-django | June 05, 2020 - 11:14:04
auth0-django | Django version 2.2.13, using settings 'webappexample.settings'
auth0-django | Starting development server at http://0.0.0.0:3000/
auth0-django | Quit the server with CONTROL-C.
auth0-django | [05/Jun/2020 11:14:13] "GET / HTTP/1.1" 200 899
auth0-django | [05/Jun/2020 11:14:18] "GET /login/auth0 HTTP/1.1" 302 0
auth0-django | [05/Jun/2020 11:14:29] "GET /complete/auth0?code=kOYVXXXXXMVD8Sl&state=s0l9XXXXXXXXXXXXbPBNzeaA HTTP/1.1" 302 0
auth0-django | [05/Jun/2020 11:14:29] "GET /dashboard HTTP/1.1" 200 1371

Auth0サイドのログ

Auth0のログ

Auth0 Django Tutorial width=640

Type:Success ExchangeAuthorization Code for Access TokenというDescriptionが付与されており、前述のGET /complete/auth0?code=で指定している認可コードを取得している。

内容はにRawContextDataとしてJSON形式で確認できる。

Rawでは以下が表示され、アプリからのリクエスト情報が記録されている。
User-Agentはアプリであり、内部的に使用されるPython RequestsのUser-Agentが記録されている。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"date": "2020-06-05T11:14:28.994Z",
"type": "seacft",
"description": "Authorization Code for Access Token",
"connection_id": "",
"client_id": "orEXXXXXXXXXXXXXXXXXIFWsMF",
"client_name": "testapp",
"ip": "XXX.XXX.XXX.XXX",
"user_agent": "Python Requests 2.23.0 / Other 0.0.0",
"details": {
"code": "*************8Sl"
},
"hostname": "devXXXXXXXXXXXXX.auth0.com",
"user_id": "auth0|XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"user_name": "XXXXXXXXXXXXX@xxxxxxx.xxxxxx",
"log_id": "9002020XXXXXXXXXXXXXXXXXXXXXXXXXXXX08290750546",
"_id": "9002020XXXXXXXXXXXXXXXXXXXXXXXXXXXX08290750546",
"isMobile": false
}

ContextDataにはdetailsの内容が入っている。

1
2
3
{
"code": "*************8Sl"
}

Type:Success Loginはクライアントのログイン認証の成功を示している。利用者からの認証であり、User-Agentは利用者のブラウザの情報が記録されている。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
"date": "2020-06-05T11:14:28.363Z",
"type": "s",
"connection": "Username-Password-Authentication",
"connection_id": "con_XXXXXXXXXXXXXXv7",
"client_id": "orEXXXXXXXXXXXXXXXXXIFWsMF",
"client_name": "testapp",
"ip": "XXX.XXX.XXX.XXX",
"user_agent": "Chrome 83.0.4103 / Windows 10.0.0",
"details": {
"prompts": [
{
"name": "lock-password-authenticate",
"initiatedAt": 1591355668017,
"completedAt": 1591355668324,
"connection": "Username-Password-Authentication",
"connection_id": "con_XXXXXXXXXXXXXXv7",
"strategy": "auth0",
"identity": "5edXXXXXXXXXXXXXXXcf9",
"stats": {
"loginsCount": 6
},
"session_user": "5edaXXXXXXXXXXXXXXX2e9d36",
"elapsedTime": 307
},
{
"name": "login",
"flow": "login",
"initiatedAt": 1591355658531,
"completedAt": 1591355668329,
"user_id": "auth0|XXXXXXXXXXXXXXX6ecf9",
"user_name": "XXXXXXXXXXXXX@xxxxxxx.xxxxxx",
"elapsedTime": 9798
}
],
"initiatedAt": 1591355658530,
"completedAt": 1591355668362,
"elapsedTime": 9832,
"session_id": "0FetBO15mf0vQs_YfMoZTQdeItwyJKdH",
"stats": {
"loginsCount": 6
}
},
"hostname": "dev-e6hrtsp8.auth0.com",
"user_id": "auth0|5ed5fb1b424ed40bee36ecf9",
"user_name": "XXXXXXXXXXXXX@xxxxxxx.xxxxxx",
"strategy": "auth0",
"strategy_type": "database",
"log_id": "900202XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX7572418",
"_id": "900202XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX7572418",
"isMobile": false,
"description": "Successful login"
}

コメント・シェア

認証プラットフォームAuth0

 
カテゴリー SaaS   タグ

Auth0

IDaaS(Identity as a Service)

STANDARD PROTOCOLS

SAML, OpenID Connect, JSON Web Token, OAuth 2.0, OAuth 1.0a, WS­-Federation and OpenID.

標準的なプロトコルに対応。

  • SAML … XMLベースの標準シングルサイオン形式のフレームワーク
  • OpenID Connect … 認証・認可プロトコル、属性情報を取得する機能も含む
  • JWT(JSON Web Token) … 安全にクレームを表現するための方式
  • OAuth 1.0a/2.0 … 認可プロトコル
  • WS-Federation … SAMLライクなクレームベース認証仕様(Microsoft, IBM, Novel)
  • OpenID … 認証プロトコル(認可はしない)

MULTIFACTOR AUTHENTICATION

Typically, Multifactor Authentication requires a combination of something the user knows, something the user has, and sometimes something the user is.

  • Knowledge factors, such as passwords, PINs, or secret questions.
  • Possesion factors, such as an access card, phone, or hardware key.
  • Inherence factors, which are biometric information, such as the user’s fingerprint, face, or voice.

多要素認証はユーザが「知っていること」「持っていること」「自身であること」を組み合わせて認証する。

  • 知っていること … パスワード、PIN、秘密の質問
  • 持っていること … アクセスカード、ハードウェアキー、電話
  • 自身であること … 指紋、顔、声などの生体情報

「記憶」「所持」「バイオメトリクス」であったり「SYK:Something You Know」「SYH:Something You Have」「SYA:Something You Are」など、表現はいろいろあるが、認証の3要素として基本。
多要素認証はこれら異なる要素を用いる認証方式のことで、同じ要素の認証を複数組み合わせる場合は多段階認証(Multi Step Authentication)である。

ADAPTIVE CONTEXT-AWARE MULTIFACTOR
Adaptative Context-aware Multifactor allows you to enforce MFA or additional layers of authentication based on different conditions such as: geographic location, time of day/week, type of network, custom domains or certain IPs, or any arbitrary condition that can be expressed in code on the Auth0 platform.

地理的位置、時刻、ネットワークの種類、カスタムドメイン、特定のIPなどの条件でMFAや追加の認証レイヤーを適用することができる。

いわゆるステップアップ認証やリスクベース認証を実現する機能で、Ruleによって多要素認証を適用する条件を記述する。

CUSTOM MFA PROVIDERS
If you are using a different MFA provider or want to build your own, you can use the redirect protocol in Auth0.

To use a custom MFA provider, you can interrupt the authentication transaction and redirect the user to an arbitrary URL where an additional authentication factor can happen. After this completes (successfully or not), the transaction can then resume in Auth0 for further processing.

途中で別のMFAプロバイダーにredirectして処理できる。リダイレクト先の処理が完了すると成功か否かにかかわらずAuth0側での処理が再開される。

SINGLE SIGN ON

You can enable Single Sign On for your corporate applications like Salesforce, Dropbox, Slack, and much more! With Auth0, this is just a few clicks away. Auth0 provides out-of-the-box support for more than 15 cloud applications.
These applications are: Microsoft Azure Active Directory, Box, CloudBees, Concur, Dropbox, Microsoft Dynamics CRM, Adobe Echosign, Egnyte, New Relic, Office 365, Salesforce, Sharepoint, Slack, Springcm, Zendesk, and Zoom.

標準で多くのクラウドアプリにシングルサインオンできる。

SINGLE LOG OUT
Single Log Out is the inverse process of Single Sign On, once you log out of one of the configured applications, your session will end in all of them. You will save time, and will never forget your sessions opened again.

シングルサインアウトもできる。

LAST MILE INTEGRATION THROUGH JAVASCRIPT
If you need further customization, you can always use Auth0’s rules engine. Rules are JavaScript code snippets that run in Auth0 and empowers you to control and customize any stage of the authentication and authorization pipeline. We know that every case is completely different!
See the Rules documentation for more information.

JavaScriptでRuleを記述し、認証パイプラインを構築できる。

SOCIAL LOGIN

SOCIAL PROVIDERS WITH AUTH0
Auth0 supports 30+ social providers: Facebook, Twitter, Google, Yahoo, Windows Live, LinkedIn, GitHub, PayPal, Amazon, vKontakte, Yandex, 37signals, Box, Salesforce, Salesforce (sandbox), Salesforce Community, Fitbit, Baidu, RenRen, Weibo, AOL, Shopify, WordPress, Dwolla, miiCard, Yammer, SoundCloud, Instagram, The City, The City (sandbox), Planning Center, Evernote, Evernote (sandbox), and Exact. Additionally, you can add any OAuth2 Authorization Server you need.

標準で多くのソーシャルプロバイダーをサポート。さらにOAuth2の認証サーバを追加することができる。

Every provider has its own profile properties, required headers, and response format, and some use OAuth1 (Twitter) while others use OAuth2. Auth0 simplifies this for you, encapsulating the differences, and unifying the way to call providers and the information retrieved from all of them.

各プロバイダーが持つ独自のプロファイルプロパティやヘッダー情報、応答フォーマット、プロトコルの違い(OAuth1, OAuth2)を吸収する。

料金

Get Auth0 for free with up to 7,000 active users, unlimited logins. No credit card required.

7000アクティブユーザまで無料。登録ユーザ数ではなくアクティブユーザである点は素晴らしい。

サインアップ

Auth0 width=640

Auth0 width=640

Auth0 width=640

ソーシャルログインに対応している。ここではGitHubアカウントを使用する。

Auth0 width=640

Auth0 width=640

Auth0 width=640

Auth0 width=640

REGIONを選択。後から変更することはできない。

Auth0 width=640

Auth0 width=640

Auth0 width=640

使ってみる

Try your Login boxからログインを試すことができる。Try it outを押すとログイン画面が表示される。

Auth0 width=640

Auth0 width=640

Auth0 width=640

Auth0 width=640

コメント・シェア

DooD(Docker outside of Docker)

起動したDockerコンテナの中で、dockerを利用する方法の1つで、Dockerデーモンはホスト側にバイパスしてDockerコンテナを動作させる方法。dockerやdocker-composeの操作をdockerコンテナ内で行っていても、コンテナから起動したコンテナはホスト側で動いている。

コンテナにDockerをインストール

起動させるコンテナ側でdockerやdocker-composeのCUIを使用するので、必要パッケージをインストール。

1
2
apt-get install -y --no-install-recommends docker.io
apt-get install -y --no-install-recommends docker-compose

Dockerサーバの共有

Dockerのホスト側へは/var/run/docker.sockをバイパスすることでアクセス。
docker-comopose.yml/var/run/docker.sockをvolumeとしてマウント。

1
2
volumes:
- /var/run/docker.sock:/var/run/docker.sock

DooDで起動したDockerでVolumeマウント

ボリュームマウントは注意が必要。
Dockerデーモンが動作する親ホスト、そこから起動した子コンテナ、DooDでさらに起動する孫コンテナとした場合、孫コンテナが行うボリュームマウントは親ホストのボリュームで、子コンテナのボリュームではない。

子コンテナが親ホストのボリュームをマウントする場合

親ホスト側でdocker-compose.ymlを記述する場合、以下のような相対パスで指定できる。
これはdocker-composeを起動しているのは親ホストで、相対パスは自身の認識する相対パスだから可能。

1
2
volumes:
- .:/work/:rw

孫コンテナが親ホストのボリュームをマウントする場合

子コンテナで起動するdocker-compose.ymlでは相対パスで記述することはできない。
記述してもエラーにはならないが、空のディレクトリとしてマウントされるだけだ。DooDの仕組みから考えれば直感的に理解できる。

1
2
volumes:
- /host/full/path:/work/:rw

どちらでも起動できるようにするには

docker-compose.ymlは動かす環境ごとに記述したくないので、docker-compose.yml内で、環境変数を使って環境ごとにボリューム先を変える。

1
2
volumes:
- ${WORK_DIR}:/work/:rw

親ホストで実行する場合は.envファイルでWORK_DIR=.を指定する。
子コンテナから起動する場合は親ホストのフルパスを環境変数としてWORK_DIRを実行ホストの絶対パスで指定する。

コメント・シェア

DockerでCIFSマウントする

 
カテゴリー Container   タグ

cifs-utilsのインストール

1
apt-get install -y --no-install-recommends cifs-utils

cifs-utilsがない場合はmount: /mnt: cannot mount //xxx.xxx.xxx.xxx/xxxxxx read-only.となる。

コンテナからcifs-utilsでマウントする例

ENTRYPOINTでCIFSをマウントするにはcifs-utilsをインストールして、mount -t cifsでマウントする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#
# CIFS Mount
#
if [ -z ${CIFS_USER} ] || [ -z ${CIFS_PASS} ] || [ -z ${CIFS_HOST} ] || [ -z ${CIFS_REMOTE_PATH} ] || [ -z ${CIFS_LOCAL_PATH} ]; then
echo "need export CIFS_XXXXXX"
exit 1
fi

mkdir -p ${CIFS_LOCAL_PATH}
mount -t cifs -o username=${CIFS_USER},password=${CIFS_PASS} //${CIFS_HOST}${CIFS_REMOTE_PATH} ${CIFS_LOCAL_PATH}
MOUNT_STATUS=$?
if [ ${MOUNT_STATUS} = "0" ]; then
echo "Mount Status: ${MOUNT_STATUS}"
echo "Mount From: ${CIFS_HOST}:${CIFS_REMOTE_PATH}"
echo "Mount To: ${CIFS_LOCAL_PATH}"
else
echo "Mount Status: ${MOUNT_STATUS}"
exit 1
fi

…略…

#
# CIFS Umount
#
umount ${CIFS_LOCAL_PATH}

権限がない(privilegedとcapabilities)

デフォルトでDockerでmountを試みた場合、Unable to apply new capability set.でマウントできない。

これはDockerのRuntime privilege and Linux capabilitiesに記載がある。

By default, Docker containers are “unprivileged” and cannot, for example, run a Docker daemon inside a Docker container. This is because by default a container is not allowed to access any devices, but a “privileged” container is given access to all devices (see the documentation on cgroups devices).

デフォルトではDockerコンテナはunprivilegedで動作し、デバイスへのアクセスを許可されていない。

When the operator executes docker run –privileged, Docker will enable access to all devices on the host as well as set some configuration in AppArmor or SELinux to allow the container nearly all the same access to the host as processes running outside containers on the host.

docker run --privilegedで実行したとき、privileged状態で起動することができる。その場合、Dockerはホストすべてのデバイスにアクセス可能で、AppArmorやSELinuxの設定を行い、他のホスト上のプロセスと同じ権限を与えてしまう。

If you want to limit access to a specific device or devices you can use the –device flag. It allows you to specify one or more devices that will be accessible within the container.

--device付きで実行すれば、特定のデバイスの利用許可を与えることができる。

In addition to –privileged, the operator can have fine grain control over the capabilities using –cap-add and –cap-drop. By default, Docker has a default list of capabilities that are kept. The following table lists the Linux capability options which are allowed by default and can be dropped.

--privilegedに加えて、--cap-addで細かく権限を制御することができる。

docker-composeで権限付与を行う

privilegedはprivileged: trueで有効化することができる。
privilegedはすべての権限を付与するので以下の例に意味はないが、--cap-addcap_addとして設定することができる。

1
2
3
4
5
6
7
8
9
10
11
12
…略…
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
CIFS_USER: ${CIFS_USER}
CIFS_PASS: ${CIFS_PASS}
CIFS_HOST: ${CIFS_HOST}
CIFS_REMOTE_PATH: ${CIFS_REMOTE_PATH}
CIFS_LOCAL_PATH: ${CIFS_LOCAL_PATH}
privileged: true
cap_add:
- SYS_ADMIN

コメント・シェア

Dockerでsudoを実行する

 
カテゴリー Container   タグ

Dockerでsudoしようとするとエラーになる

Dockerでsudoを実行すると、パスワード入力を求められるためエラーになる。

1
2
3
4
5
6
7
8
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.

sudo: no tty present and no askpass program specified

対話型でパスワードを入力しないようにecho "<user> ALL=(ALL) NOPASSWD: ALL" > /etc/sudoersで指定ユーザはパスワードなしで実行可能にする。

環境変数が引き継がれない

sudoで実行した場合、環境変数が引き継がれない。これはenv_resetが有効になっているため。Defaults:<user> !env_resetで指定ユーザのみenv_resetを無効化することができる。

sudoを利用するためのDockerfile記述内容

1
2
3
4
RUN apt-get install -y --no-install-recommends sudo && \
echo "Defaults:<user> !env_reset" > /etc/sudoers && \
echo "<user> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
USER <user>

コメント・シェア



nullpo

めも


募集中


Japan