アプリケーションをセキュアに
JHipsterによって生成されたもののように、単一のWebページアプリケーションでSpring Securityを使用するには、XHRによるログイン/ログアウト/エラービューが必要です。これらのビューを正しく使用するためにSpring Securityを設定し、すべてのJavaScriptとHTMLコードを生成します。
デフォルトでは、JHipsterには2つの異なるユーザがいます。
- "user":これは"ROLE_USER"権限を持つ通常のユーザーです。デフォルトのパスワードは"user"です。
- "admin":"ROLE_USER"および"ROLE_ADMIN"権限を持つ管理ユーザーです。デフォルトのパスワードは"admin"です。
"ROLE_USER"と"ROLE_ADMIN"の2つの権限は、エンティティに対して同じアクセスを提供します。つまり、"user"は"admin"と同じCRUD操作する権限を与えられています。この動作は、"user"が任意のエンティティを削除できるなどの理由で、アプリケーションが本番に移行するときに問題になる可能性があります。アクセス制御を改善する方法の詳細については、このブログ投稿を参照してください。
セキュリティ上の理由から、運用環境ではこれらのデフォルトパスワードを変更する必要があります。
JHipsterは、3つの主要なセキュリティメカニズムを提供します。
JSON Web Tokens (JWT)
JSON Web Token (JWT)認証はステートレス・セキュリティー・メカニズムなので、複数の異なるサーバー上でアプリケーションを拡張したい場合には良い選択肢です。
マイクロサービスアーキテクチャを使用する場合、これがデフォルトのオプションであることに注意してください。
この認証メカニズムは、デフォルトではSpring Securityには存在せず、Java JWTプロジェクトを統合しJHipsterに特化させたものです。
このソリューションでは、ユーザーのログイン名と権限を保持するセキュア・トークンを使用します。トークンは署名されているため、ユーザーによる変更はできません。
JHipsterは、無効なJWTをカスタムアプリケーションメトリクスとして自動的に追跡します。モニタリングドキュメントを参照してください。
JWTをセキュアに
- JHipsterは、
jhipster.security.authentication.jwt.secret
とjhipster.security.authentication.jwt.base64-secret
という2つのSpring Bootプロパティを使用して設定できる秘密鍵を使用します。 2番目のオプションは、Base 64でエンコードされた文字列を使用し、より安全であると 考えられるため、推奨します。両方のプロパティが設定されている場合は、レガシーな理由により、secret
プロパティ(セキュリティが低い方)が使用されます。 Base64プロパティを使用しない場合は、アプリケーションの起動時に警告が表示されます。 - これらのキーの最小長は512ビットである必要があります。十分な長さがない場合は、ログインに使用できません。その場合は、コンソールにその問題を説明する明確な警告が表示されます。
- 秘密鍵は
application-*.yml
ファイルで設定されています。これらの鍵は秘密にしておく必要があるので、プロダクションのプロファイル用に安全な方法で保管する必要があります。 通常、Spring Bootプロパティ設定を使用して設定できます。JHipster RegistryのようなSpring Cloud Configサーバを使用するか、 環境変数を使用するか、システム管理者によってアプリケーションの実行可能なWARファイルと同じディレクトリにSCPで置かれた特有のapplication-prod.yml
ファイルを使用します。 - デフォルトの"user"および"admin"パスワードは変更する必要があります。これを行う最も簡単な方法は、アプリケーションをデプロイし、"user/user"としてログインしてから"admin/admin"としてログインし、それぞれに対して"Account > Password"メニューを使用してパスワードを変更することです。
セッションベースの認証
これは「古典的な」Spring Security認証メカニズムですが、大幅に改善されています。HTTPセッションを使用するため、ステートフルなメカニ ズムです。複数のサーバでアプリケーションを拡張する場合は、各ユーザが同じサーバにとどまるように、スティッキセッションを備えたロードバランサを使用するか、Spring Sessionを追加して、メモリではなくデータベースにセッションを格納することを検討する必要があります。
セッションベースの認証をセキュアに
- Remember-me認証の場合、Remember-meキーは
application-dev.yml
およびapplication-prod.yml
ファイル内で、jhipster.security.remember-me.key
プロパティとして設定されます。このキーは秘密にしておく必要があるため、プロダクションのプロファイル用に安全な方法で保存する必要があります。通常、Spring Bootプロパティ設定を使用して設定できます。JHipster RegistryのようなSpring Cloud Configサーバを使用するか、環境変数を使用するか、システム管理者によってアプリケーションの実行可能なWARファイルと同じディレクトリにSCPで置かれた特有のapplication-prod.yml
ファイルを使用します。 - デフォルトの"user"および"admin"パスワードは変更する必要があります。これを行う最も簡単な方法は、アプリケーションをデプロイし、"user/user"としてログインしてから"admin/admin"としてログインし、それぞれに対して"Account > Password"メニューを使用してパスワードを変更することです。
remember-meメカニズムの改善
私たちは、Spring Securityのremember-meメカニズムを変更して、データベース(SQLまたはNoSQLデータベースなど生成時の選択に応じて!)に格納される独自のトークンを持つようにしました。また、標準の実装よりも多くの情報を格納するようにし、トークンの出所(IPアドレス、ブラウザ、日付など)をよりよく理解できます。さらに、完全な管理画面を生成し、別のコンピュータでログアウトするのを忘れた場合などにセッションを無効にできるようにしました。
Cookieの盗難対策
私たちは、完成度の高いCoockie盗難防止メカニズムを追加しました。あなたのセキュリティ情報をCookieとデータベースに保存し、ユーザーがログインするたびにそれらの値を修正し、それらが変更されたかどうかをチェックします。そうすることで、誰かがあなたのCoockieを盗んだ場合でも、使用できるのは最大で1回だけます。
OAuth 2.0とOpenID Connect
OAuthは、HTTPセッションのようなステートフルなセキュリティメカニズムです。Spring Securityは、優れたOAuth 2.0とOIDCのサポートを提供しており、これはJHipsterによって活用されています。OAuthとOpenID Connect(OIDC)が何であるかわからない場合は、OAuthとは何か?を参照してください。
Keycloak
Keycloakは、JHipsterで設定されたデフォルトのOpenID Connectサーバです。
アプリケーションにログインするには、Keycloakを起動して実行する必要があります。JHipsterチームは、デフォルトのユーザーとロールを持つDockerコンテナを作成しました。次のコマンドを使用してKeycloakを起動します。
docker-compose -f src/main/docker/keycloak.yml up
あるいは、次のようなnpm
の使用もできます。
npm run docker:keycloak:up
Docker ComposeでKeycloakを使用したい場合は、Docker Composeドキュメントを必ず読み、Keycloak用に/etc/hosts
を正しく設定してください。
Apple Silicon(M1)上のJHipster 7.8.1およびKeycloak 16.1.0に関する注意
v18より前のKeycloakは、互換モードのApple Siliconで誤動作する可能性があり、解決策は明らかでは ありません。この問題はKeycloakイメージをローカルに構築することで解決できます。
git clone [email protected]:keycloak/keycloak-containers.git
cd keycloak-containers/server
git checkout 16.1.0
docker build -t jboss/keycloak:16.1.0 .
このイメージには、src/main/resources/config/application.yml
のセキュリティ設定が構成されています。上記の/etc/hosts
に関する注意を参照し、issuer-uri
を変更する必要がある場合があることに注意してください。
spring:
...
security:
oauth2:
client:
provider:
oidc:
issuer-uri: http://localhost:9080/auth/realms/jhipster
# localhostは、ホストではなく、ゲスト(コンテナ)にバインドされます。
# Keycloakをデーモンとして実行するには、npm run docker:keycloak:upとなり、/etc/hostsの編集と、
# issuer-uriを次のようにする必要があります。
# issuer-uri: http://keycloak:9080/auth/realms/jhipster
registration:
oidc:
client-id: web_app
client-secret: web_app
scope: openid,profile,email
Keycloakはデフォルトで組み込みH2データベースを使用しているため、Dockerコンテナを再起動すると、作成されたユーザが失われます。データを保持するには、Keycloak Dockerドキュメントを参照してください。H2データベースを保持する1つの解決策は、以下を実施します。
- 永続化するボリュームを追加します:
./keycloak-db:/opt/jboss/keycloak/standalone/data
- マイグレーション方法を
OVERWRITE_EXISTING
からIGNORE_EXISTING
に変更します(コマンドセクション内)
本番環境では、HTTPSを使用することがKeycloakによって要求されます。これを実現するには、HTTPSを管理するリバース・プロキシまたはロード・バランサを使用するなど、いくつかの方法があります。このトピックの詳細を知るには、Keycloak HTTPSドキュメントを読むことをお薦めします。
Auth0
Keycloakの代わりにAuth0を使用する場合は、次の設定手順に従います。
Auth0 Admin Dashboardを使用したOIDCアプリケーションの作成
-
https://auth0.com/signup で無料の開発者アカウントを作成します。サインアップが成功すると、アカウントは
dev-xxx.us.auth0.com
のような独自のドメインに関連付けられます。 -
Regular Web Applications
タイプの新しいアプリケーションを作成します。Settings
タブに切り替えて、次のようにアプリケーションの設定を構成します。- Allowed Callback URLs:
http://localhost:8080/login/oauth2/code/oidc
- Allowed Logout URLs:
http://localhost:8080/
- 注意:Consulを使用している場合は、ポート8500のURLも追加します。
- 注意:JHipsterレジストリを使用している場合は、ポート8761のURLも追加します。
- Allowed Callback URLs:
-
User Management > Rolesに移動し、
ROLE_ADMIN
およびROLE_USER
という名前の新しいロールを作成します。 -
User Management > Usersに移動し、新しいユーザーアカウントを作成します。 Roleタブをクリックして、新しく作成したユーザーアカウントに役割を割り当てます。
-
Actions > Flowsに移動し、Loginを選択します。
Add Roles
という名前の新しいアクションを作成し、デフォルトのトリガーとランタイムを使用します。onExecutePostLogin
ハンドラを次のように変更します。exports.onExecutePostLogin = async (event, api) => {
const namespace = 'https://www.jhipster.tech';
if (event.authorization) {
api.idToken.setCustomClaim('preferred_username', event.user.email);
api.idToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
api.accessToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
}
} -
Deployを選択し、
Add Roles
アクションをログインフローにドラッグします。
これらの手順をすべて自動化したい場合は、Auth0 CLIプロジェクトのissue #351に👍を追加してください。
Auth0をOIDCプロバイダとして使用するようにJHipsterアプリケーションを構成
JHipster
アプリケーションで、Auth0設定を使用するようにsrc/main/resources/config/application.yml
を変更します。
spring:
...
security:
oauth2:
client:
provider:
oidc:
# 必ず最後のスラッシュを含めるようにしてください!
issuer-uri: https://{your-auth0-domain}/
registration:
oidc:
client-id: {clientId}
client-secret: {clientSecret}
scope: openid,profile,email
jhipster:
security:
oauth2:
audience: https://{your-auth0-domain}/api/v2/
issuer-uri
の値に疑問がある場合は、Applications > {Your Application} > Settings > Advanced Settings > Endpoints > OpenID Configurationから値を取得できます。.well-known/openid-configuration
のサフィックスはSpring Securityによって追加されるので削除してください。
Applications > API > API AudienceフィールドからデフォルトのAuth0 Management API
オーディエンス値を使用できます。独自のカスタムAPIを定義して、識別子をAPIオーディエンスとして使用することもできます。
Cypress
テストを実行する前に、CYPRESS_E2E_USERNAME
およびCYPRESS_E2E_PASSWORD
環境変数を上書きして、Auth0
ユーザーの詳細を指定してください。詳細については、Cypressのドキュメントを参照してください。
export CYPRESS_E2E_USERNAME=<your-username>
export CYPRESS_E2E_PASSWORD=<your-password>
注意:Auth0では、ユーザーは最初のログイン時に認可の同意を提供する必要があります。同意フローは現在、Cypressテストスイートでは処理されません。この問題を軽減するには、すでに同意を付与しているユーザーアカウントを使用して、対話型ログインを介したアプリケーションアクセスを許可できます。
Cypressで認証の問題が発生した場合の回避策については、このガイドを参照してください。
環境変数の使用
環境変数を使用してのデフォルトの上書もできます。次に例を示します。
export SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI="https://{your-auth0-domain}/"
export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID="{client-id}"
export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET="{client-secret}"
export JHIPSTER_SECURITY_OAUTH2_AUDIENCE="https://{your-auth0-domain}/api/v2/"
これを~/.auth0.env
ファイルに入れてsource ~/.auth0.env
を実行すると、 デフォルトのKeycloak設定をAuth0でオーバーライドして、MavenまたはGradleでアプリを起動できます。登録した資格情報を使用してサインインできるはずです。
注意:Windowsの場合は、source
コマンドが動作するように、WSLをインストールする必要があります。
Auth0でモバイル用のネイティブアプリを作成する
JHipsterのIonicまたはReact NativeのBlueprintを使用してモバイルアプリを開発している場合、OIDCを使用しているなら、Auth0でネイティブアプリを作成することになる可能性があります。
-
Nativeアプリケーションを作成し、次のAllowed Callback URLsを追加します。
- Ionic:
http://localhost:8100/callback,dev.localhost.ionic:/callback
- React Native:
http://localhost:19006/,https://auth.expo.io/@<username>/<appname>
- Ionic:
-
Allowed Logout URLsを次のように設定します。
- Ionic:
http://localhost:8100/logout,dev.localhost.ionic:/logout
- React:
http://localhost:19006/,https://auth.expo.io/@<username>/<appname>
- Ionic:
-
Allowed Origins (CORS)を設定します。
- Ionic:
http://localhost:8100,capacitor://localhost,http://localhost
- React Native:
http://localhost:19006
- Ionic:
Ionicアプリをアップデートする
生成されたクライアントIDを使用するように、ionic/src/environments/environment.ts
を更新します。server_host
の値は、JHipsterアプリケーション(/api/auth-info
)から検索されますが、フォールバック値としての定義もできます。また、audienceも指定する必要があります。以下は例です。
const oidcConfig: IAuthConfig = {
client_id: '<native-client-id>',
server_host: 'https://<your-auth0-domain>/',
...
};
export const environment = {
...
audience: 'https://<your-auth0-domain>/api/v2/',
...
};
Ionicアプリを再起動し、Auth0でログインします!
Reactネイティブアプリのアップデート
クライアントIDをapp/config/app-config.js
にコピーします。
app/modules/login/login.utils.ts
のaudience
を更新します。
audience: 'https://<your-auth0-domain>/api/v2/',
React Nativeアプリを再起動し、Auth0でログインします!
Okta
Keycloakの代わりにOktaを使用したい場合は、Okta CLIを使用するとかなり早いです。インストールしたら、次のコマンドを実行します。
okta register
次に、JHipsterアプリのディレクトリでokta apps create jhipster
を実行します。これにより、Oktaアプリが設定され、ROLE_ADMIN
グループとROLE_USER
グループが作成され、Okta設定を含む.okta.env
ファイルが作成され、IDトークンにgroups
クレームが設定されます。
source .okta.env
を実行し、MavenまたはGradleでアプリを起動します。登録した資格情報を使用してサインインできるはずです。
Windowsの場合は、source
コマンドが動作するように、WSLをインストールする必要があります。
Okta Admin Consoleから手動で設定する場合は、次の手順を参照してください。
Okta管理コンソールを使用したOIDCアプリケーションの作成
まず、 https://developer.okta.com/signup で無料の開発者アカウントを作成する必要があります。その後、https://dev-123456.okta.com
のような名前の独自のOktaドメインを取得します。
Oktaの設定を使うためにsrc/main/resources/config/application.yml
を変更します。ヒント:{yourOktaDomain}
をあなたの組織の名前に置き換えてください(例:dev-123456.okta.com
)。
security:
oauth2:
client:
provider:
oidc:
issuer-uri: https://{yourOktaDomain}/oauth2/default
registration:
oidc:
client-id: {client-id}
client-secret: {client-secret}
scope: openid,profile,email
OktaでOIDCアプリを作成し、{client-id}
と{client-secret}
を取得します。これを行うには、Okta Developerアカウントにログインし、Applications > Applications > Add Application > Create New Appに移動します。Web, OpenID Connectを選択し、Createをクリックします。アプリに覚えやすい名前を 付け、ログインリダイレクトURIとしてhttp://localhost:8080/login/oauth2/code/oidc
を指定します。ログアウトリダイレクトURIとしてhttp://localhost:8080
を追加し、Saveをクリックします。クライアントIDとシークレットをapplication.yml
ファイルにコピーします。
ROLE_ADMIN
およびROLE_USER
グループを作成し(Directory > Groups > Add Group)、それらにユーザーを追加します。サインアップしたアカウントを使用するか、新しいユーザーを作成します(Directory > People > Add Person)。Security > API > Authorization Serversに移動し、default
サーバーをクリックします。Claimsタブをクリックし、Add Claimをクリックします。groups
という名前を付けて、IDトークンに含めます。値のタイプをGroups
に設定し、フィルタを.*
の正規表現に設定します。Createをクリックします。
これらを変更した後、問題なく使用できるはずです! もし問題があればStack Overflowに投稿してください。質問には必ず"jhipster"と"okta"のタグを付けてください。
e2eテストの実行時にOktaを使用するには、環境変数を設定できます。
export CYPRESS_E2E_USERNAME=<your-username>
export CYPRESS_E2E_PASSWORD=<your-password>
Protractorを使用している場合は、CYPRESS_
プレフィックスを削除してください。
環境変数の使用
環境変数を使用してデフォルトの上書もできます。次に例を示します。
export SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI="https://{yourOktaDomain}/oauth2/default"
export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID="{client-id}"
export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET="{client-secret}"
これを~/.okta.env
ファイルに入れてsource ~/.okta.env
を実行すると、KeycloakをOktaでオーバーライドできます。
次に、Herokuにデプロイするときにこれらのプロパティを設定できます。
heroku config:set \
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI="$SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI" \
SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID="$SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID" \
SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET="$SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET"
Oktaでモバイル用のネイティブアプリを作成する
JHipsterのIonicまたはReact NativeのBlueprintを使用してモバイルアプリを開発している場合、OIDCを使用しているなら、Oktaでネイティブアプリを作成することになる可能性があります。
Okta CLIを使用してokta apps create
を実行します。デフォルトのアプリ名を選択するか、必要に応じて変更します。Nativeを選択してEnterを押します。
- Ionic:リダイレクトURIを
[http://localhost:8100/callback,dev.localhost.ionic:/callback]
に変更し、ログアウトリダイレクトURIを[http://localhost:8100/logout,dev.localhost.ionic:/logout]
に変更します。 - React Native:リダイレクトURIには
[http://localhost:19006/,https://auth.expo.io/@<username>/<appname>]
を使用してください。
注意: dev.localhost.ionic
はデフォルトのスキームですが、com.okta.dev-133337
(ここでdev-133337.okta.com
はあなたのOkta OrgのURLです)のような、よりトラディショナルなものも使用できます。これを変更する場合は、Ionicアプリのsrc/environments/environment.ts
のscheme
を必ず更新してください。
Okta CLIは、Okta OrgにOIDC Appを作成します。指定したリダイレクトURIを追加し、Everyoneグループへのアクセスを許可します。
Okta application configuration:
Issuer: https://dev-133337.okta.com/oauth2/default
Client ID: 0oab8eb55Kb9jdMIr5d6
注意:Okta管理コンソールを使用してもアプリを作成できます。詳細については、ネイティブアプリの作成を参照してください。
Ionicアプリをアップデートする
ionic/src/environments/environment.ts
を開き、NativeアプリからクライアントIDを追加します。server_host
の値はJHipsterアプリ(/api/auth-info
)から検索されますが、フォールバック(代替)値として定義できます。以下は例です。
oidcConfig: {
client_id: '<native-client-id>',
server_host: 'https://<your-okta-domain>/oauth2/default',
...
}
また、http://localhost:8100
用にトラステッド・オリジンを追加する必要があります。Okta Admin Consoleで、Security > API > Trusted Origins > Add Originに移動します。次の値を使用します。
- Name:
http://localhost:8100
- Origin URL:
http://localhost:8100
- Type: CORS and Redirectの両方をチェック
Saveをクリックします。
Ionicアプリを再起動して、Oktaでログインします!
Reactネイティブアプリのアップデート
クライアントIDをapp/config/app-config.js
にコピーします。
Ionicアプリを再起動して、Oktaでロ グインします!
OpenID Connectチュートリアル
JHipster 5とOIDC with Oktaの詳細については、JHipsterでOpenID Connectサポートを使用するを参照してください。
JHipster 6を使用している場合は、Java 12とJHipster 6によるJavaの改善、高速化、軽量化を参照してください。JHipster 6でマイクロサービスを使用している場合は、Spring Cloud ConfigとJHipsterを使ったJavaマイクロサービスを参照してください。
JHipster 7については、Spring BootとJHipsterを使ったリアクティブJavaマイクロサービスを参照してください。
Okta開発者ブログには、MicronautとQuarkusへの ❤️ も掲載されています。
HTTPS
HTTPSの使用を強制するには、次の設定をSecurityConfiguration.java
に追加します。
// Spring MVC
http.requiresChannel(channel -> channel
.requestMatchers(r -> r.getHeader("X-Forwarded-Proto") != null).requiresSecure());
// WebFlux
http.redirectToHttps(redirect -> redirect
.httpsRedirectWhen(e -> e.getRequest().getHeaders().containsKey("X-Forwarded-Proto")));
詳細については、Spring SecurityのServletとWebFluxのドキュメントを参照してください。
これはHerokuとGoogle Cloudでテストされ、動作することが確認されています。Herokuでのプロダクションのヒントについては、Herokuでの運用のためのSpring Bootアプリの準備を参照してください。
実装詳細の漏洩
すべての失敗/例外は、問題データ構造にマップされ、クライアントに返されます。
{
"type": "https://www.jhipster.tech/problem/problem-with-message",
"title": "Service Unavailable",
"status": 503,
"detail": "Database not reachable"
}
JHipsterはデフォルトではスタックトレースを含んでいませんが、detail
には例外のmessage
が含まれ、APIを介して公開されたくない技術的詳細
が表れてしまう可能性があります。
{
"type": "https://www.jhipster.tech/problem/problem-with-message",
"title": "Bad Request",
"status": 400,
"detail": "JSON parse error: Cannot deserialize instance of
`java.util.LinkedHashMap<java.lang.Object,java.lang.Object>` out of VALUE_NUMBER_INT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap<java.lang.Object,java.lang.Object>`
out of VALUE_NUMBER_INT token\n at [Source: (PushbackInputStream); line: 1, column: 1]"
}
これを防ぐために、JHipsterは、実装の詳細の漏れを軽減するための専用のメカニズムを提供します。
- 既知の例外をチェックし、メッセージを一般的なメッセージに置き換えます(例:
Unable to convert http message
)。 - メッセージに潜在的なパッケージ名(例:
java.
または.org
)が含まれているかどうかをチェックし、メッセージを一般的なもの(例:Unexpected runtime exception
)で置き換えます。
ログには依然として詳細な例外が含まれているため、外部からの攻撃者がAPIを悪用して貴重な技術的詳細を得ることができない間に、 実際の問題を特定できます(訳注:miusing→misusing)。
ロジックを変更する必要がある場合(メッセージに技術的な詳細が含まれていても検出されなかった場合など)は、
必要なロジックをExceptionTranslator.java
のprepare
メソッドに追加することで変更できます。