/* * Copyright 2002-2013 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.security.web.header.writers.frameoptions; import org.springframework.security.web.header.HeaderWriter; import org.springframework.util.Assert; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * {@code HeaderWriter} implementation for the X-Frame-Options headers. When using the * ALLOW-FROM directive the actual value is determined by a {@code AllowFromStrategy}. * * @author Marten Deinum * @author Rob Winch * @since 3.2 * * @see AllowFromStrategy */ public final class XFrameOptionsHeaderWriter implements HeaderWriter { public static final String XFRAME_OPTIONS_HEADER = "X-Frame-Options"; private final AllowFromStrategy allowFromStrategy; private final XFrameOptionsMode frameOptionsMode; /** * Creates an instance with {@link XFrameOptionsMode#DENY} */ public XFrameOptionsHeaderWriter() { this(XFrameOptionsMode.DENY); } /** * Creates a new instance * * @param frameOptionsMode the {@link XFrameOptionsMode} to use. If using * {@link XFrameOptionsMode#ALLOW_FROM}, use * {@link #XFrameOptionsHeaderWriter(AllowFromStrategy)} instead. */ public XFrameOptionsHeaderWriter(XFrameOptionsMode frameOptionsMode) { Assert.notNull(frameOptionsMode, "frameOptionsMode cannot be null"); if (XFrameOptionsMode.ALLOW_FROM.equals(frameOptionsMode)) { throw new IllegalArgumentException( "ALLOW_FROM requires an AllowFromStrategy. Please use FrameOptionsHeaderWriter(AllowFromStrategy allowFromStrategy) instead"); } this.frameOptionsMode = frameOptionsMode; this.allowFromStrategy = null; } /** * Creates a new instance with {@link XFrameOptionsMode#ALLOW_FROM}. * * @param allowFromStrategy the strategy for determining what the value for ALLOW_FROM * is. */ public XFrameOptionsHeaderWriter(AllowFromStrategy allowFromStrategy) { Assert.notNull(allowFromStrategy, "allowFromStrategy cannot be null"); this.frameOptionsMode = XFrameOptionsMode.ALLOW_FROM; this.allowFromStrategy = allowFromStrategy; } /** * Writes the X-Frame-Options header value, overwritting any previous value. * * @param request the servlet request * @param response the servlet response */ public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { if (XFrameOptionsMode.ALLOW_FROM.equals(frameOptionsMode)) { String allowFromValue = allowFromStrategy.getAllowFromValue(request); if (allowFromValue != null) { response.setHeader(XFRAME_OPTIONS_HEADER, XFrameOptionsMode.ALLOW_FROM.getMode() + " " + allowFromValue); } } else { response.setHeader(XFRAME_OPTIONS_HEADER, frameOptionsMode.getMode()); } } /** * The possible values for the X-Frame-Options header. * * @author Rob Winch * @since 3.2 */ public enum XFrameOptionsMode { DENY("DENY"), SAMEORIGIN("SAMEORIGIN"), ALLOW_FROM("ALLOW-FROM"); private String mode; private XFrameOptionsMode(String mode) { this.mode = mode; } /** * Gets the mode for the X-Frame-Options header value. For example, DENY, * SAMEORIGIN, ALLOW-FROM. Cannot be null. * * @return the mode for the X-Frame-Options header value. */ private String getMode() { return mode; } } }