/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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.alibaba.citrus.dev.handler.component; import static com.alibaba.citrus.util.BasicConstant.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static com.alibaba.citrus.util.ObjectUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.Enumeration; import java.util.List; import java.util.regex.Pattern; import com.alibaba.citrus.util.internal.webpagelite.PageComponent; import com.alibaba.citrus.util.internal.webpagelite.PageComponentRegistry; import com.alibaba.citrus.util.regex.ClassNameWildcardCompiler; import com.alibaba.citrus.webx.handler.RequestHandlerContext; import com.alibaba.citrus.webx.handler.support.AbstractVisitor; /** * 用来避免从非授权的机器上访问开发者页面的组件。 * * @author Michael Zhou */ public class AccessControlComponent extends PageComponent { private static final String PROPERTY_ALLOWD_HOSTS = "developmentMode.allowedHosts"; private final Pattern[] allowdHostPatterns; public AccessControlComponent(PageComponentRegistry registry, String componentPath) { super(registry, componentPath); String[] allowedHosts = split(defaultIfNull(System.getProperty(PROPERTY_ALLOWD_HOSTS), EMPTY_STRING), ", "); List<Pattern> patterns = createLinkedList(); for (String allowedHost : allowedHosts) { patterns.add(ClassNameWildcardCompiler.compileClassName(allowedHost)); } this.allowdHostPatterns = patterns.toArray(new Pattern[patterns.size()]); } public boolean accessAllowed(RequestHandlerContext context) { if (checkPermission(context)) { return true; } else { getTemplate().accept(new AccessDeniedVisitor(context)); return false; } } private boolean checkPermission(RequestHandlerContext context) { String remoteAddr = getRemoteAddr(context); try { InetAddress addr = InetAddress.getByName(remoteAddr); for (Pattern allowedHostPattern : allowdHostPatterns) { if (allowedHostPattern.matcher(remoteAddr).matches()) { return true; } } // 总是接受localhost if (addr.isLoopbackAddress()) { return true; } else { // 总是接受当前主机中任意一块网卡的任意ip for (Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements(); ) { for (Enumeration<InetAddress> f = e.nextElement().getInetAddresses(); f.hasMoreElements(); ) { if (addr.equals(f.nextElement())) { return true; } } } } } catch (Exception e) { } return false; } private String getRemoteAddr(RequestHandlerContext context) { return trimToNull(context.getRequest().getRemoteAddr()); } @SuppressWarnings("unused") private class AccessDeniedVisitor extends AbstractVisitor { public AccessDeniedVisitor(RequestHandlerContext context) { super(context, AccessControlComponent.this); } public void visitPropertyName() { out().print(PROPERTY_ALLOWD_HOSTS); } public void visitPropertyValue() { String remoteAddr = getRemoteAddr(context); if (remoteAddr != null) { out().print(remoteAddr); } } public void visitPropertyValueWildcard() { String remoteAddr = getRemoteAddr(context); if (remoteAddr != null) { out().print(remoteAddr.substring(0, remoteAddr.lastIndexOf(".") + 1) + "*"); } } } }