近期工作中,主要做一个平台项目,接触了一些angularjs的东西。也接触到了跨域问题
因此做一个简单的总结
一.同源策略
通信三要素分为,域名(子域名),协议,端口,这三个只要有一个不同,则称为不同源
他们之间的数据访问被称为跨域访问
同源策略限制的不同源之间的交互主要针对的是js中的XMLHttpRequest(主要代表即ajax)等请求,
下面这些情况是完全不受同源策略限制的。
1.页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
链接就不用说了,导航网站上的链接都是链接到其他站点的。
而你在域名www.foo.com下面提交一个表单到www.bar.com是完全可以的。
2.跨域资源嵌入是允许的,当然,浏览器限制了Javascript不能读写加载的内容。
如前面提到的嵌入的<script src="..."></script>,<img>,<link>,<iframe>等。
当然,如果要阻止iframe嵌入我们网站的资源(页面或者js等),
我们可以在web服务器加上一个X-Frame-Options DENY头部来限制。
nginx就可以这样设置add_header X-Frame-Options DENY;。
二.跨域问题
这一节来讨论下跨域问题,当然前置条件是我们在WEB服务器或者服务端脚本中设置
ACCESS-CONTROL-ALLOW-ORIGIN头部,如果设置了这些头部并允许某些域名跨域访问,
则浏览器就会跳过同源策略的限制返回对应的内容。
此外,如果你不是通过浏览器去获取资源,
比如你通过一个python脚本去调用接口或者获取js文件,也不在这个限制之内。
package net.xiayule.spring.cors.SpringBootCorsTest.controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = {"http://localhost:9000", "null"})//这个注解也可以加方法上
@RequestMapping(value = "/api")
public class TestController {
@RequestMapping(value = "/test")
public String greetings() {
System.out.println("接口被访问了~~~");
return "{\"project\":\"just a test\"}";
}
}
package net.xiayule.spring.cors.SpringBootCorsTest.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@RequestMapping("/demo")
public String getDemo() {
System.out.println("demo接口被访问到了~~~");
return "hello demo";
}
}
package net.xiayule.spring.cors.SpringBootCorsTest.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/demo/**")
.allowedOrigins("http://localhost:9000", "null")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
}
}
在本地新建一个demo.html,然后写入以下代码
Hello CORS
<script src="./jquery-3.2.1.min.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url: "http://localhost:8080/demo",
method: "POST",
contentType: "application/json; charset=utf-8"
}).then(function(data, status, jqxhr) {
alert(data)
});
});
</script>
因此你从这个null域,发送了一个ajax请求到我的服务器域地址,这就构成了一个跨域请求的案例
下面这个例子和我们生产中使用的非常相似
package com.snbc.platform.registry.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 描述: 使用Filter 处理跨域请求,即CORS(跨来源资源共享)。
*
* @author city space
*/
@Configuration
public class SimpleCORS {
/**
* 设置 跨域请求参数,处理跨域请求
*
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 原始请求的域名
corsConfiguration.addAllowedOrigin("*");
// 服务器支持的所有跨域请求的方法
corsConfiguration.addAllowedMethod("PUT, POST, GET, OPTIONS, DELETE");
// 添加请求头字段
corsConfiguration
.addAllowedHeader("X-Auth-Token,Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, x-xsrf-token, Accept,Last-Modified, accesstoken, Cache-Control, Expires, Content-Type, X-E4M-With");
// 允许请求发送Cookie
corsConfiguration.setAllowCredentials(true);
// 预检请求的有效期,单位为秒。
corsConfiguration.setMaxAge(3600L);
return corsConfiguration;
}
}
# ===================================================================
# Spring Boot configuration for the "dev" profile.
#
# This configuration overrides the application.yml file.
#
# More information on profiles: https://platform.github.io/profiles/
# More information on configuration properties: https://platform.github.io/common-application-properties/
# ===================================================================
# ===================================================================
# Standard Spring Boot properties.
# Full reference is available at:
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
# ===================================================================
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://admin:${platform.registry.password}@localhost:8761/eureka/
spring:
profiles:
active: dev
include: swagger
devtools:
restart:
enabled: true
livereload:
enabled: false # we use gulp + BrowserSync for livereload
jackson:
serialization.indent_output: true
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://192.168.160.146:3306/uaa?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: SNBC123abc!
hikari:
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
jpa:
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
database: MYSQL
show-sql: true
properties:
hibernate.id.new_generator_mappings: true
hibernate.cache.use_second_level_cache: true
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
hibernate.cache.hazelcast.instance_name: uaa
hibernate.cache.use_minimal_puts: true
hibernate.cache.hazelcast.use_lite_member: true
mail:
host: localhost
port: 25
username:
password:
messages:
cache-seconds: 1
thymeleaf:
cache: false
zipkin: # Use the "zipkin" Maven profile to have the Spring Cloud Zipkin dependencies
base-url: http://localhost:9411
enabled: false
locator:
discovery:
enabled: true
liquibase:
contexts: dev
# ===================================================================
# To enable SSL, generate a certificate using:
# keytool -genkey -alias uaa -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
#
# You can also use Let's Encrypt:
# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
#
# Then, modify the server.ssl properties so your "server" configuration looks like:
#
# server:
# port: 8443
# ssl:
# key-store: keystore.p12
# key-store-password:
# keyStoreType: PKCS12
# keyAlias: uaa
# ===================================================================
server:
port: 9999
# ===================================================================
# JHipster specific properties
#
# Full reference is available at: https://platform.github.io/common-application-properties/
# ===================================================================
platform:
http:
version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
cache: # Cache configuration
ehcache: # Ehcache configuration
time-to-live-seconds: 3600 # By default objects stay 1 hour in the cache
max-entries: 100 # Number of objects in each cache entry
# CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API
cors:
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
security:
client-authorization:
client-id: internal
client-secret: internal
mail: # specific JHipster mail property, for standard properties see MailProperties
from: uaa@localhost
base-url: http://127.0.0.1:9999
metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
jmx.enabled: true
graphite: # Use the "graphite" Maven profile to have the Graphite dependencies
enabled: false
host: localhost
port: 2003
prefix: uaa
prometheus: # Use the "prometheus" Maven profile to have the Prometheus dependencies
enabled: false
endpoint: /prometheusMetrics
logs: # Reports Dropwizard metrics in the logs
enabled: false
report-frequency: 60 # in seconds
logging:
logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
enabled: false
host: localhost
port: 5000
queue-size: 512
# ===================================================================
# Application specific properties
# Add your own application properties here, see the ApplicationProperties class
# to have type-safe configuration, like in the platformProperties above
#
# More documentation is available at:
# https://platform.github.io/common-application-properties/
# ===================================================================
application:
/*
* Copyright 2016-2017 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://platform.github.io/
* for more information.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.snbc.platform.common.config;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.cors.CorsConfiguration;
/**
* Properties specific to Platform.
*
*
* Properties are configured in the application.yml file.
*
*
* @author liGang
*/
@ConfigurationProperties(prefix = "platform", ignoreUnknownFields = false)
public class PlatformProperties {
/**
* 异步配置
*/
private final Async async = new Async();
/**
* Http协议配置
*/
private final Http http = new Http();
/**
* 缓存配置
*/
private final Cache cache = new Cache();
/**
* EMail 配置
*/
private final Mail mail = new Mail();
/**
* 安全配置
*/
private final Security security = new Security();
/**
* Swagger配置
*/
private final Swagger swagger = new Swagger();
/**
* 指标配置
*/
private final Metrics metrics = new Metrics();
/**
* CORS配置
*/
private final CorsConfiguration cors = new CorsConfiguration();
/**
* social配置
*/
private final Social social = new Social();
/**
* Gateway配置
*/
private final Gateway gateway = new Gateway();
/**
* Ribbon配置
*/
private final Ribbon ribbon = new Ribbon();
/**
* Registry配置
*/
private final Registry registry = new Registry();
public Async getAsync() {
return async;
}
public Http getHttp() {
return http;
}
public Cache getCache() {
return cache;
}
public Mail getMail() {
return mail;
}
public Registry getRegistry() {
return registry;
}
public Security getSecurity() {
return security;
}
public Swagger getSwagger() {
return swagger;
}
public Metrics getMetrics() {
return metrics;
}
public CorsConfiguration getCors() {
return cors;
}
public Social getSocial() {
return social;
}
public Gateway getGateway() {
return gateway;
}
public Ribbon getRibbon() {
return ribbon;
}
public static class Async {
private int corePoolSize = 2;
private int maxPoolSize = 50;
private int queueCapacity = 10000;
public int getCorePoolSize() {
return corePoolSize;
}
public void setCorePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
}
public int getMaxPoolSize() {
return maxPoolSize;
}
public void setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}
public int getQueueCapacity() {
return queueCapacity;
}
public void setQueueCapacity(int queueCapacity) {
this.queueCapacity = queueCapacity;
}
}
public static class Http {
public enum Version {
V_1_1, V_2_0
}
private final Cache cache = new Cache();
/**
* HTTP version, must be "V_1_1" (for HTTP/1.1) or V_2_0 (for (HTTP/2)
*/
public Version version = Version.V_1_1;
public Cache getCache() {
return cache;
}
public Version getVersion() {
return version;
}
public void setVersion(Version version) {
this.version = version;
}
public static class Cache {
private int timeToLiveInDays = 1461;
public int getTimeToLiveInDays() {
return timeToLiveInDays;
}
public void setTimeToLiveInDays(int timeToLiveInDays) {
this.timeToLiveInDays = timeToLiveInDays;
}
}
}
public static class Cache {
private final Hazelcast hazelcast = new Hazelcast();
private final Ehcache ehcache = new Ehcache();
private final Infinispan infinispan = new Infinispan();
public Hazelcast getHazelcast() {
return hazelcast;
}
public Ehcache getEhcache() {
return ehcache;
}
public Infinispan getInfinispan() {
return infinispan;
}
public static class Hazelcast {
private int timeToLiveSeconds = 3600;
private int backupCount = 1;
public int getTimeToLiveSeconds() {
return timeToLiveSeconds;
}
public void setTimeToLiveSeconds(int timeToLiveSeconds) {
this.timeToLiveSeconds = timeToLiveSeconds;
}
public int getBackupCount() {
return backupCount;
}
public void setBackupCount(int backupCount) {
this.backupCount = backupCount;
}
}
public static class Ehcache {
private int timeToLiveSeconds = 3600;
private long maxEntries = 100;
public int getTimeToLiveSeconds() {
return timeToLiveSeconds;
}
public void setTimeToLiveSeconds(int timeToLiveSeconds) {
this.timeToLiveSeconds = timeToLiveSeconds;
}
public long getMaxEntries() {
return maxEntries;
}
public void setMaxEntries(long maxEntries) {
this.maxEntries = maxEntries;
}
}
public static class Infinispan {
private String configFile = "default-configs/default-jgroups-tcp.xml";
private boolean statsEnabled;
private final Local local = new Local();
private final Distributed distributed = new Distributed();
private final Replicated replicated = new Replicated();
public String getConfigFile() {
return configFile;
}
public void setConfigFile(String configFile) {
this.configFile = configFile;
}
public boolean isStatsEnabled() {
return statsEnabled;
}
public void setStatsEnabled(boolean statsEnabled) {
this.statsEnabled = statsEnabled;
}
public Local getLocal() {
return local;
}
public Distributed getDistributed() {
return distributed;
}
public Replicated getReplicated() {
return replicated;
}
public static class Local {
private long timeToLiveSeconds = 60;
private long maxEntries = 100;
public long getTimeToLiveSeconds() {
return timeToLiveSeconds;
}
public void setTimeToLiveSeconds(long timeToLiveSeconds) {
this.timeToLiveSeconds = timeToLiveSeconds;
}
public long getMaxEntries() {
return maxEntries;
}
public void setMaxEntries(long maxEntries) {
this.maxEntries = maxEntries;
}
}
public static class Distributed {
private long timeToLiveSeconds = 60;
private long maxEntries = 100;
private int instanceCount = 1;
public long getTimeToLiveSeconds() {
return timeToLiveSeconds;
}
public void setTimeToLiveSeconds(long timeToLiveSeconds) {
this.timeToLiveSeconds = timeToLiveSeconds;
}
public long getMaxEntries() {
return maxEntries;
}
public void setMaxEntries(long maxEntries) {
this.maxEntries = maxEntries;
}
public int getInstanceCount() {
return instanceCount;
}
public void setInstanceCount(int instanceCount) {
this.instanceCount = instanceCount;
}
}
public static class Replicated {
private long timeToLiveSeconds = 60;
private long maxEntries = 100;
public long getTimeToLiveSeconds() {
return timeToLiveSeconds;
}
public void setTimeToLiveSeconds(long timeToLiveSeconds) {
this.timeToLiveSeconds = timeToLiveSeconds;
}
public long getMaxEntries() {
return maxEntries;
}
public void setMaxEntries(long maxEntries) {
this.maxEntries = maxEntries;
}
}
}
}
public static class Mail {
private String from = "";
private String baseUrl = "";
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
}
public static class Security {
private final RememberMe rememberMe = new RememberMe();
private final ClientAuthorization clientAuthorization = new ClientAuthorization();
private final Authentication authentication = new Authentication();
public RememberMe getRememberMe() {
return rememberMe;
}
public ClientAuthorization getClientAuthorization() {
return clientAuthorization;
}
public Authentication getAuthentication() {
return authentication;
}
public static class ClientAuthorization {
private String accessTokenUri;
private String tokenServiceId;
private String clientId;
private String clientSecret;
public String getAccessTokenUri() {
return accessTokenUri;
}
public void setAccessTokenUri(String accessTokenUri) {
this.accessTokenUri = accessTokenUri;
}
public String getTokenServiceId() {
return tokenServiceId;
}
public void setTokenServiceId(String tokenServiceId) {
this.tokenServiceId = tokenServiceId;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
}
public static class Authentication {
private final Oauth oauth = new Oauth();
private final Jwt jwt = new Jwt();
public Oauth getOauth() {
return oauth;
}
public Jwt getJwt() {
return jwt;
}
public static class Oauth {
private String clientId;
private String clientSecret;
private int tokenValidityInSeconds = 1800;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public int getTokenValidityInSeconds() {
return tokenValidityInSeconds;
}
public void setTokenValidityInSeconds(int tokenValidityInSeconds) {
this.tokenValidityInSeconds = tokenValidityInSeconds;
}
}
public static class Jwt {
private String secret;
private long tokenValidityInSeconds = 1800;
private long tokenValidityInSecondsForRememberMe = 2592000;
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public long getTokenValidityInSeconds() {
return tokenValidityInSeconds;
}
public void setTokenValidityInSeconds(long tokenValidityInSeconds) {
this.tokenValidityInSeconds = tokenValidityInSeconds;
}
public long getTokenValidityInSecondsForRememberMe() {
return tokenValidityInSecondsForRememberMe;
}
public void setTokenValidityInSecondsForRememberMe(long tokenValidityInSecondsForRememberMe) {
this.tokenValidityInSecondsForRememberMe = tokenValidityInSecondsForRememberMe;
}
}
}
public static class RememberMe {
@NotNull
private String key;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
}
public static class Swagger {
private String title = "Application API";
private String description = "API documentation";
private String version = "0.0.1";
private String termsOfServiceUrl;
private String contactName;
private String contactUrl;
private String contactEmail;
private String license;
private String licenseUrl;
private String defaultIncludePattern = "/api/.*";
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTermsOfServiceUrl() {
return termsOfServiceUrl;
}
public void setTermsOfServiceUrl(String termsOfServiceUrl) {
this.termsOfServiceUrl = termsOfServiceUrl;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getContactUrl() {
return contactUrl;
}
public void setContactUrl(String contactUrl) {
this.contactUrl = contactUrl;
}
public String getContactEmail() {
return contactEmail;
}
public void setContactEmail(String contactEmail) {
this.contactEmail = contactEmail;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public String getLicenseUrl() {
return licenseUrl;
}
public void setLicenseUrl(String licenseUrl) {
this.licenseUrl = licenseUrl;
}
public String getDefaultIncludePattern() {
return defaultIncludePattern;
}
public void setDefaultIncludePattern(String defaultIncludePattern) {
this.defaultIncludePattern = defaultIncludePattern;
}
}
public static class Metrics {
private final Jmx jmx = new Jmx();
private final Graphite graphite = new Graphite();
private final Prometheus prometheus = new Prometheus();
private final Logs logs = new Logs();
public Jmx getJmx() {
return jmx;
}
public Graphite getGraphite() {
return graphite;
}
public Prometheus getPrometheus() {
return prometheus;
}
public Logs getLogs() {
return logs;
}
public static class Jmx {
private boolean enabled = true;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
public static class Graphite {
private boolean enabled = false;
private String host = "localhost";
private int port = 2003;
private String prefix = "jhipsterApplication";
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
}
public static class Prometheus {
private boolean enabled = false;
private String endpoint = "/prometheusMetrics";
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
}
public static class Logs {
private boolean enabled = false;
private long reportFrequency = 60;
public long getReportFrequency() {
return reportFrequency;
}
public void setReportFrequency(int reportFrequency) {
this.reportFrequency = reportFrequency;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}
private final Logging logging = new Logging();
public Logging getLogging() {
return logging;
}
public static class Logging {
private final Logstash logstash = new Logstash();
public Logstash getLogstash() {
return logstash;
}
public static class Logstash {
private boolean enabled = false;
private String host = "localhost";
private int port = 5000;
private int queueSize = 512;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getQueueSize() {
return queueSize;
}
public void setQueueSize(int queueSize) {
this.queueSize = queueSize;
}
}
private final SpectatorMetrics spectatorMetrics = new SpectatorMetrics();
public SpectatorMetrics getSpectatorMetrics() {
return spectatorMetrics;
}
public static class SpectatorMetrics {
private boolean enabled = false;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}
public static class Social {
private String redirectAfterSignIn = "/#/home";
public String getRedirectAfterSignIn() {
return redirectAfterSignIn;
}
public void setRedirectAfterSignIn(String redirectAfterSignIn) {
this.redirectAfterSignIn = redirectAfterSignIn;
}
}
public static class Gateway {
private final RateLimiting rateLimiting = new RateLimiting();
public RateLimiting getRateLimiting() {
return rateLimiting;
}
private Map
> authorizedMicroservicesEndpoints = new LinkedHashMap<>();
public Map
> getAuthorizedMicroservicesEndpoints() {
return authorizedMicroservicesEndpoints;
}
public void setAuthorizedMicroservicesEndpoints(Map
> authorizedMicroservicesEndpoints) {
this.authorizedMicroservicesEndpoints = authorizedMicroservicesEndpoints;
}
public static class RateLimiting {
private boolean enabled = false;
private long limit = 100_000L;
private int durationInSeconds = 3_600;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public long getLimit() {
return this.limit;
}
public void setLimit(long limit) {
this.limit = limit;
}
public int getDurationInSeconds() {
return durationInSeconds;
}
public void setDurationInSeconds(int durationInSeconds) {
this.durationInSeconds = durationInSeconds;
}
}
}
public static class Ribbon {
private String[] displayOnActiveProfiles;
public String[] getDisplayOnActiveProfiles() {
return displayOnActiveProfiles;
}
public void setDisplayOnActiveProfiles(String[] displayOnActiveProfiles) {
this.displayOnActiveProfiles = displayOnActiveProfiles;
}
}
private static class Registry {
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
}
package com.snbc.platform.registry.config;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.servlet.InstrumentedFilter;
import com.codahale.metrics.servlets.MetricsServlet;
import com.snbc.platform.common.config.PlatformConstants;
import com.snbc.platform.common.config.PlatformProperties;
import com.snbc.platform.common.web.filter.CachingHttpHeadersFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.*;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import io.undertow.UndertowOptions;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.io.File;
import java.nio.file.Paths;
import java.util.*;
import javax.servlet.*;
/**
* Configuration of web application with Servlet 3.0 APIs.
*/
@Configuration
public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {
private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
private final Environment env;
private final PlatformProperties platformProperties;
private MetricRegistry metricRegistry;
public WebConfigurer(Environment env, PlatformProperties platformProperties) {
this.env = env;
this.platformProperties = platformProperties;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
if (env.getActiveProfiles().length != 0) {
log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
}
EnumSet
disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC); initMetrics(servletContext, disps); if (env.acceptsProfiles(PlatformConstants.SPRING_PROFILE_PRODUCTION)) { initCachingHttpHeadersFilter(servletContext, disps); } log.info("Web application fully configured"); } /** * Customize the Servlet engine: Mime types, the document root, the cache. */ @Override public void customize(ConfigurableEmbeddedServletContainer container) { MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT); // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711 mappings.add("html", "text/html;charset=utf-8"); // CloudFoundry issue, see // https://github.com/cloudfoundry/gorouter/issues/64 mappings.add("json", "text/html;charset=utf-8"); container.setMimeMappings(mappings); // When running in an IDE or with ./mvnw spring-boot:run, set location // of the static web assets. setLocationForStaticAssets(container); /* * Enable HTTP/2 for Undertow - * https://twitter.com/ankinson/status/829256167700492288 HTTP/2 * requires HTTPS, so HTTP requests will fallback to HTTP/1.1. See the * platformProperties class and your application-*.yml configuration * files for more information. */ if (platformProperties.getHttp().getVersion().equals(PlatformProperties.Http.Version.V_2_0) && container instanceof UndertowEmbeddedServletContainerFactory) { ((UndertowEmbeddedServletContainerFactory) container) .addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true)); } } private void setLocationForStaticAssets(ConfigurableEmbeddedServletContainer container) { File root; String prefixPath = resolvePathPrefix(); root = new File(prefixPath + "target/www/"); if (root.exists() && root.isDirectory()) { container.setDocumentRoot(root); } } /** * Resolve path prefix to static resources. */ private String resolvePathPrefix() { String fullExecutablePath = this.getClass().getResource("").getPath(); String rootPath = Paths.get(".").toUri().normalize().getPath(); String extractedPath = fullExecutablePath.replace(rootPath, ""); int extractionEndIndex = extractedPath.indexOf("target/"); if (extractionEndIndex <= 0) { return ""; } return extractedPath.substring(0, extractionEndIndex); } /** * Initializes the caching HTTP Headers Filter. */ private void initCachingHttpHeadersFilter(ServletContext servletContext, EnumSet
disps) { log.debug("Registering Caching HTTP Headers Filter"); FilterRegistration.Dynamic cachingHttpHeadersFilter = servletContext.addFilter("cachingHttpHeadersFilter", new CachingHttpHeadersFilter(platformProperties)); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/content/*"); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/app/*"); cachingHttpHeadersFilter.setAsyncSupported(true); } /** * Initializes Metrics. */ private void initMetrics(ServletContext servletContext, EnumSet
disps) { log.debug("Initializing Metrics registries"); servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE, metricRegistry); servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY, metricRegistry); log.debug("Registering Metrics Filter"); FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter", new InstrumentedFilter()); metricsFilter.addMappingForUrlPatterns(disps, true, "/*"); metricsFilter.setAsyncSupported(true); log.debug("Registering Metrics Servlet"); ServletRegistration.Dynamic metricsAdminServlet = servletContext.addServlet("metricsServlet", new MetricsServlet()); metricsAdminServlet.addMapping("/management/metrics/*"); metricsAdminServlet.setAsyncSupported(true); metricsAdminServlet.setLoadOnStartup(2); } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = platformProperties.getCors(); if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) { log.debug("Registering CORS filter"); source.registerCorsConfiguration("/api/**", config); source.registerCorsConfiguration("/v2/api-docs", config); source.registerCorsConfiguration("/*/api/**", config); source.registerCorsConfiguration("/management/**", config); source.registerCorsConfiguration("/*/management/**", config); } return new CorsFilter(source); } @Autowired(required = false) public void setMetricRegistry(MetricRegistry metricRegistry) { this.metricRegistry = metricRegistry; } }