Ein Artikel führt Sie durch den Autorisierungsvorgang in Spring Security

1. Autorisierung

Die sogenannte Autorisierung bedeutet, dass, wenn ein Benutzer auf eine bestimmte Ressource zugreifen möchte, geprüft werden muss, ob der Benutzer über eine solche Berechtigung verfügt. Wenn dies der Fall ist, darf er darauf zugreifen, wenn nicht, ist dies nicht zulässig.

Zweitens: Bereiten Sie sich darauf vor, Benutzer zu testen

Da wir noch keine Verbindung zur Datenbank hergestellt haben, ist der Testbenutzer weiterhin basierend auf dem Speicher konfiguriert.

Basierend auf den Benutzern des Speicherkonfigurationstests haben wir zwei Methoden: Die erste ist die Konfigurationsmethode, die wir in den vorherigen Artikeln dieser Serie wie folgt verwendet haben:

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

Dies ist eine Konfigurationsmethode.

Da Spring Security eine Vielzahl von Datenquellen wie Speicher, Datenbanken, LDAP usw. unterstützt, werden diese verschiedenen Datenquellen in einer gemeinsamen UserDetailServiceSchnittstelle gekapselt. Jedes Objekt, das diese Schnittstelle implementiert, kann als Authentifizierungsdatenquelle verwendet werden.

So können wir Umschreiben WebSecurityConfigurerAdapterder userDetailsServiceein Verfahren zum Bereitstellen UserDetailServiceBeispiel weiter angeordnet , um eine Vielzahl von Benutzern:

    @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;
    }

Drittens bereiten Sie sich darauf vor, die Schnittstelle zu testen

Der Testbenutzer ist bereit, und dann bereiten wir drei Testschnittstellen vor. wie folgt:

@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";
    }
}

Für diese drei Testschnittstellen sieht unser Plan folgendermaßen aus:

(1) Es /helloist eine Schnittstelle, auf die jeder zugreifen kann.
(2) Es /admin/helloist eine Schnittstelle, auf die nur eine Person mit einer Administratoridentität zugreifen kann.
(3) /user/helloEine Schnittstelle, auf die eine Person mit einer Benutzeridentität zugreifen kann.
(4) Alle Benutzer können auf Ressourcen zugreifen , der Administrator kann Zugriff

Beachten Sie, dass die vierte Spezifikation bedeutet, dass alle Personen mit Administratoridentität automatisch eine Benutzeridentität haben

Viertens Konfiguration

Als Nächstes konfigurieren wir die Berechtigungen zum Blockieren von Regeln. In der Spring Security- configure(HttpSecurity http)Methode lautet der Code wie folgt:

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

Für die Übereinstimmungsregeln verwenden wir hier Pfadanpassungssymbole im Ant-Stil. Pfadanpassungssymbole im Ameisenstil werden in der Spring-Familie häufig verwendet, und die Übereinstimmungsregeln sind auch sehr einfach:

Fügen Sie hier eine Bildbeschreibung ein
Die Bedeutung der obigen Konfiguration ist:

(1) Wenn die Anforderung ein Pfadformat erfüllt /admin/**, muss der Benutzer eine Administratorrolle haben.
(2) erfüllt, wenn die Anforderung ein Pfadformat /user/**ist, muss der Benutzer die Benutzerrolle haben.
(3) Auf die verbleibenden Anforderungspfade in anderen Formaten kann erst nach der Authentifizierung (Anmeldung) zugegriffen werden.

Beachten Sie, dass die Reihenfolge der drei im Code konfigurierten Regeln sehr wichtig ist. Ähnlich wie bei Shiro stimmt Spring Security beim Abgleich auch von oben nach unten überein. Nach dem Abgleich wird es nicht mehr übereinstimmen.Die Reihenfolge der Abfangregeln kann also nicht falsch geschrieben werden

Auf der anderen Seite, wenn Sie eine Anforderung erzwingen, die vor antMatchers gestellt wird, wie folgt:

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

Zu diesem Zeitpunkt, wenn das Projekt gestartet wird, wird ein Fehler gemeldet und es wird angezeigt, dass antMatchers nach anyRequest nicht hinzugefügt werden können:

Fügen Sie hier eine Bildbeschreibung ein
Dies ist semantisch gut verstanden, anyRequestandere Anforderungen sind bereits enthalten, und es macht keinen Sinn, wenn andere Anforderungen danach konfiguriert werden.

Semantisch verstanden anyRequestsollte es am Ende stehen und angeben, wie die verbleibenden Anforderungen zusätzlich zu den vorherigen Abfangregeln behandelt werden sollen.

In den Blockierungsregeln für Konfigurationsklassen sehen AbstractRequestMatcherRegistrywir folgenden Code (Abschnitt Quelle):

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));
 }
}

Anhand dieses Quellcodes können wir erkennen, dass vor Abfangregeln (einschließlich anyRequest selbst) zunächst ermittelt wird, ob anyRequest konfiguriert wurde. Wenn es konfiguriert ist, wird eine Ausnahme ausgelöst und das System kann nicht gestartet werden.

Jeder versteht also, warum anyRequest zuletzt gestellt werden muss

Fünftens, starten Sie den Test

Als nächstes starten wir das Projekt zum Testen.

Nachdem das Projekt erfolgreich gestartet wurde, melden wir uns zuerst als yolo an:

Fügen Sie hier eine Bildbeschreibung ein
Besuchen Sie nach erfolgreicher Anmeldung die drei Schnittstellen / hello, / admin / hello und / user / hello, darunter:

(1) /helloDa Sie nach dem Anmelden darauf zugreifen können, wird erfolgreich auf diese Schnittstelle zugegriffen.
(2) Die /admin/helloAdministratoridentität ist erforderlich, daher schlägt der Zugriff fehl.
(3) Die /user/helloBenutzeridentität ist erforderlich, damit der Zugriff erfolgreich ist.

Melden Sie sich auf die gleiche Weise bei nlcs an.

Sechs, Rollenvererbung

Wie bereits erwähnt, kann der Administrator auf alle Ressourcen zugreifen, auf die der Benutzer zugreifen kann. Offensichtlich verfügt unser aktueller Code noch nicht über eine solche Funktion.

Um alle Ressourcen zu implementieren, auf die der Benutzer zugreifen kann, kann der Administrator darauf zugreifen. Dazu gehört ein weiterer Wissenspunkt, der aufgerufen wirdRollenvererbung

Dies ist sehr nützlich in der tatsächlichen Entwicklung.

Die obere Ebene verfügt möglicherweise über alle Berechtigungen der unteren Ebene. Wenn die Rollenvererbung verwendet wird, ist diese Funktion sehr einfach zu implementieren. Sie müssen SecurityConfig nur den folgenden Code hinzufügen, um die Rollenvererbungsbeziehung zu konfigurieren:

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

Beachten Sie, dass Sie in der Konfiguration das Zeichenpräfix manuell hinzufügen müssen ROLE_. Die obige Konfiguration bedeutet ROLE_adminautomatisch ROLE_userBerechtigung.

Nachdem die Konfiguration abgeschlossen ist, starten Sie das Projekt neu. Dieses Mal haben wir festgestellt, dass yolo auch über /user/hellodiese Schnittstelle zugreifen kann

Fügen Sie hier eine Bildbeschreibung ein

Ich denke du magst

Origin blog.csdn.net/nanhuaibeian/article/details/108596231
Empfohlen
Rangfolge