Grundlegende und systematische Geschichte Zertifizierungs- / Autorisierungsgeschichte Remember-Me-Geschichte CSRF-Geschichte Session Management Story Die Geschichte des Antwortheaders Method Security Story 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
@ tomoyukilabs 'CORS Summary --Qiita war eine Lernerfahrung.
Grob zusammengefasst
Es fühlt sich an wie.
Was ist "Herkunft"?Definition des Ursprungs|Gleiche Ursprungspolitik-Web-Sicherheit| MDNSehen.
Hello World
Platzieren Sie das folgende HTML auf GitHub, damit es im Browser als statische Seite geöffnet werden kann.
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>
Der tatsächlich auf GitHub gepostete
Ich versuche mit Ajax auf localhost
zuzugreifen.
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!!");
}
}
}
Eine Implementierung, die nur den entsprechenden Header und Textkörper zurückgibt.
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();
}
}
Es wurden keine Einstellungen für CORS vorgenommen.
Wenn ich auf der Bestätigungsseite auf die Schaltfläche "Anfrage senden" klicke, wird folgende Fehlermeldung angezeigt: ..
Ich wurde durch die Authentifizierungsprüfung von Spring Security blockiert und auf die Anmeldeseite umgeleitet.
Es heißt auch, dass nicht darauf zugegriffen werden kann, da der in der CORS-Spezifikation definierte Header "Access-Control-Allow-Origin" in der Antwort fehlt.
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;
}
...
}
Führe es nochmals aus.
Diesmal war der Zugriff erfolgreich und der vom Server zurückgegebene Text kann ausgegeben werden.
applicationContext.xml
<bean id="corsSource" class="org.springframework.web.cors.UrlBasedCorsConfigurationSource">
...
</bean>
<sec:http>
...
<sec:cors configuration-source-ref="corsSource" />
</sec:http>
MySpringSecurityConfig.java
@Override
public void configure(HttpSecurity http) throws Exception {
http...
.and()
.cors()
.configurationSource(this.corsConfigurationSource());
}
private CorsConfigurationSource corsConfigurationSource() {
...
}
.cors (). ConfigurationSource (CorsConfigurationSource)
anapplicationContext.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>
--Verwenden Sie zwei Klassen, um CORS zu konfigurieren
--CorsConfigurationSource
und CorsConfiguration
CorsConfiguration
zulässig ist und auf welchen Ursprung zugegriffen werden darf.CorsConfiguration
ist standardmäßig auf ** nicht alle Anfragen ** eingestellt, daher müssen Sie eine Berechtigung festlegen.
--CorsConfigurationSource
behält mehrere CorsConfiguration
s bei und legt fest, welche CorsConfiguration
auf die aktuelle Anforderung angewendet werden sollUrlBasedCorsConfigurationSource
verwaltet, welche CorsConfiguration
angewendet werden soll, indem sie dem Pfadmuster zugeordnet wird.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;
}
Die CORS-Spezifikation begrenzt die HTTP-Methoden und konfigurierbaren Header, die standardmäßig zulässig sind.
Wenn Sie einen Header senden möchten, der standardmäßig nicht zulässig ist, müssen Sie eine Prefilight-Anforderung senden, eine Prefilight-Anforderung, um zu überprüfen, ob dies zulässig ist.
Der Client sendet die Produktionsanforderung nur, wenn der Server dieser Anforderung "OK" zurückgibt.
Versuchen Sie, eine Anfrage mit einem nicht autorisierten Header namens "Hoge" zu senden.
Ich war sehr wütend.
Es heißt, dass nicht darauf zugegriffen werden konnte, da in der Preflight-Anforderung ein Header vorhanden war, der nicht zulässig war.
Überprüfen Sie die Anforderungs- und Antwortheader.
Der Anforderungsheader lautet "Access-Control-Request-Headers: hoge", und ich überprüfe, ob der Header "hoge" zulässig ist. Die Antwort enthält jedoch keinen Header, der besagt, dass "hoge" zulässig ist.
Aus diesem Grund stellt der Browser fest, dass "hoge" ein nicht autorisierter Header ist, und setzt die Verarbeitung aus.
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">★ Ergänzung
<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");★ Ergänzung
...
}
...
}
"Hoge" wird in "CorsConfiguration" zu "allowHeader" hinzugefügt.
Überprüfen Sie den Vorgang erneut.
Diesmal wurde die Anfrage ordnungsgemäß bestanden.
Überprüfen Sie den Status der HTTP-Anforderung.
Die Preflight-Anforderung durch die "OPTIONS" -Methode wird zuerst ausgeführt, und dann wird die Anforderung durch die Produktion "GET" gesendet.
Schauen Sie sich die Kopfzeile für "OPTIONEN" an.
"Access-Control-Allow-Headers: hoge" wurde dem Antwortheader hinzugefügt, um anzuzeigen, dass der "hoge" -Header zulässig ist.
Spring Security reagiert automatisch auf Preflight-Anfragen gemäß den in CorsConfiguration
festgelegten Berechtigungsregeln.
Es gibt standardmäßig Einschränkungen, wenn Clients auf beliebige Antwortheader zugreifen, aber exponierte Header. Dies kann durch Festlegen von CorsConfiguration.html # addExposedHeader-java.lang.String-) zugelassen werden.
Recommended Posts