Histoire de base et systématique Histoire de certification / autorisation Histoire Remember-Me Histoire CSRF Histoire de gestion de session Histoire de l'en-tête de la réponse Histoire de la sécurité de la méthode L'histoire de Run-As L'histoire d'ACL Test story Parlez de la coopération avec MVC et Boot
Édition supplémentaire Ce que Spring Security peut et ne peut pas faire
Le [Résumé CORS --Qiita] de @ tomoyukilabs (http://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34) a été une expérience d'apprentissage.
En gros résumé
C'est comme ressentir.
Qu'est-ce que "l'origine"Définition de l'origine|Même politique d'origine-Sécurité Web| MDNVoir.
Hello World
Placez le code HTML suivant sur GitHub afin qu'il puisse être ouvert à partir du navigateur en tant que page statique.
python
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>cors test</title>
</head>
<body>
<div>
<select id="contextPath">
<option value="namespace" selected>namespace</option>
<option value="java-config">java-config</option>
</select>
</div>
<div>
<input id="headerName" placeholder="Header-Name" />
<input id="headerValue" placeholder="Header-Value" />
</div>
<div>
<input id="responseHeaderName" placeholder="responseHeaderName" />
</div>
<button type="button" id="sendButton">Send Request</button>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script>
$(function() {
$('#sendButton').on('click', function() {
var headers = {};
var headerName = $('#headerName').val();
var headerValue = $('#headerValue').val();
if (headerName) {
headers[headerName] = headerValue;
}
var contextPath = $('#contextPath').val();
$.ajax({
url: 'http://localhost:8080/' + contextPath + '/cors',
type: 'GET',
dataType: 'text',
headers: headers
})
.done(function(text, status, jqXhr) {
console.log("text = " + text);
var responseHeaderName = $('#responseHeaderName').val();
if (responseHeaderName) {
console.log("[ResponseHeader] " + responseHeaderName + " : " + jqXhr.getResponseHeader(responseHeaderName));
}
})
.fail(function() {
console.error(arguments);
});
});
});
</script>
</body>
</html>
Celui qui a été publié sur GitHub
J'essaye d'accéder à localhost
avec Ajax.
CorsServlet.java
package sample.spring.security.servlet;
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("/cors")
public class CorsServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Original-Header", "CORS!!");
try (PrintWriter writer = resp.getWriter()) {
writer.println("Hello CORS!!");
}
}
}
Une implémentation qui renvoie simplement l'en-tête et le corps du texte appropriés.
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: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
MySpringSecurityConfig.java
package sample.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
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 MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.eraseCredentials(false)
.inMemoryAuthentication()
.withUser("hoge")
.password("hoge")
.roles();
}
}
Aucun réglage pour CORS n'a été effectué.
Lorsque je clique sur le bouton «Envoyer la demande» sur la page de vérification, j'obtiens l'erreur suivante: ..
J'ai été bloqué par la vérification d'authentification de Spring Security et j'ai été redirigé vers la page de connexion.
Il indique également qu'il n'est pas accessible car l'en-tête ʻAccess-Control-Allow-Origin` défini dans la spécification CORS est absent de la réponse.
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">
<bean id="corsConfiguration" class="org.springframework.web.cors.CorsConfiguration">
<property name="allowedOrigins">
<list>
<value>http://opengl-8080.github.io</value>
</list>
</property>
<property name="allowedMethods">
<list>
<value>GET</value>
</list>
</property>
</bean>
<bean id="corsSource" class="org.springframework.web.cors.UrlBasedCorsConfigurationSource">
<property name="corsConfigurations">
<map>
<entry key="/cors" value-ref="corsConfiguration" />
</map>
</property>
</bean>
<sec:http>
<sec:intercept-url pattern="/login" access="permitAll" />
<sec:intercept-url pattern="/cors" access="permitAll" />
<sec:intercept-url pattern="/**" access="isAuthenticated()" />
<sec:form-login />
<sec:logout />
<sec:cors configuration-source-ref="corsSource" />
</sec:http>
...
</beans>
Java Configuration
MySpringSecurityConfig.java
package sample.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
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.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@EnableWebSecurity
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/cors").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.cors()
.configurationSource(this.corsConfigurationSource());
}
private CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedMethod("GET");
corsConfiguration.addAllowedOrigin("http://opengl-8080.github.io");
UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
corsSource.registerCorsConfiguration("/cors", corsConfiguration);
return corsSource;
}
...
}
Exécutez à nouveau.
Cette fois, l'accès a réussi et le texte renvoyé par le serveur peut être sorti.
applicationContext.xml
<bean id="corsSource" class="org.springframework.web.cors.UrlBasedCorsConfigurationSource">
...
</bean>
<sec:http>
...
<sec:cors configuration-source-ref="corsSource" />
</sec:http>
CorsConfigurationSource
qui définit les paramètres détaillés de CORS dans l'attribut configuration-source-ref
.MySpringSecurityConfig.java
@Override
public void configure(HttpSecurity http) throws Exception {
http...
.and()
.cors()
.configurationSource(this.corsConfigurationSource());
}
private CorsConfigurationSource corsConfigurationSource() {
...
}
--Pour la configuration Java, spécifiez avec .cors (). ConfigurationSource (CorsConfigurationSource)
applicationContext.xml
<bean id="corsConfiguration" class="org.springframework.web.cors.CorsConfiguration">
<property name="allowedOrigins">
<list>
<value>http://opengl-8080.github.io</value>
</list>
</property>
<property name="allowedMethods">
<list>
<value>GET</value>
</list>
</property>
</bean>
<bean id="corsSource" class="org.springframework.web.cors.UrlBasedCorsConfigurationSource">
<property name="corsConfigurations">
<map>
<entry key="/cors" value-ref="corsConfiguration" />
</map>
</property>
</bean>
--Utilisez deux classes pour configurer CORS
--CorsConfigurationSource
et CorsConfiguration
CorsConfiguration
et quelle origine est autorisée à accéder. est spécifiée pour la liste des origines autorisées par la propriété ʻallowedOrigins
.
--CorsConfiguration
est défini sur ** ne pas autoriser ** toutes les demandes par défaut, vous devez donc définir une autorisation.
--CorsConfigurationSource
conserve plusieurs CorsConfiguration
s et détermine quelle CorsConfiguration
doit être appliquée à la demande actuelle
--Dans les paramètres ci-dessus, ʻUrlBasedCorsConfigurationSource est utilisé comme classe d'implémentation. --ʻUrlBasedCorsConfigurationSource
gère quelle CorsConfiguration
doit être appliquée en l'associant au modèle de chemin.corsConfiguration
sont appliquées lors de l'accès au / cors
.MySpringSecurityConfig.java
private CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedMethod("GET");
corsConfiguration.addAllowedOrigin("http://opengl-8080.github.io");
UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
corsSource.registerCorsConfiguration("/cors", corsConfiguration);
return corsSource;
}
--Pour la configuration Java, vous pouvez utiliser des méthodes qui peuvent être définies une par une, telles que ʻaddAllowedMethod (String) et
registerCorsConfiguration (String, CorsConfiguration) `.
La spécification CORS limite les méthodes HTTP et les en-têtes configurables autorisés par défaut.
Si vous souhaitez envoyer un en-tête qui n'est pas autorisé par défaut, vous êtes censé envoyer une demande de pré-allumage, une demande de pré-allumage pour "vérifier si c'est autorisé".
Le client envoie la demande de production uniquement si le serveur renvoie "OK" à cette demande.
Essayez de soumettre une demande avec un en-tête non autorisé appelé «Hoge».
J'étais très en colère.
Il indique qu'il n'est pas accessible car un en-tête n'était pas autorisé dans la demande de contrôle en amont.
Vérifiez les en-têtes de demande et de réponse.
L'en-tête de la requête dit ʻAccess-Control-Request-Headers: hoge, et je vérifie si l'en-tête
hoge` est autorisé.
Cependant, la réponse n'a pas d'en-tête indiquant que «hoge» est autorisé.
Pour cette raison, le navigateur détermine que «hoge» est un en-tête non autorisé et suspend le traitement.
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="corsConfiguration" class="org.springframework.web.cors.CorsConfiguration">
<property name="allowedOrigins">
<list>
<value>http://opengl-8080.github.io</value>
</list>
</property>
<property name="allowedMethods">
<list>
<value>GET</value>
</list>
</property>
<property name="allowedHeaders">★ Ajout
<list>
<value>Hoge</value>
</list>
</property>
</bean>
...
</beans>
Java Configuration
MySpringSecurityConfig.java
package sample.spring.security;
...
@EnableWebSecurity
public class MySpringSecurityConfig extends WebSecurityConfigurerAdapter {
...
private CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
...
corsConfiguration.addAllowedHeader("Hoge");★ Ajout
...
}
...
}
Hoge
est ajouté à ʻallowedHeader de
CorsConfiguration`.
Vérifiez à nouveau l'opération.
Cette fois, la demande est passée correctement.
Vérifiez l'état de la requête HTTP.
La demande de contrôle en amont de la méthode ʻOPTIONSest exécutée en premier, puis la demande de la production
GET` est envoyée.
Jetez un œil à l'en-tête vers «OPTIONS».
ʻAccess-Control-Allow-Headers: hogea été ajouté à l'en-tête de réponse pour indiquer que l'en-tête
hoge` est autorisé.
Spring Security répond automatiquement aux demandes de contrôle en amont selon les règles d'autorisation définies dans CorsConfiguration
.
Il existe des restrictions par défaut lorsque le client accède à n'importe quel en-tête de réponse, mais [ExposedHeaders](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/cors/ Cela peut être autorisé en définissant CorsConfiguration.html # addExposedHeader-java.lang.String-).
Recommended Posts