Java tutorial
/* * Copyright (C) 2010-2101 Alibaba Group Holding Limited. * * 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.otter.manager.web.webx.valve; import static com.alibaba.citrus.turbine.util.TurbineUtil.getTurbineRunData; import static com.alibaba.otter.shared.common.utils.Assert.assertNotNull; import static com.alibaba.citrus.util.StringUtil.trimToNull; import java.util.Enumeration; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import com.alibaba.citrus.service.pipeline.Pipeline; import com.alibaba.citrus.service.pipeline.PipelineContext; import com.alibaba.citrus.service.pipeline.support.AbstractValve; import com.alibaba.citrus.service.uribroker.URIBrokerService; import com.alibaba.citrus.service.uribroker.uri.URIBroker; import com.alibaba.citrus.turbine.TurbineRunData; import com.alibaba.citrus.util.StringUtil; import com.alibaba.otter.manager.web.common.WebConstant; import com.alibaba.otter.manager.web.common.api.ApiAuthService; import com.alibaba.otter.manager.web.webx.valve.auth.RegExpURLAnalyze; import com.alibaba.otter.shared.common.model.user.AuthorizeType; import com.alibaba.otter.shared.common.model.user.User; /** * ?? * * @author jianghang 2011-11-11 ?11:46:11 * @version 4.0.0 */ public class AuthContextValve extends AbstractValve { private static final String DEFAULT_ACTION_PARAM_NAME = "action"; private static final String DEFAULT_EVENT_PATTERN = "event_submit_do_"; private static final String IMAGE_BUTTON_SUFFIX_1 = ".x"; private static final String IMAGE_BUTTON_SUFFIX_2 = ".y"; private static final String IMAGE_BUTTON_SUFFIX_3 = ".X"; private static final String IMAGE_BUTTON_SUFFIX_4 = ".Y"; @Autowired private HttpServletRequest request; @Autowired private URIBrokerService uriBrokerService; @Autowired private RegExpURLAnalyze urlAnalyze; @Autowired private ApiAuthService apiAuthService; private String loginLink = WebConstant.OTTER_LOGIN_LINK; private String forbiddenLink = WebConstant.ERROR_FORBIDDEN_Link; private String redirectParmeter = "Done"; private String actionParam; protected void init() throws Exception { if (actionParam == null) { actionParam = DEFAULT_ACTION_PARAM_NAME; } } public void invoke(PipelineContext pipelineContext) throws Exception { TurbineRunData rundata = getTurbineRunData(request); // TODO api ? if (isAPI(rundata)) { if (apiAuthService.auth(rundata)) { pipelineContext.invokeNext(); } else { redirect(pipelineContext, rundata, forbiddenLink); // TODO ? json ? link } return; } // URL(????/??) String requestUrl = rundata.getRequest().getRequestURI(); List<AuthorizeType> result = urlAnalyze.check(requestUrl); String action = StringUtil.toCamelCase(trimToNull(rundata.getParameters().getString(actionParam))); String eventName = getEventName(); // ? User user = (User) rundata.getRequest().getSession().getAttribute(WebConstant.USER_SESSION_KEY); if (StringUtils.isNotEmpty(action)) { result.addAll(urlAnalyze.check(action, eventName)); } if (result.isEmpty()) { // ?????? redirect(pipelineContext, rundata, forbiddenLink); } else { if (null == user) { // ???? // 1.????? // 2.??????? if (result.contains(AuthorizeType.OPERATOR) || result.contains(AuthorizeType.ADMIN)) { redirect(pipelineContext, rundata, loginLink); } else { pipelineContext.invokeNext(); } } else { // ????? // 1.????? // 2.?????? if (compareAuth(user.getAuthorizeType(), result)) { pipelineContext.invokeNext(); } else { redirect(pipelineContext, rundata, forbiddenLink); } } } } // TODO ?? protected boolean isAPI(TurbineRunData rundata) { String requestUrl = rundata.getRequest().getRequestURI(); return StringUtils.containsIgnoreCase(requestUrl, "/api/"); } private boolean compareAuth(AuthorizeType sType, List<AuthorizeType> dTypes) { // ???true if (sType.isAdmin()) { return true; } // ????????false for (AuthorizeType dType : dTypes) { if ((sType.isOperator() && dType.isAdmin()) || (sType.isAnonymous() && !dType.isAnonymous())) { return false; } } return true; } public boolean isAuthenticated(TurbineRunData rundata) { Map<String, String> user = (Map<String, String>) rundata.getRequest().getSession() .getAttribute(WebConstant.OTTER_USER_SESSION_KEY); if (user == null) { return false; } return true; } private void redirect(PipelineContext pipelineContext, TurbineRunData rundata, String uriBroker) { URIBroker urlBroker = assertNotNull(uriBrokerService.getURIBroker(uriBroker), "uriBroker get from loginLink should not be null"); urlBroker.addQueryData(redirectParmeter, getRequestUrlWithQueryString()); rundata.setRedirectLocation(urlBroker.render()); pipelineContext.breakPipeline(Pipeline.TOP_LABEL); } private String getRequestUrlWithQueryString() { StringBuffer requestUrl = request.getRequestURL(); String queryString = StringUtil.trimToNull(request.getQueryString()); if (!StringUtil.isBlank(queryString)) { requestUrl.append("?").append(queryString); } return requestUrl.toString(); } /** * ?key=eventSubmit_doXyz, value?? */ private String getEventName() { String event = null; @SuppressWarnings("unchecked") Enumeration<String> e = request.getParameterNames(); while (e.hasMoreElements()) { String originalKey = e.nextElement(); String paramKey = StringUtil.toLowerCaseWithUnderscores(originalKey); if (paramKey.startsWith(DEFAULT_EVENT_PATTERN) && !StringUtil.isBlank(request.getParameter(originalKey))) { int startIndex = DEFAULT_EVENT_PATTERN.length(); int endIndex = paramKey.length(); // ?<input type="image"> if (paramKey.endsWith(IMAGE_BUTTON_SUFFIX_1)) { endIndex -= IMAGE_BUTTON_SUFFIX_1.length(); } else if (paramKey.endsWith(IMAGE_BUTTON_SUFFIX_2)) { endIndex -= IMAGE_BUTTON_SUFFIX_2.length(); } else if (paramKey.endsWith(IMAGE_BUTTON_SUFFIX_3)) { endIndex -= IMAGE_BUTTON_SUFFIX_3.length(); } else if (paramKey.endsWith(IMAGE_BUTTON_SUFFIX_4)) { endIndex -= IMAGE_BUTTON_SUFFIX_4.length(); } event = StringUtil.trimToNull(paramKey.substring(startIndex, endIndex)); if (event != null) { break; } } } return event; } public void setLoginLink(String loginLink) { this.loginLink = loginLink; } public void setRedirectParmeter(String redirectParmeter) { this.redirectParmeter = redirectParmeter; } public void setActionParam(String actionParam) { this.actionParam = actionParam; } }