Azure Active Directoryで認証するJavaアプリケーションが作れるライブラリ「Spring Cloud Azure」を紹介

はじめに

Azureでは「Azure Active Directory (Azure AD) 」とJavaライブラリ「Spring Cloud Azure」を使うことで、Azure ADに登録されているユーザで認証を行うWEBアプリケーションの作成を行うことができます。

この記事では「Spring Cloud Azure」について紹介します。

Spring Cloud Azure

Springは、VMwareが開発したJava言語のWEBアプリケーション開発に必要な機能を提供するフレームワークです。

Spring Cloud Azureは、AzureのサービスとSpringのシームレスな統合を提供するオープンソースプロジェクトです。

https://microsoft.github.io/spring-cloud-azure/current/reference/html/index.html#spring-security-support

https://docs.microsoft.com/ja-jp/azure/active-directory/develop/quickstart-register-app

Spring Cloud AzureでのAD認証

Spring FramworkにはSpring Securityというログイン認証やCSRF対策をフレームワークが含まれています。

Spring Cloud AzureではAzure用に拡張されたSpring SecutiryでOAuth2.0での認証を行います。

以下にAD認証のシーケンスを記載しています。

https://microsoft.github.io/spring-cloud-azure/current/reference/html/index.html#spring-security-support

https://spring.pleiades.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/builders/HttpSecurity.html

Azure ADへのアプリケーション登録

WEBアプリケーションでAzure ADでの認証を行うには、AzureポータルでAzure ADに対象のアプリケーションの登録と、クライアントシークレットの作成を行います。

アプリケーション登録

Azure ADメニューからAzure ADを選択します。

  • 表示名 : 任意のアプリケーション名を入力
  • サポートされているアカウントの種類 : 今回は任意の組織ディレクトリ内のアカウントを選択します
  • リダイレクトURI : 省略可能。省略した場合は https://WEBアプリホスト名/login/oauth2/code/azure になります

クライアントシークレット登録

Azure ADに登録したアプリの「証明書とシークレット」からクライアントシークレットを追加します。

  • 説明 : 任意
  • 有効期間 : 今回は2年を設定します

作成されたクライアントシークレットの値を控えます。(※再表示はできません) その後、クライアントID(アプリケーションID)および、テナントIDを確認し、控えます。

https://docs.microsoft.com/ja-jp/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory

https://tech-lab.sios.jp/archives/23371

Javaアプリケーションを作成

Spring Initializrを使ってJava アプリを作成します。

  • https://start.spring.io/ を参照します。

  • Java で Maven プロジェクトを生成することを指定し、アプリケーションの [グループ] と [アーティファクト] に名前を入力します。

  • Spring Web、Azure Active Directory、OAuth2 Client の依存関係を追加します。

  • ページの下部にある GENERATE ボタンを選択します。

  • メッセージが表示されたら、ローカル コンピューター上のパスにプロジェクトをダウンロードします。

  • src/main/resources のapplication.propertiesをapplication.ymlに変更し、以下の内容を設定します。I

Spring Cloud Azureでは、application.ymlを設定するだけで、ADでの認証ができるようになります。

https://microsoft.github.io/spring-cloud-azure/current/reference/html/appendix.html#_azure_app_configuration_proeprties

cloud:
  azure:
    active-directory:
      enabled: true
      profile:
        tenant-id: ${AZURE_TENANT_ID:控えたテナントIDを入力}
     credential:
        client-id: ${AZURE_CLIENT_ID:控えたクライアントIDを入力}
        client-secret: ${AZURE_CLIENT_SECRET:控えたクライアントシークレットを入力}
      redirect-uri-template: ${AZURE_REDIRECTI_URL:AzureADに設定したリダイレクトURLを入力}
  • アプリケーションの Java ソース フォルダー内に controller という名前のフォルダーを作成します。 例: src/main/java/com/wingtiptoys/security/controller。

  • controller フォルダーに “HelloController.java” という名前の新しい Java ファイルを作成し、テキスト エディターで開きます。

  • 次のコードを入力し、ファイルを保存して閉じます。

package com.wingtiptoys.security;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.security.access.prepost.PreAuthorize;

@RestController
public class HelloController {
     @GetMapping("Admin")
     @ResponseBody
     @PreAuthorize("hasAuthority('APPROLE_Admin')")
     public String Admin() {
         return "Admin message";
     }
}
  • 上記のコードをビルドして、実行します

  • http://localhost:8080/Admin にアクセスするとMSログイン画面が表示されるので、ログインします

  • ログイン後、“Admin message"が表示されるようになります。

アクセス制御をカスタマイズする場合

単純にAD認証をするだけであれば、application.ymlを設定するだけで可能ですが、 ロードバランサーからWEBアプリのヘルスチェックを行う場合など、ロードバランサーからのリクエスト時はAD認証をスキップするなど、アクセス制御をカスタマイズした場合もございます。

以下のようにアクセス制御の設定をカスタマイズする場合はAadWebSecurityConfigurerAdapterを継承したクラスを作成します。

http://localhost:8080/skip へのリクエスト時は認証不要でWEBページを表示することができます。


    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class AadOAuth2LoginSecurityConfig extends AadWebSecurityConfigurerAdapter {

        /**
         * Add configuration logic as needed.
         */
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            super.configure(http);
            http.authorizeRequests()
                    .anyMatchers("/skip").permitAll() // /skipへのアクセスは認証なしでアクセス可能
                    .anyRequest().authenticated() // 認証済みのユーザならどのURLでもアクセス可能
                    .and().csrf().disable(); // CSRFを無効に設定
            // Do some custom configuration
        }
    }

https://stackoverflow.com/questions/55303851/why-i-recieve-invalid-csrf-token

https://stackoverflow.com/questions/73191248/ad-authentication-in-azure-spring-cloud-causes-invalid-csrf-token-found

https://baubaubau.hatenablog.com/entry/2020/11/23/205726

https://stackoverflow.com/questions/50908023/using-spring-security-oauth-using-a-custom-oauth-provider-i-get-authorization

https://stackoverflow.com/questions/58921642/how-to-set-redirect-uri-for-spring-boot-app-on-app-service-using-azure-ad

https://stackoverflow.com/questions/73118442/how-do-i-get-the-authentication-url-and-user-id-using-spring-cloud-azure-starter

おわりに

この記事では「Spring Cloud Azure」について紹介しました。
Spring Cloud Azureを使うことによって、ほとんどコードを書かずにADでの認証を実現することができるようになります。
本記事がAzureでWEBアプリケーションを作成するエンジニアの参考になれば、幸いです。 I