2017年8月22日---阶段性工作总结(跨域访问)

来源:互联网 发布:excel数据透视图公式 编辑:程序博客网 时间:2024/06/06 17:30

近期工作中,主要做一个平台项目,接触了一些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;@RestControllerpublic 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;@Configurationpublic 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        
然后你直接打开的方式去访问,你会看到地址为:file:///D:/work/demo.html

因此你从这个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 */@Configurationpublic 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: trueliquibase:    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. */@Configurationpublic 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; }}







原创粉丝点击