/* * 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.umt.ui.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.springframework.beans.factory.BeanFactory; import cn.vlabs.umt.common.util.CommonUtils; import cn.vlabs.umt.common.util.RandomUtil; import cn.vlabs.umt.common.util.RequestUtil; import cn.vlabs.umt.domain.OauthLog; import cn.vlabs.umt.services.account.IOauthLogService; import cn.vlabs.umt.services.role.RoleService; import cn.vlabs.umt.services.role.UMTRole; import cn.vlabs.umt.services.user.LoginService; import cn.vlabs.umt.services.user.UserService; import cn.vlabs.umt.services.user.bean.LoginInfo; import cn.vlabs.umt.services.user.bean.OauthClientBean; import cn.vlabs.umt.services.user.bean.OauthToken; import cn.vlabs.umt.services.user.bean.Token; import cn.vlabs.umt.services.user.bean.TokenLoginCredential; import cn.vlabs.umt.services.user.bean.User; import cn.vlabs.umt.services.user.service.IOauthClientService; import cn.vlabs.umt.services.user.service.IOauthTokenService; import cn.vlabs.umt.services.user.service.ITokenService; import cn.vlabs.umt.ui.Attributes; import cn.vlabs.umt.ui.UMTContext; /** * @author lvly * @since 2013-9-13 */ public class LoginTokenServlet extends HttpServlet { /** * */ private static final long serialVersionUID = -4979947905914747000L; private static final Logger LOGGER=Logger.getLogger(LoginTokenServlet.class); private IOauthTokenService oauthTokenService; private ITokenService tokenService; private LoginService loginService; private RoleService rs ; private IOauthClientService clientServer; private IOauthLogService logService; private UserService userService; public LoginTokenServlet(){ super(); } public void init(){ BeanFactory factory = (BeanFactory) getServletContext().getAttribute(Attributes.APPLICATION_CONTEXT_KEY); oauthTokenService = (IOauthTokenService)factory.getBean(IOauthTokenService.BEAN_ID); tokenService=(ITokenService)factory.getBean(ITokenService.BEAN_ID); loginService=(LoginService)factory.getBean(LoginService.BEAN_ID); rs=(RoleService) factory.getBean(RoleService.BEAN_ID); clientServer=(IOauthClientService)factory.getBean(IOauthClientService.BEAN_ID); logService=(IOauthLogService)factory.getBean(IOauthLogService.BEAN_ID); userService=(UserService)factory.getBean(UserService.BEAN_ID); } @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action=request.getParameter("action"); if("apply".equals(action)){ apply(request,response); }else if("login".equals(action)){ login(request,response); }else{ error(response,"not such action["+action+"]",null); } } /** * 使用token并登陆 * */ private void login(HttpServletRequest request, HttpServletResponse response)throws IOException { String token=request.getParameter("token"); String returnUrl=request.getParameter("returnUrl"); OauthLog oauthLog=new OauthLog(); oauthLog.setAction(OauthLog.ACTION_VALIDATE_TOKEN_LOGIN); oauthLog.setIp(RequestUtil.getRemoteIP(request)); oauthLog.setUserAgent(request.getHeader("User-Agent")); if(CommonUtils.isNull(token)){ oauthLog.setResult(OauthLog.RESULT_TOKEN_NOT_FOUND); error(response,"token is null",oauthLog); return; } if(CommonUtils.isNull(returnUrl)){ oauthLog.setResult(OauthLog.RESULT_REDIRECT_URL_ERROR); error(response,"returnUrl is null",oauthLog); return; } String tokenInfo[]=token.split("-"); if(tokenInfo.length!=2){ oauthLog.setResult(OauthLog.RESULT_TOKEN_FORMAT_ERROR); error(response,"token is unvalid["+token+"]",oauthLog); return; } int tokenId=Integer.parseInt(tokenInfo[1]); if(!tokenService.isValid(tokenId, tokenInfo[0], Token.OPERATION_WEB_LOGIN)){ oauthLog.setResult(OauthLog.RESULT_TOKEN_EXPIRED); error(response,"token is expired or can't find["+token+"]",oauthLog); return; } Token tokenObj=tokenService.getTokenById(tokenId); LoginInfo info=loginService.loginAndReturnPasswordType(new TokenLoginCredential(tokenObj)); if(info.getUser()==null){ oauthLog.setResult(OauthLog.RESULT_USER_NOT_FOUND); error(response,"can't find user ,login error",oauthLog); return; } try { JSONObject obj=new JSONObject(tokenObj.getContent()); oauthLog.setClientId(obj.getString("clientId")); } catch (JSONException e) { LOGGER.error(e.getMessage(),e); } OauthClientBean bean=clientServer.findByClientId(oauthLog.getClientId()); if(bean==null){ oauthLog.setResult(OauthLog.RESULT_CLIENT_ID_ERROR); error(response, "cant found client that id is "+oauthLog.getClientId(), oauthLog); return; } oauthLog.setClientId(bean.getClientId()); oauthLog.setClientName(bean.getClientName()); oauthLog.setUid(info.getUser().getId()); oauthLog.setCstnetId(info.getUser().getCstnetId()); oauthLog.setResult(OauthLog.RESULT_SUCCESS); logService.addLog(oauthLog); tokenService.toUsed(tokenObj.getId()); UMTContext.saveUser(request.getSession(), info); UMTRole[] roles = rs.getUserRoles(info.getUser().getCstnetId()); UMTContext.saveRoles(request.getSession(), roles); response.sendRedirect(setHash2Url(returnUrl)); } private String setHash2Url(String url){ int index=url.indexOf("#"); String result=url; if(index>-1){ String prefix=url.substring(0,index); String suffix=url.substring(index+1); prefix=addParam(prefix,"hash",suffix); return prefix+"#"+suffix; } return result; } private String addParam(String url,String key,String value){ if(CommonUtils.isNull(url)||CommonUtils.isNull(key)||CommonUtils.isNull(value)){ return url; }else if(url.contains(key+"=")){ return url; }else{ if(url.contains("?")){ return url+"&"+key+"="+value; }else{ return url+"?"+key+"="+value; } } } /** * 申请临时token * */ private void apply(HttpServletRequest request, HttpServletResponse response) throws IOException { // umt_token 和 umt_oauth_token 都需要记下来 String accessToken=request.getParameter("accessToken"); OauthLog log=new OauthLog(); log.setAction(OauthLog.ACTION_VALIDATE_TOKEN_LOGIN_RANDOM_TOKEN); log.setIp(RequestUtil.getRemoteIP(request)); log.setUserAgent(request.getHeader("User-Agent")); if(CommonUtils.isNull(accessToken)){ log.setResult(OauthLog.RESULT_TOKEN_FORMAT_ERROR); error(response,"accessToken is Null!",log); return; } OauthToken token=oauthTokenService.getTokenByAccess(accessToken); if(token==null){ log.setResult(OauthLog.RESULT_TOKEN_NOT_FOUND); error(response,"can't find accessToken["+accessToken+"]",log); return; } if(token.isAccessExpired()){ log.setResult(OauthLog.RESULT_TOKEN_EXPIRED); error(response,"access Token["+accessToken+"] is Expired!",log); return; } OauthClientBean bean=clientServer.findByClientId(token.getClientId()); Token randomToken=new Token(); Date now=new Date(); randomToken.setCreateTime(now); randomToken.setExpireTime(new Date(now.getTime()+5*60*1000)); randomToken.setUid(Integer.parseInt(token.getUid())); randomToken.setRandom(RandomUtil.random(30)); randomToken.setOperation(Token.OPERATION_WEB_LOGIN); randomToken.setStatus(Token.STATUS_UNUSED); randomToken.setContent(token.toString()); randomToken.setPasswordType(token.getPasswordType()); tokenService.createToken(randomToken); log.setUid(Integer.parseInt(token.getUid())); User u=userService.getUserByUid(log.getUid()); log.setCstnetId(u==null?null:u.getCstnetId()); log.setResult(OauthLog.RESULT_SUCCESS); log.setClientId(bean.getClientId()); log.setClientName(bean.getClientName()); logService.addLog(log); writeToResponse(response,randomToken); } private void writeToResponse(HttpServletResponse response,Token randomToken) throws IOException{ // all for ie response.setContentType("text/html"); PrintWriter writer = response.getWriter(); JSONObject obj=new JSONObject(); try { obj.put("token", randomToken.getRandom()+"-"+randomToken.getId()); obj.put("createTime", randomToken.getCreateTime().getTime()); obj.put("expireTime", String.valueOf(randomToken.getExpireTime())); } catch (JSONException e) { LOGGER.error(e.getMessage(),e); return; } writer.write(obj.toString()); } /** * 验证失败 * */ private void error(HttpServletResponse response,String msg,OauthLog log){ response.setStatus(403); if(log!=null){ log.setDesc(msg); logService.addLog(log); } LOGGER.error(msg); } }