記事では、Spring Securityの承認操作について説明しています

1.認可

いわゆる承認とは、ユーザーが特定のリソースにアクセスしたい場合に、ユーザーがそのような権限を持っているかどうかを確認する必要があることを意味します。権限がある場合は、アクセスが許可され、許可されていない場合は許可されません。

2、ユーザーをテストする準備をする

データベースにはまだ接続していないため、テストユーザーはメモリに基づいて構成されています。

メモリ構成テストのユーザーに基づいて、2つの方法があります。1つ目は、このシリーズの以前の記事で使用した構成方法です。

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        //在内存中进行配置
        auth.inMemoryAuthentication()
                .withUser("yolo")
                .password("123").roles("admin")
                .and()
                .withUser("nlcs")
                .password("123")
                .roles("user");
    }

これは設定方法です。

Spring Securityは、メモリ、データベース、LDAPなどのさまざまなデータソースをサポートしているため、これらのさまざまなデータソースは共通のUserDetailServiceインターフェイスにカプセル化され、このインターフェイスを実装するすべてのオブジェクトを認証データソースとして使用できます。

したがって、我々は書き換えることができるWebSecurityConfigurerAdapteruserDetailsServiceための方法を提供UserDetailServiceさらに、複数のユーザを配置例:

    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
    
    
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("yolo").password("123").roles("admin").build());
        manager.createUser(User.withUsername("nlcs").password("123").roles("user").build());
        return manager;
    }

3、インターフェースをテストする準備をする

テストユーザーの準備ができたら、3つのテストインターフェイスを準備します。次のように:

@RestController
public class HelloController {
    
    
    @GetMapping("/hello")
    public String hello() {
    
    
        return "hello";
    }

    @GetMapping("/admin/hello")
    public String admin() {
    
    
        return "admin";
    }

    @GetMapping("/user/hello")
    public String user() {
    
    
        return "user";
    }
}

これらの3つのテストインターフェイスの場合、計画は次のようになります。

(1)/hello誰でもアクセスできるインターフェースです
(2)/admin/hello管理者IDを持つ人だけがアクセスできるインターフェースです
(3)/user/helloユーザーIDを持つ人がアクセスできるインターフェース
(4)すべてのユーザーはリソースにアクセスでき、管理者はできますアクセス

4番目の仕様は、管理者IDを持つすべての人が自動的にユーザーIDを持つことを意味することに注意してください

4、構成

次に、ブロックルールのアクセス許可を構成します。SpringSecurityのconfigure(HttpSecurity http)メソッドでは、コードは次のようになります。

http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("admin")
        .antMatchers("/user/**").hasRole("user")
        .anyRequest().authenticated()
        .and()
        ...
        ...

ここでのマッチングルールには、Antスタイルのパスマッチングシンボルを使用します。Antスタイルのパスマッチングシンボルは、Springファミリで広く使用されており、そのマッチングルールも非常に単純です。

ここに画像の説明を挿入
上記の設定の意味は次のとおりです。

(1)リクエストがパス/admin/**形式を満たす場合、ユーザーは管理者の役割を持っている必要があります。
(2)リクエストがパス/user/**形式である場合、ユーザーはユーザーロールを持つ必要があります。
(3)その他の形式の残りの要求パスは、認証(ログイン)後にのみアクセスできます。

コードで構成された3つのルールの順序は非常に重要であることに注意してください。Shiroと同様に、Spring Securityも照合時に上から下に照合します。一度照合すると、照合は続行されません。したがって、遮断ルールの順序を間違って書くことはできません

一方、次のように、antMatchersの前にanyRequestを強制的に配置すると、

http.authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/admin/**").hasRole("admin")
        .antMatchers("/user/**").hasRole("user")
        .and()

この時点で、プロジェクトが開始されると、エラーが報告され、anyRequestの後にantMatchersを追加できないというプロンプトが表示されます。

ここに画像の説明を挿入
これは意味的によく理解されており、anyRequest他のリクエストはすでに含まれており、その後に他のリクエストが設定されても意味がありません。

意味的に理解さanyRequestれているため、最後に配置する必要があります。これは、以前のインターセプトルールに加えて、残りのリクエストを処理する方法を示します。

構成クラスのブロックルールAbstractRequestMatcherRegistryでは、次のようなコードが表示されます(ソースセクション)。

public abstract class AbstractRequestMatcherRegistry<C> {
    
    
 private boolean anyRequestConfigured = false;
 public C anyRequest() {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure anyRequest after itself");
  this.anyRequestConfigured = true;
  return configurer;
 }
 public C antMatchers(HttpMethod method, String... antPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.antMatchers(method, antPatterns));
 }
 public C antMatchers(String... antPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.antMatchers(antPatterns));
 }
 protected final List<MvcRequestMatcher> createMvcMatchers(HttpMethod method,
   String... mvcPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure mvcMatchers after anyRequest");
  return matchers;
 }
 public C regexMatchers(HttpMethod method, String... regexPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.regexMatchers(method, regexPatterns));
 }
 public C regexMatchers(String... regexPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.regexMatchers(regexPatterns));
 }
 public C requestMatchers(RequestMatcher... requestMatchers) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure requestMatchers after anyRequest");
  return chainRequestMatchers(Arrays.asList(requestMatchers));
 }
}

このソースコードから、インターセプトルール(anyRequest自体を含む)の前に、最初にanyRequestが構成されているかどうかが判断されます。構成されている場合、例外がスローされ、システムは起動に失敗します。

だから誰でもanyRequestを最後に配置しなければならない理由を理解しています

5、テストを開始

次に、テストのためにプロジェクトを開始します。

プロジェクトが正常に起動した後、最初にyoloとしてログインします。

ここに画像の説明を挿入
ログインに成功したら、3つのインターフェース/ hello、/ admin / hello、/ user / helloにそれぞれアクセスします。

(1)/helloログイン後もアクセスできるため、このインターフェースへのアクセスは成功しています。
(2)/admin/hello管理者IDが必要なので、アクセスは失敗します。
(3)/user/helloユーザーIDが必要なので、アクセスは成功します。

同じ方法でnlcsにログインします。

6、役割の継承

前述のように、ユーザーがアクセスできるすべてのリソースには管理者がアクセスできますが、明らかに、現在のコードにはまだそのような機能はありません。

ユーザーがアクセスできるすべてのリソースを実装するために、管理者はリソースにアクセスできます。これには、役割の継承

これは実際の開発で非常に役立ちます。

上位レベルには下位レベルのすべての権限が含まれる場合があります。ロールの継承が使用されている場合、この関数の実装は非常に簡単です。ロールの継承関係を構成するには、次のコードをSecurityConfigに追加するだけです。

@Bean
RoleHierarchy roleHierarchy() {
    
    
    RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
    hierarchy.setHierarchy("ROLE_admin > ROLE_user");
    return hierarchy;
}

構成では、手動で文字ROLE_プレフィックスを追加する必要があることに注意してください上記の設定は、ROLE_admin自動的にROLE_user権限を持つことを意味します

構成が完了したら、プロジェクトを再起動します。今度は、yoloも/user/helloこのインターフェイスにアクセスできることがわかりまし

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/nanhuaibeian/article/details/108596231