Grundlegende und systematische Geschichte Zertifizierungs- / Autorisierungsgeschichte CSRF-Geschichte Session Management Story Die Geschichte des Antwortheaders Method Security Story CORS-Geschichte Die Geschichte von Run-As Die Geschichte von ACL Teststory Sprechen Sie über die Zusammenarbeit mit MVC und Boot
Sonderedition Was Spring Security kann und was nicht
Ich schreibe oft "Angemeldet bleiben" oder "Angemeldet bleiben für ○ Wochen" auf dem Anmeldebildschirm von Webdiensten.
Hello World
namespace
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()" />
<sec:form-login />
<sec:logout />
<sec:remember-me />★ Jetzt denk dran-Ich ist aktiviert
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user
name="hoge"
password="hoge"
authorities="" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
</beans>
Java Configuration
python
package sample.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import java.util.Collections;
@EnableWebSecurity
@ComponentScan
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().access("isAuthenticated()")
.and()
.formLogin()
.and()
.rememberMe(); //★ Denken Sie hier-Ermöglichen es mir
}
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("hoge")
.password("hoge")
.authorities(Collections.emptyList());
}
}
Wenn Sie den Anmeldebildschirm (/ login
) öffnen, wird ein Kontrollkästchen mit dem Namen" Auf diesem Computer an mich erinnern "hinzugefügt (Standard-Anmeldebildschirm. 032ed0fa27a239bdc1cc #% E3% 83% AD% E3% 82% B0% E3% 82% A4% E3% 83% B3% E3% 83% 9A% E3% 83% BC% E3% 82% B8% E3% 82% 92 % E6% 8C% 87% E5% AE% 9A% E3% 81% 99% E3% 82% 8B) nur wenn Sie verwenden).
Versuchen Sie zunächst, sich anzumelden, ohne es zu überprüfen.
Überprüfen Sie nach dem Anmelden das Cookie Ihres Browsers.
Die JSESSIONID wird gespeichert. Löschen Sie diese und zeichnen Sie den Bildschirm neu.
Natürlich kehren Sie zum Anmeldebildschirm zurück.
Melden Sie sich anschließend mit dem Kontrollkästchen "Auf diesem Computer an mich erinnern" an. Aktivieren Sie auf dem Anmeldebildschirm das Kontrollkästchen.
Wenn Sie sich das Cookie nach dem Anmelden ansehen, werden Sie feststellen, dass "JSESSIONID" und ein weiteres "Remember-Me" gespeichert sind.
Löschen Sie "JSESSIONID" erneut und zeichnen Sie den Bildschirm neu.
Anschließend kann der Bildschirm neu gezeichnet werden, ohne zum Anmeldebildschirm übersprungen zu werden. Wenn Sie sich das Cookie ansehen, wird "JSESSIONID" mit einem anderen Wert als zuvor gespeichert.
--Remember-Me wird beim Anmelden aktiviert, wenn den Anmeldeparametern ein Parameter mit dem Namen "Remember-Me" hinzugefügt wird
:
) verknüpft werden.Der zum Signieren verwendete SCHLÜSSEL zeigt auf eine beliebige Zeichenfolge, die im Attribut "key" von "
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:remember-me key="foobar" />
</sec:http>
...
</beans>
Dieses Attribut ist jedoch optional, andernfalls wird eine zufällige Zeichenfolge verwendet, die mit "SecureRandom" generiert wurde.
Ich denke, es ist sicherer, "SecureRandom" zu verwenden, aber dieser Wert wird nur einmal generiert, wenn die Anwendung gestartet wird. Wenn Sie also die Anwendung neu starten, während Sie "SecureRandom" verwenden, werden alle vom Client aufgezeichneten "Remember-Me" -Cookies ungültig. (Da sich der Signaturwert ändert, wenn sich der SCHLÜSSEL ändert, tritt beim Überprüfen der Signatur immer ein Fehler auf.)
Es scheint, dass Sie eine feste Zeichenfolge angeben müssen, wenn Sie das "Remember-Me" -Cookie des Clients beibehalten möchten, auch wenn Sie die Anwendung neu starten.
――Wenn Sie den Wert von Cookie kennen, können Sie aufgrund des oben genannten Mechanismus leicht fälschen.
Wenn Sie das sichere Attribut des Cookies aktivieren, wird das Cookie nur für die https-Kommunikation gesendet. Wenn Sie ein Cookie über eine unverschlüsselte http-Kommunikation senden, wird es möglicherweise von einem Dritten abgefangen und das Cookie wird möglicherweise gestohlen. Daher sollte diese Einstellung aktiviert sein.
Wenn Sie Spring Securty verwenden, können Sie das sichere Attribut des von Remember-Me verwendeten Cookies aktivieren, indem Sie Folgendes festlegen:
namespace
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:remember-me use-secure-cookie="true" />
</sec:http>
...
</beans>
Setzen Sie das Attribut "use-secure-cookie" des Tags "
Java Configuration
python
package sample.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import java.util.Collections;
@EnableWebSecurity
@ComponentScan
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.rememberMe()
.useSecureCookie(true);
}
...
}
Setze useSecureCookie (true)
.
Vertrauen Sie der Remember-Me-Anmeldung nicht vollständig und benötigen Sie vor einem wirklich wichtigen Vorgang erneut eine Kennwortauthentifizierung. Eine wichtige Verarbeitung umfasst beispielsweise das Aktualisieren von Daten oder den Zugriff auf eine Seite mit persönlichen Informationen.
Selbst wenn das Remember-Me-Cookie gestohlen und gefälscht wird, können Sie es auf diese Weise davor schützen, wirklich wichtige Aktionen auszuführen.
Ich denke, das ist derjenige, der oft nach einem Passwort fragt, bevor er eine Bestellung auf einer Online-Shopping-Site bestätigt (wahrscheinlich).
Zugriffssteuerungsausdrücke für Spring Security (http://qiita.com/opengl-8080/items/032ed0fa27a239bdc1cc#%E5%BC%8F%E3%83%99%E3%83%BC%E3% 82% B9% E3% 81% A7% E3% 81% AE% E3% 82% A2% E3% 82% AF% E3% 82% BB% E3% 82% B9% E5% 88% B6% E5% BE% In A1) können Sie einen Ausdruck verwenden, der berücksichtigt, dass es sich nicht um Remember-Me handelt, z. B. "isFullyAuthenticated ()", sodass er mithilfe dieses Ausdrucks realisiert werden kann.
namespace
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="/remember-me/high-level" access="isFullyAuthenticated()" />
<sec:intercept-url pattern="/**" access="isAuthenticated()" />
...
<sec:remember-me />
</sec:http>
...
</beans>
Java Configuration
MySpringSecurityConfig.java
package sample.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import java.util.Collections;
@EnableWebSecurity
@ComponentScan
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/remember-me/high-level").fullyAuthenticated()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.rememberMe();
}
...
}
Es ist so eingestellt, dass Sie beim Zugriff auf "/ memor-me / high-level" vollständig authentifiziert sein müssen ("fullAuthenticated ()").
Außerdem haben wir ein einfaches Servlet vorbereitet, das beim Zugriff auf / memor-me / *
nur den Pfad zu diesem Zeitpunkt zurückgibt.
** Funktionsprüfung **
Melden Sie sich mit aktiviertem Remember-Me an.
Entfernen Sie "JSESSIONID" aus dem Cookie (machen Sie es wie eine tote Sitzung).
Wenn Sie in diesem Zustand erneut auf die Startseite zugreifen, wird die automatische Anmeldung von Remember-Me ausgeführt und die Startseite wird angezeigt.
Greifen Sie auf / memor-me / foo
zu, nachdem Sie sich mit Remember-Me angemeldet haben.
Die Seite wird normal angezeigt. Dann gehe zu "/ Remember-Me / High-Level".
Dieses Mal werden Sie zur Anmeldeseite weitergeleitet. Dies liegt daran, dass "/ memor-me / high-level" auf "vollständig authentifiziert" eingestellt ist, dh nur eine vollständige Anmeldung mit einem Kennwort angezeigt werden kann.
Geben Sie Ihr Passwort ein, um sich anzumelden.
Dieses Mal wird "/ memor-me / high-level" richtig angezeigt.
Spring Security steuert das Übergangsziel nach der Anmeldung automatisch als die URL, auf die Sie vor der Anmeldung zugreifen wollten. Daher sind keine besonderen Einstellungen erforderlich (es kann eine beliebige URL angegeben werden).
Mit dem oben beschriebenen Standard-Remember-Me-Mechanismus kann nicht festgestellt werden, ob ein Cookie von einem Dritten gestohlen wurde. Daher bemerkt das Opfer nicht, dass es beschädigt wurde, und gibt dem Angreifer einen Spielraum, um zu tun, was er will.
Daher bietet Spring Security einen Mechanismus, der erkennen kann, ob ein Cookie gestohlen wurde, um den Schaden zu minimieren.
Spring Security realisiert den Diebstahlerkennungsmechanismus, indem es den im Artikel hier erläuterten Mechanismus übernimmt.
Der Umgang mit Cookies ist ungefähr wie folgt.
Der Inhalt des Cookies ist "Serie" und "Token". Und der Server zeichnet die Kombination der beiden auf.
Zum Zeitpunkt der automatischen Anmeldung wird die aus dem Cookie extrahierte "Serie" nach dem vom Server aufgezeichneten "Token" durchsucht und überprüft, ob es mit dem "Token" im Cookie übereinstimmt.
Die automatische Anmeldung wird nur durchgeführt, wenn die "Token" übereinstimmen. Danach werden die "Token" durch neue Werte ersetzt.
Dieser Mechanismus zur Verwendung der "Serie", bei der Werte als Kennung zur Identifizierung des Cookies wiederverwendet werden, und zur Aktualisierung des "Tokens" bei jeder automatischen Anmeldung ist ein Mechanismus zur Erkennung von Diebstahl.
Wenn sich ein Angreifer automatisch mit einem gestohlenen Cookie anmeldet, werden das im Cookie des Angreifers enthaltene "Token" und das vom Server aufgezeichnete "Token" aktualisiert, aber das "Token" des Cookies des Opfers wird aktualisiert. Wird alt bleiben.
Wenn das Opfer versucht, sich nach einer nicht autorisierten Anmeldung automatisch anzumelden, stimmen das auf der Serverseite aufgezeichnete "Token" und das im Cookie des Opfers enthaltene "Token" nicht überein.
Auf diese Weise kann der Server erkennen, dass das Cookie möglicherweise gestohlen wurde, und das Opfer oder den Dienstadministrator benachrichtigen.
Dies ist meine persönliche Meinung, aber ich bin der Meinung, dass der Diebstahl umso schneller erkannt werden kann, je kürzer das Sitzungszeitlimit ist. In diesem Fall treten jedoch häufig Sitzungszeitlimits auf, und Sie müssen das Kennwort jedes Mal eingeben, wenn Sie versuchen, einen Bildschirm zu öffnen, für den eine vollständige Anmeldung erforderlich ist, wie oben beschrieben. Ich bin der Meinung, dass die Benutzerfreundlichkeit abnimmt. (Dies hängt davon ab, ob Sie der Sicherheit oder der Benutzerfreundlichkeit Priorität einräumen.)
Zufällige Zeichenketten, die mit "SecureRandom" generiert wurden, werden für "Serien" und "Token" verwendet.
build.gradle
dependencies {
compile 'org.springframework.security:spring-security-web:4.2.1.RELEASE'
compile 'org.springframework.security:spring-security-config:4.2.1.RELEASE'
compile 'org.springframework:spring-jdbc:4.3.7.RELEASE' ★
}
Spring-jdbc
zu Abhängigkeiten hinzugefügt.
namespace
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"
...>
...
<bean id="rememberMeTokenRepository"
class="org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl" />
<sec:http>
...
<sec:remember-me token-repository-ref="rememberMeTokenRepository" />
</sec:http>
...
</beans>
Fügen Sie der Bean-Definition "InMemoryTokenRepositoryImpl" hinzu und geben Sie es in "token-repository-ref" des Tags "
Java Configuration
python
package sample.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl;
import java.util.Collections;
@EnableWebSecurity
@ComponentScan
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/remember-me/high-level").fullyAuthenticated()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.rememberMe()
.tokenRepository(new InMemoryTokenRepositoryImpl()); ★
}
...
}
Übergeben Sie eine Instanz von "InMemoryTokenRepositoryImpl" mit "tokenRepository ()".
Melden Sie sich mit aktiviertem Remember-Me an.
Kopieren Sie den Wert des ausgegebenen Cookies.
Öffnen Sie einen anderen Browser und fügen Sie dem Cookie "Remember-Me" hinzu, um den gerade kopierten Wert festzulegen.
Wenn Sie auf die oberste Seite zugreifen, können Sie sich ohne Eingabe eines Kennworts anmelden (bei einem erfolgreichen Angriff).
Kehren Sie in diesem Zustand zu dem Browser zurück, der ursprünglich mit dem Kennwort normal angemeldet war, löschen Sie "JSESSIONID" und greifen Sie dann auf die Startseite zu. (Reproduktion des Zustands, auf den das Opfer nach Ablauf der Sitzung erneut zugegriffen hat)
CookieTheftException
wird ausgelöst und ein Fehlerbildschirm wird angezeigt.
Selbst wenn eine Ausnahme, die Cookie-Diebstahl bedeutet, ausgelöst wird, scheint sie standardmäßig nicht behandelt zu werden und wird als Systemfehler behandelt. (Vorerst wurde festgestellt, dass der Cookie gestohlen wurde.)
Der Remember-Me-Prozess wird von "RememberMeAuthenticationFilter" gestartet. Wenn im nicht authentifizierten Zustand Zugriff besteht, delegiert dieser Filter den Authentifizierungsprozess an "RememberMeService".
RememberMeService
hat zwei Implementierungsklassen.
TokenBasedRememberMeServices
bietet eine Remember-Me-Authentifizierung mit der einfachen Methode, die wir in der ersten Hello World gesehen haben.
Auf der anderen Seite realisiert "PersistentTokenBasedRememberMeServices" Remember-Me durch eine Methode, die Diebstahl erkennen kann, die später beschrieben wird.
PersistentTokenBasedRememberMeServices
delegiert die Speicherung von" Serien "und" Token "an PersistentTokenRepository
, und PersistentTokenRepository
hat abhängig von der spezifischen Speichermethode zwei Klassen.
JdbcTokenRepositoryImpl
zeichnet Informationen in einer Tabelle in der Datenbank auf und InMemoryTokenRepositoryImpl
zeichnet sie im Speicher auf.
Wenn Sie nur Remember-Me aktivieren, wird "TokenBasedRememberMeServices" verwendet, um "RememberMeService" zu implementieren. Sie können jedoch die Implementierung von "RememberMeService" auf "PersistentTokenBasedRememberMeServices" umstellen, indem Sie "PersistentTokenRepository" in "Token-Repository-Ref" angeben.
Eine "CookieTheftException" wird ausgelöst, wenn ein Cookie-Diebstahl erkannt wird. Wenn Sie jedoch versuchen, diese Ausnahme zu behandeln, scheint dies mit der von Spring Security bereitgestellten API nicht möglich zu sein.
Die von "PersistentTokenBasedRememberMeServices" ausgelöste "CookieTheftException" wird einmal von "AbstractRememberMeServices" abgefangen. Nachdem der Cookie gelöscht wurde, wird er erneut geworfen.
Danach wird es nirgendwo gefangen und fliegt zum Servlet.
Wenn Sie versuchen, diese Ausnahme zu behandeln, haben Sie keine andere Wahl, als den Standard-Ausnahmebehandlungsmechanismus für Servlets zu verwenden.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
...
<error-page>
<exception-type>org.springframework.security.web.authentication.rememberme.CookieTheftException</exception-type>
<location>/cookie-theft.html</location>
</error-page>
</web-app>
cookie-theft.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>CookieTheftException</title>
</head>
<body>
<h1>Der Keks wurde gestohlen!</h1>
</body>
</html>
Wenn Sie so arbeiten, dass "CookieTheftException" ausgelöst wird, wird der Fehlerbildschirm der Stapelverfolgung nicht angezeigt und Sie werden zum nächsten Bildschirm übersprungen.
Servlet kann das Übergangsziel definieren, wenn in web.xml
ein Fehler mit dem Tag <Fehlerseite>
auftritt. Verwenden Sie dies also.
Im obigen Beispiel können nur statische Seiten angezeigt werden, aber die dynamische Verarbeitung kann durch Kombination mit Servlet eingefügt werden.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
...
<error-page>
<exception-type>org.springframework.security.web.authentication.rememberme.CookieTheftException</exception-type>
<location>/cookie-theft</location>
</error-page>
</web-app>
CookieTheftServlet.java
package sample.spring.security.servlet;
import org.springframework.security.web.authentication.rememberme.CookieTheftException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/cookie-theft")
public class CookieTheftServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
CookieTheftException e = (CookieTheftException)req.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
try (PrintWriter writer = resp.getWriter()) {
writer.println(e.getMessage());
}
}
}
Geben Sie an, wann ein Fehler generiert wird
Stellen Sie sicher, dass das Servlet den durch "HttpServletRequest
verweisen.
Ich habe es nicht ausprobiert, aber wenn Sie Spring MVC verwenden, können Sie es vom MVC-Controller akzeptieren lassen.
In jedem Fall können Sie so eine beliebige Verarbeitung durchführen, sodass Sie Fehlerinformationen per E-Mail senden können.
build.gradle
dependencies {
compile 'org.springframework.security:spring-security-web:4.2.1.RELEASE'
compile 'org.springframework.security:spring-security-config:4.2.1.RELEASE'
compile 'org.springframework:spring-jdbc:4.3.7.RELEASE'
compile 'com.h2database:h2:1.4.193'
}
Verwenden Sie für die Datenbank vorerst H2 der integrierten Datenbank.
src/main/resources/sql/create_remember-me_tables.sql
CREATE TABLE PERSISTENT_LOGINS (
USERNAME VARCHAR(64) NOT NULL,
SERIES VARCHAR(64) NOT NULL PRIMARY KEY,
TOKEN VARCHAR(64) NOT NULL,
LAST_USED TIMESTAMP NOT NULL
);
Eine SQL-Datei, die eine Tabelle zum Aufzeichnen von Token-Informationen erstellt.
namespace
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:jdbc="http://www.springframework.org/schema/jdbc"
...
xsi:schemaLocation="
...
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
...
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:/sql/create_remember-me_tables.sql" />
</jdbc:embedded-database>
<sec:http>
<sec:intercept-url pattern="/login" access="permitAll" />
<sec:intercept-url pattern="/remember-me/high-level" access="isFullyAuthenticated()" />
<sec:intercept-url pattern="/**" access="isAuthenticated()" />
<sec:form-login />
<sec:logout />
<sec:remember-me data-source-ref="dataSource" />
</sec:http>
...
</beans>
Definieren Sie die Datenquelle als Bean und geben Sie sie im Attribut "data-source-ref" des Tags "
Java Configuration
python
package sample.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import javax.sql.DataSource;
import java.util.Collections;
@EnableWebSecurity
@ComponentScan
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.rememberMe()
.tokenRepository(this.createTokenRepository());
}
public PersistentTokenRepository createTokenRepository() {
DataSource dataSource =
new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(EmbeddedDatabaseType.H2)
.setScriptEncoding("UTF-8")
.addScript("/sql/create_remember-me_tables.sql")
.build();
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
return tokenRepository;
}
...
}
Die Java-Konfiguration scheint keine Methode zu haben, um "DataSource" direkt anzugeben. Setzen Sie "DataSource" auf "JdbcTokenRepositoryImpl" und übergeben Sie sie dann mit der Methode "tokenRepository ()".
Wie ich die Implementierung gesehen habe, scheint es unmöglich, den Tabellennamen und den Spaltennamen nur mit der Standardimplementierung anzupassen.
Die Implementierung von JdbcTokenRepositoryImpl
sieht folgendermaßen aus:
JdbcTokenRepositoryImpl.java
public class JdbcTokenRepositoryImpl extends JdbcDaoSupport implements
PersistentTokenRepository {
// ~ Static fields/initializers
// =====================================================================================
/** Default SQL for creating the database table to store the tokens */
public static final String CREATE_TABLE_SQL = "create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, "
+ "token varchar(64) not null, last_used timestamp not null)";
/** The default SQL used by the <tt>getTokenBySeries</tt> query */
public static final String DEF_TOKEN_BY_SERIES_SQL = "select username,series,token,last_used from persistent_logins where series = ?";
/** The default SQL used by <tt>createNewToken</tt> */
public static final String DEF_INSERT_TOKEN_SQL = "insert into persistent_logins (username, series, token, last_used) values(?,?,?,?)";
/** The default SQL used by <tt>updateToken</tt> */
public static final String DEF_UPDATE_TOKEN_SQL = "update persistent_logins set token = ?, last_used = ? where series = ?";
/** The default SQL used by <tt>removeUserTokens</tt> */
public static final String DEF_REMOVE_USER_TOKENS_SQL = "delete from persistent_logins where username = ?";
// ~ Instance fields
// ================================================================================================
private String tokensBySeriesSql = DEF_TOKEN_BY_SERIES_SQL;
private String insertTokenSql = DEF_INSERT_TOKEN_SQL;
private String updateTokenSql = DEF_UPDATE_TOKEN_SQL;
private String removeUserTokensSql = DEF_REMOVE_USER_TOKENS_SQL;
...
SQL-Text wird im Feld public`` static
definiert und bei der Instanziierung in das Feld gesetzt.
Das in diesem Feld festgelegte SQL wird bei der Suche nach Token usw. verwendet, es gibt jedoch keine Methode zum Umschreiben dieses Felds.
Es scheint also, dass es nicht umgeschrieben werden kann (ernsthaft? Stimmt etwas nicht?).
Wenn Sie den Tabellennamen oder Spaltennamen aufgrund von Umständen für Erwachsene nicht angeben können, müssen Sie möglicherweise "JdbcTokenRepositoryImpl" kopieren, um Ihr eigenes "TokenRepository" zu erstellen.
Recommended Posts