Microsoft ID プラットフォ�`ム | 幄塀氏芙爺胆勧箪 Thu, 04 Jul 2024 12:45:36 +0000 ja hourly 1 https://wordpress.org/?v=6.9.10 Microsoft ID プラットフォ�`ムのアクセスト�`クンが ̄Invalid Signature ̄になる周 その2��Spring Security�� /blog/20240306-2276/ Wed, 06 Mar 2024 06:41:18 +0000 /?post_type=blog&p=2276 峻さん、こんにちは。室宝蝕�kグル�`プの稼-看噛温敬温稼です。書定は避定だったんですね。避定の訳周は富し鹸�jで、��4で護り俳れる定は避定、�擇靴�し100で護り俳れる定は峠定、�曚燭世�400で護り俳れる定は避定、になります。 […]

The post Microsoft ID プラットフォ�`ムのアクセスト�`クンが ̄Invalid Signature ̄になる周 その2��Spring Security�� first appeared on 幄塀氏芙爺胆勧箪.

]]>
峻さん、こんにちは。室宝蝕�kグル�`プの稼-看噛温敬温稼です。
書定は避定だったんですね。避定の訳周は富し鹸�jで、��4で護り俳れる定は避定、�擇靴�し100で護り俳れる定は峠定、�曚燭世�400で護り俳れる定は避定、になります。

云籾です。
念指、Microsoft ID プラットフォ�`ムから�k佩されたアクセスト�`クンをGraph API參翌のリソ�`スサ�`バ�`で旋喘しようとすると、 ̄Invalid Signature ̄として屎しく�I尖してくれない���}を函り貧げました。書指は、この���}に��する���I圭隈をSpring Securityで盾�Qしたいと房います。 ̄Invalid Signature ̄に�vする圻咀や尖喇などについては、念指を歌孚してください。

Graph API參翌のアクセスト�`クンを�k佩する圭隈

ゴ�`ル

盾�Qの圭��は念指と揖じです。1指朕のシ�`ケンスでは、OIDC�J�^��Graph API喘のアクセスト�`クンを�k佩して�Bいます。2指朕のシ�`ケンスでは、OAuth2.0により徭念で喘吭したリソ�`スサ�`バ�`へのアクセスト�`クンを�k佩して�Bいます。

或鴛禽遺範�^に駅勣な秤烏を譜協する

或鴛禽遺範�^で駅勣となる秤烏をapplication.propertiesに協吶します。

# 1指朕のシ�`ケンス��OIDC�J�^��Graph API喘アクセスト�`クン�k佩��
spring.security.oauth2.client.registration.microsoftonline.client-name=microsoftonline
spring.security.oauth2.client.registration.microsoftonline.client-id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
spring.security.oauth2.client.registration.microsoftonline.client-secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
spring.security.oauth2.client.registration.microsoftonline.provider=microsoftonline
spring.security.oauth2.client.registration.microsoftonline.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.microsoftonline.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.provider.microsoftonline.issuer-uri: https://login.microsoftonline.com/{tenantId}/v2.0
spring.security.oauth2.client.provider.microsoftonline.authorization-uri=https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize
spring.security.oauth2.client.provider.microsoftonline.token-uri=https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token
spring.security.oauth2.client.provider.microsoftonline.user-info-uri=https://graph.microsoft.com/oidc/userinfo
spring.security.oauth2.client.provider.microsoftonline.user-name-attribute=name

# 2指朕のシ�`ケンス��OAuth2.0によるアクセスト�`クン�k佩��
spring.security.oauth2.client.registration.microsoftonline4rsc.client-name=microsoftonline4rsc
spring.security.oauth2.client.registration.microsoftonline4rsc.client-id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
spring.security.oauth2.client.registration.microsoftonline4rsc.client-secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
spring.security.oauth2.client.registration.microsoftonline4rsc.provider=microsoftonline4rsc
spring.security.oauth2.client.registration.microsoftonline4rsc.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.microsoftonline4rsc.redirect-uri={baseUrl}/authorized/{registrationId}
spring.security.oauth2.client.registration.microsoftonline4rsc.scope=offline_access,yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/.default
spring.security.oauth2.client.provider.microsoftonline4rsc.issuer-uri: https://login.microsoftonline.com/{tenantId}/v2.0
spring.security.oauth2.client.provider.microsoftonline4rsc.authorization-uri=https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize
spring.security.oauth2.client.provider.microsoftonline4rsc.token-uri=https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token

1指朕のシ�`ケンスと、2指朕のシ�`ケンスに駅勣な秤�鵑鬚修譴召豢��xしています。�O協坪否に�vしては、Express + Passport�」�念?指、念指��と揖じなので�h苧を福待します。

協吶する縞のポイントとしては、プロパティ兆の{registrationId}何蛍を癖卷�筝�することです。箭えば1指朕シ�`ケンスの遺鉛庄艶稼岳鴛禽では、プロパティ兆がspring.security.oauth2.client.registration.microsoftonline.client-idとなっています。��して、2指朕シ�`ケンスの遺鉛庄艶稼岳鴛禽では、プロパティ兆がspring.security.oauth2.client.registration.microsoftonline4rsc.client-idです。この橿忖になっている倖侭により、それぞれを蛍けて協吶しています。

皆艶界顎姻庄岳霞酷庄鉛岳艶姻遺鞄温庄稼を伏撹する

參和は、1指朕のシ�`ケンスと、2指朕のシ�`ケンスの�I圭を佩う皆艶界顎姻庄岳霞酷庄鉛岳艶姻遺鞄温庄稼を伏撹するコ�`ドです。

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  // 1指朕のシ�`ケンス��OIDC�J�^��Graph API喘アクセスト�`クン�k佩��
  http
    .authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
    .oauth2Login(oauth2 ->
      oauth2
        .loginPage(
          OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/microsoftonline"
        )
    );

  // 2指朕のシ�`ケンス��OAuth2.0によるアクセスト�`クン�k佩��
  http
    .oauth2Client(Customizer.withDefaults())
    .addFilterAfter(
      this.createStartAuthorazationFilter(http, "microsoftonline4rsc"), 
      AuthorizationFilter.class
    );

  return http.build();
}

