Azureの小ネタ (改)

~Azureネタを中心に、色々とその他の技術的なことなどを~

Azure Active Directory で Spring Boot and OAuth2

追記 2017/07/12

少しきれいにしたサンプルを以下に置いてあります。

github.com

Sprint Boot and OAuth2 ということで、以下にチュートリアルがあったりするわけですが、チュートリアルには、FaceBookとGithubの例が載っていたので、ふと思い立ってAzure Active Directoryでも出来るのか試してみました。結論からいうとできたのですが、全てを理解してやっているわけではないのでご注意を。もっとスマートな方法があるのではないかと思ってます。

spring.io

チュートリアル内にはいくつかサンプルがありますが、基本同じ様なことをちょっとづつ変えて試すような流れになっているぽいです。

click: adds an explicit link that the user has to click to login.

の中で↑のようなやつを少し改変しようと思います。

準備

  1. 適当にGithubからサンプルをCloneして、Eclipseあたりに放り込んでください。
  2. Azure Active Directory で アプリの登録し、テナントID、クライアントID、クライアントシークレットを入手しておきます。

application.yaml

クライアントIDとかクライアントシークレットとか、認証のURIとかはapplication.yamlに記述します。 accessTokenUriとかには、TenantIdを埋め込んでおいてください。最後のuserInfoUriですが、最終的にフレームワーク側が、このURIをアクセスしてユーザ情報を引っ張ってくるみたいですので、自身の情報が取得できURIを設定しておきます。

security:
  oauth2:
    client:
      clientId: <<your client id>>
      clientSecret: <<your client secret>>
      accessTokenUri: https://login.microsoftonline.com/<<tenantId>>/oauth2/token
      userAuthorizationUri: https://login.microsoftonline.com/<<tenantId>>/oauth2/authorize
      clientAuthenticationScheme: form
      scope: openid
    resource:
      userInfoUri: https://graph.windows.net/me?api-version=1.6

このままでも実行してアクセスするとLogin画面にリダイレクトされて認証のことろまで進みますが、エラーがでてしまいます。

Enhancer

POSTするときに、一部情報が足りないようです。RequestEnhancer を実装して新しいクラスを作成し、

resource : https://graph.windows.net/

の情報が付加されるようにしておきます。これは、Graph API というリソースにアクセスしまうというものです。

package com.example;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.RequestEnhancer;
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;

@Component
public class AzureRequestEnhancerCustomizer {

    @Autowired
    private OAuth2RestTemplate userInfoRestTemplate;

    @PostConstruct
    public void testWiring() {
        AuthorizationCodeAccessTokenProvider authorizationCodeAccessTokenProvider = new AuthorizationCodeAccessTokenProvider();
        authorizationCodeAccessTokenProvider.setTokenRequestEnhancer(new AzureRequestEnhancer());
        userInfoRestTemplate.setAccessTokenProvider(authorizationCodeAccessTokenProvider);
    }
}

@Component
class AzureRequestEnhancer implements RequestEnhancer {

    public AzureRequestEnhancer() {
    }

    @Override
    public void enhance(AccessTokenRequest request, OAuth2ProtectedResourceDetails resource,
            MultiValueMap<String, String> form, HttpHeaders headers) {
        form.set("resource", "https://graph.windows.net");
    }
}

実行

実行してもそのままだと、名前が表示されません。とりえあず、

http://localhost:8080/user

をたたくと、JSONが返ってきますので、どんな情報が返ってくるか確認できるでしょう。

index.html を以下のように編集しておくと名前がでるかもしれません。

self.user = data.userAuthentication.details.displayName;

f:id:StateMachine:20160419155327p:plain

参考

世の中には大体やろうとしていることの先行者がいるわけでして、以下のあたりをだいぶ参考に動きを把握させてもらいました。 AzureRequestEnhancer とかは以下の部分からのコピペ&改変です。

あとは、

などです。