/* * Copyright (c) 2008-2016 Computer Network Information Center (CNIC), Chinese Academy of Sciences. * * This file is part of Duckling project. * * 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 cn.vlabs.duckling.api.umt.sso; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import cn.vlabs.duckling.common.util.ClassUtil; /** * Introduction Here. * @date 2010-6-29 * @author Fred Zhang (fred@cnic.cn) */ public class LoginFilter implements Filter{ private static final Logger LOG =Logger.getLogger(LoginFilter.class); private ArrayList<Pattern> ignoreList; public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest pRequest = (HttpServletRequest)request; HttpServletResponse pResponse = (HttpServletResponse)response; UserContext userContext = SessionUtil.getUserContext(pRequest); if(userContext == null&&needLoginRequest(pRequest)) { Map<String,String> params = new HashMap<String,String>(); String loginHandClass = SSOProperties.getInstance().getProperty(ILoginHandle.UMT_LOGIN_EXTHANDLE_CLASS); Object object = null; if(loginHandClass!=null) { object = ClassUtil.classInstance(loginHandClass); if(object!=null) { ((ILoginHandle)object).initBeforLogin((HttpServletRequest)request, (HttpServletResponse)response,params); } } String uri = pRequest.getRequestURL().toString(); String fullRequest = uri; String queryString = pRequest.getQueryString(); if (queryString!=null) { fullRequest=fullRequest+"?"+queryString; } SessionUtil.setUserRedirectUrl(pRequest, fullRequest); pResponse.sendRedirect(makeUmtLoginURL(pRequest,params)); }else { chain.doFilter(request, response); return; } } private boolean needLoginRequest(HttpServletRequest request) { String uri = request.getRequestURI(); String contexPath=request.getContextPath(); if (contexPath!=null && contexPath.length()>0){ uri = uri.substring(contexPath.length()); } for (Pattern p:ignoreList){ if (p.matcher(uri).matches()){ return false; } } return true; } private String extract(String url){ int index = url.indexOf('/', 7); if (index==-1) return url; else return url.substring(0, index); } private String makeUmtLoginURL(HttpServletRequest request,Map<String,String> extParamsToUmt) { String localURL = extract(request.getRequestURL().toString()); localURL = localURL +request.getContextPath() +"/login"; String url = null; String defaultLogoutUrl = "http://"+request.getLocalAddr(); if (request.getLocalPort()!=80){ defaultLogoutUrl =defaultLogoutUrl+":"+request.getLocalPort(); } defaultLogoutUrl = defaultLogoutUrl+request.getContextPath()+"/logout"; StringBuffer extparams = new StringBuffer(); try { for(Entry<String,String> entry:extParamsToUmt.entrySet()){ extparams.append("&").append(URLEncoder.encode(entry.getKey(),"UTF-8")).append("=").append(URLEncoder.encode(extParamsToUmt.get(entry.getKey()), "UTF-8")); } String logoutUrl = SSOProperties.getInstance().getProperty(ILoginHandle.LOCALAPP_LOGOUT_URL,defaultLogoutUrl); if(logoutUrl.indexOf("?")>0) { logoutUrl = logoutUrl+"&umtSsoLogout=true"; }else { logoutUrl = logoutUrl+"?umtSsoLogout=true"; } url = getUMTLoginURL() + "?appname=" + URLEncoder.encode(SSOProperties.getInstance().getProperty(ILoginHandle.UMT_AUTH_APPNAME_KEY), "UTF-8") + "&WebServerURL=" + URLEncoder.encode(localURL, "UTF-8") +"&sid="+request.getSession(true).getId() +"&logoutURL="+URLEncoder.encode(logoutUrl, "UTF-8") +extparams.toString(); } catch (UnsupportedEncodingException e) { } return url; } private String getUMTLoginURL() { String umtLoginUrl = SSOProperties.getInstance().getProperty(ILoginHandle.UMT_LOGIN_URL_KEY); umtLoginUrl = umtLoginUrl.trim(); if (umtLoginUrl.endsWith("/")) { umtLoginUrl = umtLoginUrl.substring(0, umtLoginUrl.length() - 1); } return umtLoginUrl; } private void initRules(ServletContext context) { ignoreList = new ArrayList<Pattern>(); String file = SSOProperties.getInstance().getProperty(ILoginHandle.UMT_AUTH_RULE_KEY); file = context.getRealPath(file); BufferedReader reader=null; InputStreamReader isr=null; FileInputStream fis=null; try { fis=new FileInputStream(file); isr=new InputStreamReader(fis, "UTF-8"); reader=new BufferedReader(isr); String line = null; while ((line=reader.readLine())!=null){ line=line.trim(); if (line.length()>0 && !line.startsWith("#")){//A pattern line line = line.replaceAll("/", "\\/"); line = line.replaceAll("\\*", ".*"); Pattern p = Pattern.compile(line); ignoreList.add(p); } } } catch (Exception e) { LOG.error("初始化登录过滤器时失败:"+e.getMessage()); }finally{ try{ if(fis!=null){fis.close();} if(isr!=null){isr.close();} if(reader!=null){reader.close();} }catch(IOException e){ LOG.error(e.getMessage(),e); } } } public void init(FilterConfig filterConfig) throws ServletException { String file = filterConfig.getInitParameter("config"); file = filterConfig.getServletContext().getRealPath(file); SSOProperties.getInstance().initProperties(file, true); initRules(filterConfig.getServletContext()); } }