1指朕のシ�`ケンスではoauth2.loginPage()にて、ログインに聞喘する譜協を峺協しています。枠ほど、application.propertiesに或鴛禽遺範�^および或粥顎岳鞄2.0で駅勣となる譜協として、microsoftonlineとmicrosoftonline4rscの2つを協吶しました。もし、oauth2.loginPage()を福待すると、皆沿姻庄稼乙皆艶界顎姻庄岳霞はどちらの譜協で範�^すれば措いのか登僅が竃栖ないため、參和の鮫中を燕幣してユ�`ザ�`に僉�kさせる強恬となります。書指はmicrosoftonlineで或鴛禽遺範�^したいので、oauth2.loginPage()で峺協しています。

2指朕のシ�`ケンスではhttp.oauth2Client()で或粥顎岳鞄2.0を佩うように峺協しています。http.oauth2Client()もhttp.oauth2Login()と揖��に、/oauth2/authorization/{registrationId}へのリダイレクトをトリガ�`にシ�`ケンスが蝕兵されます。http.oauth2Login()の�袁犬紛�恬については、參念��墮した仝Spring Security の児云とOIDC�J�^�rの�嘛�々を歌孚ください。

2指朕シ�`ケンスのregistrationIdはmicrosoftonline4rscですので、2指朕のシ�`ケンスを蝕兵するには、/oauth2/authorization/microsoftonline4rscへリダイレクトする駅勣があります。このリダイレクトする�I尖は徭念で�g廾する駅勣があります。http.addFilterAfter()にて、/oauth2/authorization/microsoftonline4rscへリダイレクトするフィルタを、AuthorizationFilterの朔ろに弖紗しています。

2指朕のシ�`ケンスを蝕兵するフィルタ

2指朕のシ�`ケンスを蝕兵するためのフィルタを�g廾します。

