追記 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.
の中で↑のようなやつを少し改変しようと思います。
準備
- 適当にGithubからサンプルをCloneして、Eclipseあたりに放り込んでください。
- 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;
参考
世の中には大体やろうとしていることの先行者がいるわけでして、以下のあたりをだいぶ参考に動きを把握させてもらいました。
AzureRequestEnhancer とかは以下の部分からのコピペ&改変です。
あとは、
などです。