皆沿姻庄稼乙皆艶界顎姻庄岳霞の温顎岳鞄看姻庄噛艶堰岳岳沿檎艶援顎艶壊岳壊によるアクセス崙囮

峻さん、こんにちは。室宝蝕�kグル�`プの稼-看噛温敬温稼です。
2埖14晩はバレンタインですね。嶄忽?ベトナムでは槻來から溺來へプレゼントする晩だそうです。槻來の圭?は社怛サ�`ビスをしてみてはいかがでしょうか��

云籾です。
Spring Securityでは、http.authorizeHttpRequests(...)を聞って、パスへのアクセス崙囮を佩います。このアクセス崙囮はSpring Securityにおいては児�A嶄の児�Aであり、でも1ペ�`ジ来ごと聞って盾�hしています。書指はhttp.authorizeHttpRequests(...)について盾�hしつつ、念指の艶のやり圭を幣したいと房います。

アクセスを崙囮する

児云

箭えば參和のコ�`ドがあるとします。

http
  .authorizeHttpRequests(authorize -> authorize
    .requestMatchers("/secure/**").authenticated()
  )

requestMatchers("/secure/**").authenticated()は、リクエストの雨檎晦が/secure/**に乎輝する魁栽に範�^が駅勣であることを幣します。つまり、範�^していないユ�`ザ�`は/secure/**にアクセスすることが竃栖ません。コ�`ドの慕き圭としては、恷兜に崙囮���鵑離僖垢鰆原┐靴董△修離僖垢���してどう崙囮したいのかを峺協します。

この更撹を銭�Aして芝峰することも辛嬬です。

http
  .authorizeHttpRequests(authorize -> authorize
    .requestMatchers("/login_page").permitAll()
    .anyRequest().authenticated()
  )

貧芝の魁栽、ログイン鮫中である/login_pageへのアクセスは豊でも需れるようにし、それ參翌のアクセスは範�^が駅勣であることを幣します。

パスの峺協

パスの峺協でよく聞われるのはanyRequest()とrequestMatchers(...)です。anyRequest()は畠てのパスを峺協します。requestMatchers(...)は倖艶に峺協することも辛嬬ですし、ワイルドカ�`ドで峺協することも辛嬬です。

http
  .authorizeHttpRequests(authorize -> authorize
    .requestMatchers("/hoge", "/foo", "/bar").permitAll()   // ���eに峺協することが辛嬬
    .requestMatchers("/api/**").permitAll()                 // ワイルドカ�`ドで峺協することも辛嬬
    .requestMatchers(HttpMethod.GET).permitAll()            // HTTPメソッドで峺協することも辛嬬
    .anyRequest().permitAll()                               // anyRequest()は畠てのパスを峺協
  )

崙囮坪否

崙囮には參和があります。

メソッド�h苧
permitAll()このリクエストに範�^は音勣であり、豊でもアクセスが辛嬬です。
denyAll()このリクエストはいかなる彜趨でも俯辛されません。
authenticated()このリクエストでは範�^が駅勣になります。
範�^されない�泙蝓▲▲�セスすることは竃栖ません。
hasAuthority(…)このリクエストでは蒙協の�慙泙鰉个靴討い覬慴�があります。
�慙泙鰉个靴討い覆こ〆呂魯▲�セス竃栖ません。
hasRole(…)このリクエストでは蒙協のロ�`ルである駅勣があります。
呟なるロ�`ルである魁栽はアクセス竃栖ません。

一艶霞界鉛看温一のアクセスト�`クンで、ロ�`ルで崙囮する艶の圭隈

念指、Spring Security でアクセスト�`クンの�編^についてお��ししました。その嶄で、keycloakが�k佩するアクセスト�`クンには、そのユ�`ザ�`に嚥えられたロ�`ルが鯉�{されており、そのロ�`ルにより詳倦するかどうかを�編^するやり圭を�B初しました。書指はhttp.authorizeHttpRequests(...)を聞って崙囮するやり圭を府初します。

まずは皆艶界顎姻庄岳霞酷庄鉛岳艶姻遺鞄温庄稼の伏撹のところを俐屎します。

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    // アクセスト�`クン�編^
    http
      .authorizeHttpRequests(authorize -> authorize.anyRequest().hasRole("admin"))
      .oauth2ResourceServer(oauth2 ->
        oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(this.jwtAuthenticationConverter()))
      );
    return http.build();
  }

http.authorizeHttpRequests(...)のところでは、hasRole("admin")を峺協することにより、温糸馨庄稼ロ�`ルが原嚥されていることを駅勣とします。oauth2.jwt(...)では、念指は徭念で喘吭した干敬岳禽艶界看糸艶姻を局していましたが、書指は徭念で喘吭した干敬岳粥顎岳鞄艶稼岳庄界温岳庄看稼遺看稼厩艶姻岳艶姻を局します。

Spring Securityはユ�`ザ�`の�J�^秤�鵑筺▲▲�セスト�`クンの秤�鵑覆匹髻�SecurityContextに隠贋します。書指蒙に廣朕すべきところは、AuthenticationのAuthoritiesです。Authoritiesには範�^したユ�`ザ�`が侭嗤する�慙泙�隠贋されています。hasRole("admin")はこのAuthoritiesに”檎或晦掘喝温糸馨庄稼”が贋壓するかどうかをチェックします。

書指チェックするロ�`ルは、一艶霞界鉛看温一鏡徭のスキ�`マでアクセスト�`クンに鯉追されています。なので、アクセスト�`クンからロ�`ルを函誼してAuthoritiesに隠贋するための、干敬岳粥顎岳鞄艶稼岳庄界温岳庄看稼遺看稼厩艶姻岳艶姻を徭念で喘吭する駅勣があります。參和が干敬岳粥顎岳鞄艶稼岳庄界温岳庄看稼遺看稼厩艶姻岳艶姻を伏撹しているコ�`ドになります。

  private JwtAuthenticationConverter jwtAuthenticationConverter() {
    DelegatingJwtGrantedAuthoritiesConverter converter = new DelegatingJwtGrantedAuthoritiesConverter(
      new JwtGrantedAuthoritiesConverter(),
      new Converter<Jwt, Collection<GrantedAuthority>>() {
        @Override
        public Collection<GrantedAuthority> convert(Jwt source) {
          Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
          for (String role : getRoles(source)) {
            grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role));
          }
          return grantedAuthorities;
        }

        @SuppressWarnings("unchecked")
        private Collection<String> getRoles(Jwt jwt) {
          Map<String, Object> claims = jwt.getClaims();
          Map<String, Object> resourceAccess = (Map<String, Object>) claims.get("resource_access");
          Map<String, Object> clientts = (Map<String, Object>) resourceAccess.get(claims.get("azp"));
          return (Collection<String>) clientts.get("roles");
        }
      }
    );

    JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
    jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(converter);
    return jwtAuthenticationConverter;
  }

2佩朕から22佩朕までが、アクセスト�`クンの坪否から、Authoritiesに鯉追するGrantedAuthorityへ�篁擦垢襪燭瓩��I尖となります。3佩朕のJwtGrantedAuthoritiesConverterはデフォルト�I尖となる遺看稼厩艶姻岳艶姻です。4佩朕から21佩朕までが、アクセスト�`クンからロ�`ルを函誼してGrantedAuthorityに�篁擦垢��I尖となります。

DelegatingJwtGrantedAuthoritiesConverterは鹸方のJwtGrantedAuthoritiesConverterを崩ねるクラスです。24佩朕から26佩朕にて、JwtAuthenticationConverterに、DelegatingJwtGrantedAuthoritiesConverterを譜協して卦抜しています。

おわりに

hasAuthority(...)やhasRole(...)などでアクセス崙囮が竃栖るようになると、より聾かい崙囮が辛嬬になります。箭えば參和のようにすれば、リクエストが/api/admin/**の粥永鴛のみ、温糸馨庄稼ロ�`ルを駅勣とし、それ參翌の粥永鴛は温糸馨庄稼ロ�`ルなしでもアクセスすることが辛嬬となります。念指府初したやり圭と曳べると、より悲罷に崙囮できるようになります。

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    // アクセスト�`クン�編^
    http
      .authorizeHttpRequests(authorize -> authorize
        .requestMatchers("/api/admin/**").hasRole("admin"))
        .anyRequest().authenticated()
      .oauth2ResourceServer(oauth2 ->
        oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(this.jwtAuthenticationConverter()))
      );
    return http.build();
  }

ではまた。


Recommendおすすめブログ