private Filter createStartAuthorazationFilter(HttpSecurity http, String registrationId) {
  return new OncePerRequestFilter() {
    @Override
    protected void doFilterInternal(
      HttpServletRequest request,
      HttpServletResponse response,
      FilterChain filterChain
    ) throws ServletException, IOException {
      Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

      // �J�^が頼阻したのか倦か
      // �J�^が隆頼阻の��栽、`authentication`のクラスは `AnonymousAuthenticationToken` となります。
      // �J�^が頼阻した��栽は、`OAuth2AuthenticationToken`になります。
      // クラスの�`いで�J�^が頼阻したのか倦かを登僅しています。
      if (authentication instanceof OAuth2AuthenticationToken) {

        // �J辛�gみのクライアントを函誼します。
        // もし、函誼できない��栽(authorizedClient == null)、まだアクセスト�`クンが函誼竃栖ていません。
        OAuth2AuthorizedClient authorizedClient = clientService.loadAuthorizedClient(
          registrationId,
          authentication.getName()
        );

        if (authorizedClient == null) {
          // `/oauth2/authorization/{registrationId}`へリダイレクトして、�J辛プロセスが畠て頼阻した瘁、
          // 圷のペ�`ジ�╂���`/secure/user��`のパスにリダイレクトしてもらう駅勣があります。
          // 參和のコ�`ドにより、Spring Securityに��して、圷のペ�`ジへのリクエスト秤�鵑魃3屬靴討�くことが竃栖ます。
          RequestCache requestCache = http.getSharedObject(RequestCache.class);
          requestCache.saveRequest(request, response);

          // リダイレクト
          AuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint(
            OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/" + registrationId
          );
          entryPoint.commence(request, response, null);
        } else {
          filterChain.doFilter(request, response);
        }
      } else {
        filterChain.doFilter(request, response);
      }
    }
  };
}

フィルタでは、範�^�gみ、かつ、徭念で喘吭したリソ�`スサ�`バ�`へのアクセスト�`クンが隆�k佩の魁栽、/oauth2/authorization/microsoftonline4rscへリダイレクトさせています。リダイレクトする縞は、リクエスト坪否を匯扮隠贋してから、リダイレクトするようにしています。

アクセスト�`クンを函誼する圭隈

アクセスト�`クンを函誼するコ�`ドです。

@Service
public class OAuth2TokenService {

  @Autowired
  private OAuth2AuthorizedClientService clientService;

  public OAuth2AccessToken getAccessToken() {
    return getAccessToken(null);
  }

  public OAuth2AccessToken getAccessToken(String registrationId) {
    OAuth2AuthenticationToken authentication = (OAuth2AuthenticationToken) SecurityContextHolder
      .getContext()
      .getAuthentication();

    OAuth2AuthorizedClient authorizedClient = clientService.loadAuthorizedClient(
      registrationId == null ? authentication.getAuthorizedClientRegistrationId() : registrationId,
      authentication.getName()
    );

    return authorizedClient.getAccessToken();
  }
}

clientService.loadAuthorizedClient(...)の及1哈方にregistrationIdを峺協することで、そのregistrationIdに��鬉靴織▲�セスト�`クンを函誼することが竃栖ます。なお、authentication.getAuthorizedClientRegistrationId()は範�^で聞喘されたregistrationIdを卦抜します。書指の箭で冱うとmicrosoftonlineになります。

おわりに

