/* * Copyright 2012-2017 the original author or authors. * * 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 org.springframework.boot.autoconfigure.security; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.util.StringUtils; /** * Properties for the security aspects of an application. * * @author Dave Syer * @author Andy Wilkinson */ @ConfigurationProperties(prefix = "security") public class SecurityProperties implements SecurityPrerequisite { /** * Order before the basic authentication access control provided by Boot. This is a * useful place to put user-defined access rules if you want to override the default * access rules. */ public static final int ACCESS_OVERRIDE_ORDER = SecurityProperties.BASIC_AUTH_ORDER - 2; /** * Order applied to the WebSecurityConfigurerAdapter that is used to configure basic * authentication for application endpoints. If you want to add your own * authentication for all or some of those endpoints the best thing to do is to add * your own WebSecurityConfigurerAdapter with lower order. */ public static final int BASIC_AUTH_ORDER = Ordered.LOWEST_PRECEDENCE - 5; /** * Order applied to the WebSecurityConfigurer that ignores standard static resource * paths. */ public static final int IGNORED_ORDER = Ordered.HIGHEST_PRECEDENCE; /** * Default order of Spring Security's Filter in the servlet container (i.e. amongst * other filters registered with the container). There is no connection between this * and the <code>@Order</code> on a WebSecurityConfigurer. */ public static final int DEFAULT_FILTER_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100; /** * Enable secure channel for all requests. */ private boolean requireSsl; /** * Enable Cross Site Request Forgery support. */ // Flip this when session creation is disabled by default private boolean enableCsrf = false; private Basic basic = new Basic(); private final Headers headers = new Headers(); /** * Session creation policy (always, never, if_required, stateless). */ private SessionCreationPolicy sessions = SessionCreationPolicy.STATELESS; /** * Comma-separated list of paths to exclude from the default secured paths. */ private List<String> ignored = new ArrayList<>(); private final User user = new User(); /** * Security filter chain order. */ private int filterOrder = DEFAULT_FILTER_ORDER; /** * Security filter chain dispatcher types. */ private Set<String> filterDispatcherTypes = new HashSet<>( Arrays.asList("ASYNC", "ERROR", "REQUEST")); public Headers getHeaders() { return this.headers; } public User getUser() { return this.user; } public SessionCreationPolicy getSessions() { return this.sessions; } public void setSessions(SessionCreationPolicy sessions) { this.sessions = sessions; } public Basic getBasic() { return this.basic; } public void setBasic(Basic basic) { this.basic = basic; } public boolean isRequireSsl() { return this.requireSsl; } public void setRequireSsl(boolean requireSsl) { this.requireSsl = requireSsl; } public boolean isEnableCsrf() { return this.enableCsrf; } public void setEnableCsrf(boolean enableCsrf) { this.enableCsrf = enableCsrf; } public void setIgnored(List<String> ignored) { this.ignored = new ArrayList<>(ignored); } public List<String> getIgnored() { return this.ignored; } public int getFilterOrder() { return this.filterOrder; } public void setFilterOrder(int filterOrder) { this.filterOrder = filterOrder; } public Set<String> getFilterDispatcherTypes() { return this.filterDispatcherTypes; } public void setFilterDispatcherTypes(Set<String> filterDispatcherTypes) { this.filterDispatcherTypes = filterDispatcherTypes; } public static class Headers { public enum HSTS { NONE, DOMAIN, ALL } public enum ContentSecurityPolicyMode { /** * Use the 'Content-Security-Policy' header. */ DEFAULT, /** * Use the 'Content-Security-Policy-Report-Only' header. */ REPORT_ONLY } /** * Enable cross site scripting (XSS) protection. */ private boolean xss = true; /** * Enable cache control HTTP headers. */ private boolean cache = true; /** * Enable "X-Frame-Options" header. */ private boolean frame = true; /** * Enable "X-Content-Type-Options" header. */ private boolean contentType = true; /** * Value for content security policy header. */ private String contentSecurityPolicy; /** * Content security policy mode. */ private ContentSecurityPolicyMode contentSecurityPolicyMode = ContentSecurityPolicyMode.DEFAULT; /** * HTTP Strict Transport Security (HSTS) mode (none, domain, all). */ private HSTS hsts = HSTS.ALL; public boolean isXss() { return this.xss; } public void setXss(boolean xss) { this.xss = xss; } public boolean isCache() { return this.cache; } public void setCache(boolean cache) { this.cache = cache; } public boolean isFrame() { return this.frame; } public void setFrame(boolean frame) { this.frame = frame; } public boolean isContentType() { return this.contentType; } public void setContentType(boolean contentType) { this.contentType = contentType; } public String getContentSecurityPolicy() { return this.contentSecurityPolicy; } public void setContentSecurityPolicy(String contentSecurityPolicy) { this.contentSecurityPolicy = contentSecurityPolicy; } public ContentSecurityPolicyMode getContentSecurityPolicyMode() { return this.contentSecurityPolicyMode; } public void setContentSecurityPolicyMode( ContentSecurityPolicyMode contentSecurityPolicyMode) { this.contentSecurityPolicyMode = contentSecurityPolicyMode; } public HSTS getHsts() { return this.hsts; } public void setHsts(HSTS hsts) { this.hsts = hsts; } } public static class Basic { /** * Enable basic authentication. */ private boolean enabled = true; /** * HTTP basic realm name. */ private String realm = "Spring"; /** * Comma-separated list of paths to secure. */ private String[] path = new String[] { "/**" }; /** * Security authorize mode to apply. */ private SecurityAuthorizeMode authorizeMode = SecurityAuthorizeMode.ROLE; public boolean isEnabled() { return this.enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public String getRealm() { return this.realm; } public void setRealm(String realm) { this.realm = realm; } public String[] getPath() { return this.path; } public void setPath(String... paths) { this.path = paths; } public SecurityAuthorizeMode getAuthorizeMode() { return this.authorizeMode; } public void setAuthorizeMode(SecurityAuthorizeMode authorizeMode) { this.authorizeMode = authorizeMode; } } public static class User { /** * Default user name. */ private String name = "user"; /** * Password for the default user name. */ private String password = UUID.randomUUID().toString(); /** * Granted roles for the default user name. */ private List<String> role = new ArrayList<>(Collections.singletonList("USER")); private boolean defaultPassword = true; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getPassword() { return this.password; } public void setPassword(String password) { if (password.startsWith("${") && password.endsWith("}") || !StringUtils.hasLength(password)) { return; } this.defaultPassword = false; this.password = password; } public List<String> getRole() { return this.role; } public void setRole(List<String> role) { this.role = new ArrayList<>(role); } public boolean isDefaultPassword() { return this.defaultPassword; } } }