Histoire de base et systématique Histoire de certification / autorisation Histoire Remember-Me Histoire CSRF Histoire de gestion de session L'histoire de l'en-tête de la réponse Histoire de la sécurité de la méthode Histoire CORS L'histoire de Run-As Histoire ACL Test story
Édition supplémentaire Ce que Spring Security peut et ne peut pas faire
Comment utiliser Spring Security avec Spring MVC et Spring Boot, etc.
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.3.RELEASE'
compile 'org.springframework.security:spring-security-config:4.2.3.RELEASE'
compile 'org.springframework:spring-webmvc:4.3.10.RELEASE'
}
spring-webmvc
aux dépendancesMyMvcController.java
package sample.spring.security.mvc;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyMvcController {
@GetMapping("/foo")
public String foo() {
return "FOO!!";
}
}
quand une requête GET arrive à
/ foo`namespace
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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc.xml
/WEB-INF/security.xml
</param-value>
</context-param>
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
--Définir Spring Security DelegatingFilterProxy
et Spring MVC DispatcherServlet
respectivement
--Spécifiez / WEB-INF / mvc.xml
et / WEB-INF / security.xml
comme fichiers de configuration Spring MVC et de sécurité
security.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="/foo" access="isAuthenticated()" />
<sec:form-login />
</sec:http>
<sec:authentication-manager />
</beans>
/ foo
nécessite une authentificationmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
<bean class="sample.spring.security.mvc.MyMvcController" />
</beans>
--Paramètres pour Spring MVC
Java Configuration
MySecurityInitializer.java
package sample.spring.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class MySecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
--Classe d'application de Spring Security Filter
MyServletInitializer.java
package sample.spring.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {MySecurityConfig.class, MyMvcConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {};
}
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
--Classe d'initialisation pour Spring MVC
--Le paramètre MVC (MyMvcConfig
) et le paramètre de sécurité ( MySecurityConfig
) sont définis comme racine de l'application (je ne sais pas pourquoi, mais si vous ne le faites pas, les mvcMatchers
décrits plus tard ne fonctionneront pas. T)
MySecurityConfig.java
package sample.spring.config;
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;
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/foo").authenticated()
.and()
.formLogin();
}
}
/ foo
nécessitent une authentificationMyMvcConfig.java
package sample.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import sample.spring.security.mvc.MyMvcController;
@EnableWebMvc
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Bean
public MyMvcController myMvcController() {
return new MyMvcController();
}
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return new RequestMappingHandlerMapping();
}
}
--Paramètres pour Spring MVC --Enregistrement du contrôleur
Tout d'abord, la demande est envoyée à / foo
, puis la demande est envoyée à / foo.html
.
$ curl http://localhost:8080/namespace/foo -i
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID=0AD6574E5F43053B42E5C9926535AC0E; Path=/namespace/; HttpOnly
Location: http://localhost:8080/namespace/login
Content-Length: 0
Date: Mon, 31 Jul 2017 13:05:03 GMT
$ curl http://localhost:8080/namespace/foo.html -i
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Disposition: inline;filename=f.txt
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 5
Date: Mon, 31 Jul 2017 13:05:06 GMT
FOO!!
Dans le cas de / foo
, j'ai été invité à rediriger vers l'écran de connexion, mais dans le cas de / foo.html
, l'implémentation du contrôleur a été appelée normalement.
--Spring MVC fera également correspondre les chemins avec des extensions telles que / foo.html
en fonction des paramètres lors du mappage du chemin / foo
sur le contrôleur.
/ foo.html
et / foo.json
sont mappés sur la même méthode de contrôleur./ foo
seront contournées.Matcher
, qui correspond aux chemins en utilisant la même logique que le processus de correspondance de chemin de Spring MVC.namespace
security.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 request-matcher="mvc">
<sec:intercept-url pattern="/foo" access="isAuthenticated()" />
<sec:form-login />
</sec:http>
<sec:authentication-manager />
</beans>
--Spécifiez mvc
dans request-matcher
de la balise<http>
Java Configuration
MySecurityConfig.java
package sample.spring.config;
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;
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/foo").authenticated()
.and()
.formLogin();
}
}
--Utilisez mvcMatchers ()
au lieu de ʻantMatchers () `
Contrôle de fonctionnement
$ curl http://localhost:8080/namespace/foo -i
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID=0322DCB394ED74B38CCA600DDEF8CBBF; Path=/namespace/; HttpOnly
Location: http://localhost:8080/namespace/login
Content-Length: 0
Date: Mon, 31 Jul 2017 13:07:48 GMT
$ curl http://localhost:8080/namespace/foo.html -i
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID=BE049E9C138392A8751351762B200D63; Path=/namespace/; HttpOnly
Location: http://localhost:8080/namespace/login
Content-Length: 0
Date: Mon, 31 Jul 2017 13:07:49 GMT
Cette fois, même si j'ai ajouté .html
, je suis passé à l'écran de connexion.
MyMvcController.java
package sample.spring.security.mvc;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyMvcController {
@GetMapping("/user")
public String foo(@AuthenticationPrincipal User user) {
System.out.println("username=" + user.getUsername() + ", authorities=" + user.getAuthorities());
return "User!!";
}
}
namespace
mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean class="sample.spring.security.mvc.MyMvcController" />
</beans>
security.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 request-matcher="mvc">
<sec:intercept-url pattern="/login" access="permitAll" />
<sec:intercept-url pattern="/**" access="isAuthenticated()" />
<sec:form-login />
<sec:logout />
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="foo" password="foo" authorities="GENERAL_USER, ADMINISTRATOR" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
</beans>
Java Configuration
MyMvcConfig.java
reste inchangé
MySecurityConfig.java
package sample.spring.config;
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;
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("foo")
.password("foo")
.authorities("GENERAL_USER", "ADMINISTRATOR");
}
}
Accédez avec un navigateur, connectez-vous en tant qu'utilisateur foo
, puis accédez à / user
.
Sortie de la console du serveur
username=foo, authorities=[ADMINISTRATOR, GENERAL_USER]
MyMvcController.java
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
...
@GetMapping("/user")
public String foo(@AuthenticationPrincipal User user) {
System.out.println("username=" + user.getUsername() + ", authorities=" + user.getAuthorities());
return "User!!";
}
comme argument de contrôleur. --Annotez l'argument avec
@ AuthenticationPrincipal`mvc.xml
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
dans
. --Si vous utilisez la configuration Java, ce paramètre est effectué automatiquement en utilisant
@ EnableWebSecurity`, donc aucun paramètre supplémentaire n'est requis.MyMvcController.java
package sample.spring.security.mvc;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyMvcController {
@GetMapping("/csrf")
public String foo(CsrfToken token) {
System.out.println("token=" + token.getToken() + ", headerName=" + token.getHeaderName() + ", parameterName=" + token.getParameterName());
return "CSRF!!";
}
}
namespace
mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean class="sample.spring.security.mvc.MyMvcController" />
</beans>
security.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 request-matcher="mvc">
<sec:intercept-url pattern="/**" access="permitAll" />
<sec:form-login />
<sec:csrf />
</sec:http>
<sec:authentication-manager />
</beans>
Java Configuration
MyMvcConfig
est inchangé
MySecurityConfig.java
package sample.spring.config;
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;
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/**").permitAll()
.and()
.formLogin()
.and()
.csrf();
}
}
Accéder à / csrf
Sortie de la console du serveur
token=bcac7b2e-f2c0-424c-a563-4b957ff7133e, headerName=X-CSRF-TOKEN, parameterName=_csrf
MyMvcController.java
import org.springframework.security.web.csrf.CsrfToken;
...
@GetMapping("/csrf")
public String foo(CsrfToken token) {
System.out.println("token=" + token.getToken() + ", headerName=" + token.getHeaderName() + ", parameterName=" + token.getParameterName());
return "CSRF!!";
}
CsrfToken
mvc.xml
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
CsrfTokenArgumentResolver
doit être spécifié dans <argument-resolvers> ʻafin de recevoir
CsrfToken` comme argument.@ EnableWebSecurity
, donc aucun paramètre supplémentaire n'est requis.Hello World La mise en oeuvre
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.6.RELEASE'
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
compileJava.options.encoding = 'UTF-8'
repositories {
mavenCentral()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-security'
}
Main.java
package sample.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
src/main/resources/static/hello.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello Spring Security with Spring Boot</title>
</head>
<body>
<h1>Hello Spring Security!!</h1>
</body>
</html>
** Contrôle de fonctionnement **
$ gradle bootRun
The plugin id 'spring-boot' is deprecated. Please use 'org.springframework.boot' instead.
:compileJava
:processResources
:classes
:findMainClass
:bootRun
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.6.RELEASE)
2017-08-02 22:55:17.710 INFO 13608 --- [ main] sample.boot.Main : Starting Main on .....
with PID 13608 (...\spring-boot-security\build\classes\main started by .... in ...\spring-boot-security)
(Omis)
2017-08-02 22:55:19.756 INFO 13608 --- [ main] b.a.s.AuthenticationManagerConfiguration :
Using default security password: 40890087-600d-417d-962d-a856e139b9c4
2017-08-02 22:55:19.808 INFO 13608 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
(Omis)
Allez sur http: // localhost: 8080 / hello.html
.
Une boîte de dialogue s'affiche et vous demande de saisir votre nom d'utilisateur et votre mot de passe.
Éléments d'entrée | valeur |
---|---|
Nom d'utilisateur | user |
mot de passe | 起動時にコンソールに出力されたmot de passe |
Le mot de passe est envoyé à la console au démarrage de l'application.
Sortie du mot de passe sur la console
Using default security password: 40890087-600d-417d-962d-a856e139b9c4
Après une connexion réussie, le contenu de hello.html
s'affiche.
La description
build.gradle
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-security'
}
spring-boot-starter-security
ajoute les dépendances de Spring Security
--Si vous ne faites rien, l'authentification de base est activée par défaut et un utilisateur nommé ʻuser` est préparé en mémoire (le mot de passe change lorsque vous le redémarrez).security.user.password
/ js / **
, / css / **
, / images / **
, / webjars / **
, ** / favicon.js
est sans authentification. Définir pour être possibleLa mise en oeuvre
MySecurityConfig.java
package sample.boot.config;
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;
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("foo").password("foo").authorities("TEST_USER");
}
}
** Contrôle de fonctionnement **
Accédez à http: // localhost: 8080 / hello.html
L'écran de connexion par défaut sera affiché, donc connectez-vous en tant qu'utilisateur foo
.
La description
Le comportement par défaut peut être réécrit arbitrairement en ajoutant la classe de configuration annotée avec @ EnableWebSecurity
et en clarifiant la configuration de Spring Security.
Recommended Posts