1指朕のシ�`ケンスから、2指朕のシ�`ケンスを�_兵させる圭隈が��つからず、寄蛍、逗�蕕靴泙靴拭�Spring Security�箸任Δ泙い海箸笋辰討�れないか�{べたのですが、いい圭隈が��つからず、�Y蕉はフィルタを弖紗する圭隈で鯛ち彭きました。ゴ�`ルに���dしたようなシ�`ケンス�蹐�ないと、Spring Securityのコ�`ドを�iみ盾くのは�yしいですね。

ではまた。

The post Microsoft ID プラットフォ�`ムのアクセスト�`クンが ̄Invalid Signature ̄になる周 その2��Spring Security�� first appeared on 幄塀氏芙爺胆勧箪.

]]>
Microsoft ID プラットフォ�`ムのアクセスト�`クンが”Invalid Signature”になる周 その1��Express + Passport�� /blog/20240228-2253/ Wed, 28 Feb 2024 02:27:58 +0000 /?post_type=blog&p=2253 峻さん、こんにちは。室宝蝕�kグル�`プの稼-看噛温敬温稼です。タツノオトシゴの嶼寂に、タツノイトコとタツノハトコがいます。 云籾です。Microsoft ID プラットフォ�`ムから�k佩されたアクセスト�`クンをGraph A […]

The post Microsoft ID プラットフォ�`ムのアクセスト�`クンが ̄Invalid Signature ̄になる周 その1��Express + Passport�� first appeared on 幄塀氏芙爺胆勧箪.

]]>
峻さん、こんにちは。室宝蝕�kグル�`プの稼-看噛温敬温稼です。
タツノオトシゴの嶼寂に、タツノイトコとタツノハトコがいます。

云籾です。
Microsoft ID プラットフォ�`ムから�k佩されたアクセスト�`クンをGraph API參翌のリソ�`スサ�`バ�`で旋喘しようとすると、”Invalid Signature”として屎しく�I尖してくれません。でアクセスト�`クンを盾裂しようとすると、揖��に”Invalid Signature”が燕幣されてデジタル俸兆の�編^に払�,靴討い襪海箸�蛍かります。書指は”Invalid Signature”の尖喇と���I圭隈についてのお��です。

Invalid Signature

採絞、デジタル俸兆の�編^に払移するのか��

Microsoft ID プラットフォ�`ムから�k佩されたアクセスト�`クンを聞って、Graph APIで秤�鵑鯣ゝ辰垢襪海箸漏�栖ます。しかし、Graph API參翌のリソ�`スサ�`バ�`に��してアクセスト�`クンを聞喘すると、デジタル俸兆の�編^に払�,靴討靴泙い泙后�この並�鵑砲弔い討�Azure AD GitHubのに�h苧がありました。

�Y��としては、Graph API喘に�k佩されたアクセスト�`クンには、Microsoft鏡徭のデジタル俸兆が仏されているため、そのアクセスト�`クンはGraph API參翌のリソ�`スサ�`バ�`では聞えません。JWTのデジタル俸兆はJWS()で�カ┐気譴討�り、Graph API喘に�k佩されたアクセスト�`クンは、その�カ┐�ら翌れたデジタル俸兆をしているため、��畜にはJWTではないことになります。

それは或粥顎岳鞄2.0の号鯉として諒籾ないの��

Graph API喘に�k佩されたアクセスト�`クンは、��畜にはJWTではありません。これはOAuth2.0の�ク颪箸靴����}ないのでしょうか�心陲┐蓮����}ありません々です。OAuth2.0はト�`クンの�k佩と聞喘に�vする�J辛プロトコルです。ト�`クンの碧��に�vしては�g廾卆贋になります。なので、アクセスト�`クンがJWT參翌の�eの採かでも、リソ�`スサ�`バ�`�箸任修離肌`クンの嗤�塵圓��編^竃栖れば、OAuth2.0の�ク馼蓮����}ないことになります。

とはいえ、でアクセスト�`クンの嶄附が需れてしまうなど、干安意であるかのように列盾させてしまったことは賦し�Uないと、で峰べられています。

Graph API參翌のアクセスト�`クンを�k佩する圭隈

ゴ�`ル

Graph API參翌のリソ�`スサ�`バ�`で旋喘辛嬬な、JWT侘塀のアクセスト�`クンを函誼したい��栽は、User.ReadなどのGraph APIに�vするアクセス�慙泙�scopeに峺協しなければ措いとのことです。なんともエンジニア日かせな碧��ですが、碧圭がありません。シ�`ケンスを2指に蛍けて、アクセスト�`クンを2つ�k佩して�Bうようにします。

1指朕のシ�`ケンスはOIDC�J�^を佩いつつ、Graph API喘のアクセスト�`クンを�k佩して�Bいます。これは念指と揖じ坪否です。2指朕のシ�`ケンスでは、或粥顎岳鞄2.0により徭念で喘吭したリソ�`スサ�`バ�`へのアクセスト�`クンを�k佩して�Bいます。1指朕のシ�`ケンスは念指を歌孚してください。書指は2指朕のシ�`ケンスについて峰べます。

リソ�`スサ�`バ�`喘のアプリを鞠�hする

からリソ�`スサ�`バ�`喘のアプリを鞠�hします。アプリを鞠�hした朔、仝粥永鴛の巷蝕々により、スコ�`プを弖紗します。

