Erläutern Sie die Grundlagen der Funktionsweise von Spring Security in einer kurzen Hello World
――Welche Klassen arbeiten zusammen und wie --Wie die Konfigurationsdatei zusammenhängt
Indem Sie lernen, wie Spring Security über Hello World funktioniert
--Schreiben Sie die Einstellungen in XML ―― Immerhin ist Java Config gleich
https://github.com/opengl-8080/spring-security-hello-world
spring-security.war
von [hier] herunter (https://github.com/opengl-8080/spring-security-hello-world/releases/tag/v1.0.0)spring-security.war
für Tomcat bereithttp: // localhost: 8080 / spring-security
Greifen Sie auf "http: // localhost: 8080 / spring-security" zu
Geben Sie "foo" in Benutzer, Passwort ein, um sich anzumelden
403 Fehler
Als nächstes melden Sie sich mit bar
an
Die Indexseite wird angezeigt.
Sie können sich abmelden, indem Sie auf die Schaltfläche Abmelden klicken.
Dateiorganisation
|-build.gradle :Gradle Build-Datei
|
`-src/main/webapp/
|
|-index.jsp :Indexseite
|
`-WEB-INF/
|
|-applicationContext.xml :Federkonfigurationsdatei
|
`-web.xml :Servlet-Konfigurationsdatei
build.gradle
apply plugin: 'war'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
compileJava.options.encoding = 'UTF-8'
repositories {
mavenCentral()
}
dependencies {
compile 'org.springframework.security:spring-security-web:4.2.1.RELEASE'
compile 'org.springframework.security:spring-security-config:4.2.1.RELEASE'
}
war.baseName = 'spring-security'
task wrapper(type: Wrapper) {
gradleVersion = '3.2.1'
}
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>
Hello Spring Security!!
</title>
</head>
<body>
<h1>
Hello Spring Security!!
</h1>
<form action="logout" method="post">
<input type="submit"
value="logout" />
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
</body>
</html>
_csrf
ist festgelegt, da es standardmäßig aktiviert ist. Da es jedoch in der folgenden Erläuterung nicht angezeigt wird, wird eine ausführliche Erläuterung weggelassen.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>
springSecurityFilterChain
</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>
springSecurityFilterChain
</filter-name>
<url-pattern>
/*
</url-pattern>
</filter-mapping>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<sec:http>
<sec:intercept-url
pattern="/login"
access="permitAll" />
<sec:intercept-url
pattern="/**"
access="isAuthenticated() and hasAuthority('BAR')" />
<sec:form-login />
<sec:logout />
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="foo"
password="foo"
authorities="" />
<sec:user name="bar"
password="bar"
authorities="BAR" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
</beans>
web.xml
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
ContextLoaderListener
WEB-INF / applicationContext.xml
wird als Konfigurationsdatei verwendetweb.xml
<filter>
<filter-name>
springSecurityFilterChain
</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>
springSecurityFilterChain
</filter-name>
<url-pattern>
/*
</url-pattern>
</filter-mapping>
--DelegatingFilterProxy
durchsucht den Spring-Container nach Bohnen, die den folgenden Kriterien entsprechen:
springSecurityFilterChain
)DelegatingFilterProxy
die Verarbeitung delegiert hat, eine vom Spring-Container erhaltene Bean ist, können die Funktionen des Spring-Containers verwendet werden.
DelegatingFilterProxy
besteht darin, den Servlet-Container und den Spring-Container zu überbrücken.applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
...>
<sec:http>
<sec:intercept-url
pattern="/login"
access="permitAll" />
<sec:intercept-url
pattern="/**"
access="isAuthenticated() and hasAuthority('BAR')" />
<sec:form-login />
<sec:logout />
</sec:http>
...
--applicationContext.xml
ist die Spring-Konfigurationsdatei
xmlns: sec
<http>
ist der SchlüsselapplicationContext.xml
<sec:http>
...
</sec:http>
--Dieses
FilterChainProxy
Filter
SchnittstelleDelegateFilterProxy
, das in web.xml
als Filter
registriert ist, wird vom Servlet-Container generiert.SecurityFilterChain
<http>
registriertFilterChainProxy
delegiert die empfangene Anfrage an die Filter
s von SecurityFilterChain
SecurityContextPersistenceFilter
CsrfFilter
AnonymousAuthenticationFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
--Spring Security wird durch eine Kombination von "Filter" realisiert
--SecurityFilterChain
kann für jedes URL-Muster definiert werden
/ **
) verwenden Sie das für den normalen Bildschirmzugriff festgelegte SecurityFilterChain
.
--Kann man sagenDie Konfigurationsdatei sieht folgendermaßen aus:
applicationContext.xml
<sec:http pattern="/api/**">
...
</sec:http>
<sec:http pattern="/**">
...
</sec:http>
--<http>
registriert SecurityFilterChain
als Bean
--SecurityFilterChain
enthält mehrereFilter
s
SecurityFilterChain
für die REST-API
--SecurityFilterChain
für normalen Bildschirmzugriff
Kann eingestellt werdenapplicationContext.xml
<sec:http>
...
<sec:form-login />
...
</sec:http>
login-page
von <form-login>
nicht angegeben ist, wird ein Filter
namens DefaultLoginPageGeneratingFilter
registriert./ login
eine GET-Methodenanforderung vorliegt/ login
eintrifft, startet der Authentifizierungsprozess.Bitte beachten Sie, dass hier viel "Delegation" herauskommt und es verwirrend ist! </ span>
AuthenticationManager
applicationContext.xml
<sec:authentication-manager> ★
<sec:authentication-provider>
<sec:user-service>
<sec:user name="foo" ... />
<sec:user name="bar" ... />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
--AuthenticationProvider
verfügt über viele Implementierungsklassen für jeden Authentifizierungstyp
--ProviderManager
enthält mehrere Instanzen von AuthenticationProvider
gemäß der von der Anwendung unterstützten Authentifizierungsmethode.
ProviderManager
ist verantwortlich für die gemeinsame Verwaltung mehrererAuthenticationProvider
s (genau ProviderManager
).applicationContext.xml
<sec:authentication-manager>
<sec:authentication-provider> ★
<sec:user-service>
<sec:user name="foo" ... />
<sec:user name="bar" ... />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
DaoAuthenticationProvider
führt die Authentifizierungsverarbeitung mit einer Kombination aus Benutzername und Kennwort durch.UserDetailsService
** delegiert **.UserDetailsService
UserDetailsService
public interface UserDetailsService {
UserDetails
loadUserByUsername(String username)
throws UsernameNotFoundException;
}
UserDetails
) basierend auf dem Benutzernamen zurückgibtUsernameNotFoundException
aus, wenn kein Benutzer gefunden wird
--Spring Security bietet mehrere Klassen, die diese Schnittstelle implementierenInMemoryUserDetailsManager Implementierung zum Speichern von Benutzerinformationen im Speicher
JdbcUserDetailsManager Implementierung, die Benutzerinformationen über JDBC aus der Datenbank abruft
applicationContext.xml
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service> ★
<sec:user name="foo" ... />
<sec:user name="bar" ... />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
UserDetails
UserDetails.java
public interface UserDetails extends Serializable {
String getUsername();
String getPassword();
Collection<? extends GrantedAuthority>
getAuthorities();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
--UserDetails
ist eine Schnittstelle, die detaillierte Informationen über den angemeldeten Benutzer bereitstellt.
applicationContext.xml
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="foo" ... /> ★
<sec:user name="bar" ... /> ★
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
User
generiert./ login
kommt, führt UsernamePasswordAuthenticationFilter
den Authentifizierungsprozess durch.DaoAuthenticationProvider
, der mit dem Tag Die obigen Beziehungen sind in den folgenden Einstellungen enthalten.
applicationContext.xml
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="foo" ... />
<sec:user name="bar" ... />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
AuthenticationProvider.java
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
}
--<form-login>
aktiviert die Formularauthentifizierung
--UsernamePasswordAuthenticationFilter
wird hinzugefügt und der Authentifizierungsprozess gestartet.
--AuthenticationManager
steuert den Authentifizierungsprozess
--AuthenticationProvider
führt eine bestimmte Authentifizierungsverarbeitung durch
--UserDetailsService
ruft Benutzerinformationen Dao ab
--UserDetails
bietet detaillierte Informationen über den Benutzer
FilterSecurityInterceptor
FilterSecurityInterceptor
initiiert--FilterSecurityInterceptor
selbst überprüft die Zugriffskontrolle nicht
AccessDecisionManager
lässt AccessDecisionVoter
für den Zugriff stimmenAccessDecisionManager
fasst die Abstimmungsergebnisse zusammen und zieht Schlussfolgerungen--AccessDecisionManager
verfügt über drei Implementierungsklassen
AffirmativeBased
ConsensusBased
UnanimousBased
applicationContext.xml
<sec:http>
<sec:intercept-url
pattern="/login"
access="permitAll" />
<sec:intercept-url
pattern="/**"
access="isAuthenticated() and hasAuthority('BAR')" />
...
</sec:http>
Expression
Das heißt, steuern Sie die Zugänglichkeit basierend auf Ausdrückenpattern
gibt das Muster der URL an, für die das Steuerelement gilt.Spring Expression Language (SpEL)
applicationContext.xml
access="permitAll"
access="isAuthenticated() and hasAuthority('BAR')"
--Verwenden Sie die Spring-eigene Ausdruckssprache Spring Expression Language für Zugriffssteuerungsausdrücke
true
, zugänglich </ font>
--Wenn false
, nicht zugänglich </ font>permitAll
: Immer wahr
--isAuthenticated ()
: true
wenn authentifiziert
--hasAuthority ()
: true
, wenn Sie die angegebene Berechtigung habenWebExpressionVoter
aktiviert.applicationContext.xml
<sec:http>
...
<sec:logout />
</sec:http>
/ logout
kommt, übernimmt LogoutFilter
die Abmeldung.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>
springSecurityFilterChain
</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>
springSecurityFilterChain
</filter-name>
<url-pattern>
/*
</url-pattern>
</filter-mapping>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
...>
<sec:http>
<sec:intercept-url
pattern="/login"
access="permitAll" />
<sec:intercept-url
pattern="/**"
access="isAuthenticated() and hasAuthority('BAR')" />
<sec:form-login />
<sec:logout />
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="foo"
password="foo"
authorities="" />
<sec:user name="bar"
password="bar"
authorities="BAR" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
</beans>
Recommended Posts