クライアント迦のアクセス俯辛にリソ�`スサ�`バ�`を弖紗する

クライアント迦のアクセス俯辛に、枠ほど鞠�hしたリソ�`スサ�`バ�`を弖紗します。これで�扮犬詫蠢砲任后�

或鴛禽遺喘の兜豚譜協を佩う

或鴛禽遺範�^に駅勣な譜協を永温壊壊沿看姻岳に局します。

  // リソ�`スサ�`バ�`へのアクセスト�`クンを函誼するための�O協
  const oauth2Strategy = new OAuth2Strategy(
    {
      passReqToCallback: true,
      authorizationURL: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`,
      tokenURL: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
      clientID: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      clientSecret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      scope: ["offline_access", "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/.default"],
      callbackURL: "/cb2", // callbackURL
    },
    function (
      req: Request,
      accessToken: string,
      refreshToken: string,
      profile: any,
      done: VerifyCallback
    ) {
      // �編^
      return done(null, {});
    }
  );

或鴛禽遺ではなく、或粥顎岳鞄2.0でト�`クンを�k佩して�Bいますので、聞喘するクラスはOAuth2Strategyになります。1指朕のシ�`ケンスと曳べて、局す譜協坪否はほぼ揖じです。この嶄で廣朕すべきはscopeで、yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/.defaultを峺協しています。yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyyはリソ�`スサ�`バ�`のクライアント鴛禽です。yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/.defaultを峺協することにより、ユ�`ザ�`にリソ�`スサ�`バ�`への範辛を箔めると揖扮に、リソ�`スサ�`バ�`へアクセス辛嬬なアクセスト�`クンが�k佩されます。

温顎岳鞄艶稼岳庄界温岳艶を柵び竃す

リクエストを鞭けて、永温壊壊沿看姻岳の温顎岳鞄艶稼岳庄界温岳艶()を�I尖します。4つ協吶しています。

  // authenticate (1指朕)
  // ユ�`ザ�`の�J�^と、Graph APIへのアクセスト�`クンを函誼します。
  server.get("/login", passport.authenticate("openidconnect"));

  // authenticate (2指朕)
  server.get(
    "/cb",
    passport.authenticate("openidconnect", {
      failureRedirect: "/",
      failureMessage: true,
    }),
    async function (req, res, err) {
      // `/gettoken`へリダイレクトする
      // ★哈き�Aき、リソ�`スサ�`バ�`へのアクセスト�`クンを函誼するシ�`ケンスを佩います。
      res.redirect("/gettoken");
    }
  );

  // authenticate (3指朕)
  // リソ�`スサ�`バ�`へのアクセスト�`クンを函誼します。
  server.get("/gettoken", passport.authenticate("oauth2"));

  // authenticate (4指朕)
  server.get(
    "/cb2",
    passport.authenticate("oauth2", {
      failureRedirect: "/",
      failureMessage: true,
    }),
    // post-request
    async function (req, res, err) {
      // `/user`へリダイレクトする
      res.redirect("/user");
    }
  );

authenticate (2指朕)では、/gettokenにリダイレクトして、そのままリソ�`スサ�`バ�`喘のアクセスト�`クンを函誼するようにしています。貧芝は�h苧喘に噫柴なコ�`ドを福いていますが、�g縞は遺皆檎酷��貨に壊岳温岳艶を局して�編^するようにした圭が措いでしょう。

おわりに

或粥顎岳鞄2.0はト�`クンの�k佩と聞喘のプロセスであり、ト�`クンの碧��を根め、謹くが�g廾卆贋もしくは桟廠卆贋となっています。揖じ或鴛禽遺範�^プロトコルだとしても、範�^児徒が離えば、聾かなところで碧��が呟なることが措く蛍かる並箭ですね。念指と揖じ急めの冱匐になりますが、範�^児徒のクセを屎しく尖盾しないといけませんね。

肝指はこの���}をSpring Securityでどう盾�Qするのかをテ�`マにしたいと房います。

ではまた。

The post Microsoft ID プラットフォ�`ムのアクセスト�`クンが ̄Invalid Signature ̄になる周 その1��Express + Passport�� first appeared on 幄塀氏芙爺胆勧箪.

]]>