关于登陆的配置问题总结
2017-06-17 14:23
381 查看
spring-servelet.xml
拦截器的写法
自定义登陆异常
自定义异常
登出功能 步骤 1.清理当前服务端的loginToken 并且 把Cookie值清空
<?xml version="1.0" encoding="GBK"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core" xmlns:p="http://cxf.apache.org/policy" xmlns:ss="http://www.springframework.org/schema/security" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 使用CGLIB自动创建代理Bean --> <aop:aspectj-autoproxy proxy-target-class="true"> </aop:aspectj-autoproxy> <context:annotation-config /> <context:component-scan base-package="com.suning.uras.admin.web" /> <!-- 登陆权限插件包注解 --> <context:component-scan base-package="com.suning.uras.common" /> <mvc:annotation-driven /> <!-- mvc 登陆鉴权拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 需要拦截的URL --> <mvc:mapping path="/*/**" /> <bean class="com.suning.uras.common.interceptor.AuthLoginInterceptor"> <!-- 登陆页面 --> <property name="loginUrl" value="/login.htm" /> <!-- 放行URL配置 --> <property name="excludeList"> <list> <value>/login.htm</value> <value>/logout.htm</value> </list> </property> </bean> </mvc:interceptor> </mvc:interceptors> <!--无权限异常处理页面 --> <bean id="exceptionResolver" class="com.suning.uras.common.exception.AuthRightFailedExceptionResolver"> <!-- class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> --> <property name="exceptionMappings"> <props> <!-- 支持自定义异常跳转FTL页面或者响应JSON数据,格式要求:FTL页面以.ftl结尾,其他配置全部以JSON数据格式处理 --> <!-- JSON格式,根据实际无权限结果码配置,如果不配置,默认返回{"errorCode":"no_right","errorMessage":"无权限访问"} --> <!-- JSON格式数据支持JSONP,但是回调函数名称必须是callback--> <!-- JSON配置参考: --> <prop key="com.suning.uras.common.exception.AuthRightFailedException">no_right.ftl</prop> <prop key="com.suning.uras.common.exception.AuthRightJsonFailedException">{"code":"1001","message":"no right message"}</prop> </props> </property> <property name="warnLogCategory" value="WARN"></property> </bean> <!--===================== view resovler ===================== --> <bean id="viewResolver" abstract="true"> <property name="attributes"> <props> <prop key="resRoot">@{resRoot}</prop> <prop key="envName">@{envName}</prop> <prop key="versionNo">@{appVersion}</prop> <prop key="esbUrl">$[esbUrl]</prop> <prop key="urasLoginUrl">$[uras.login.url]</prop> </props> </property> </bean> <!--freemarker页面解析器 --> <bean id="freemarkerResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" parent="viewResolver"> <!--<property name="cache" value="true"/> --> <property name="order" value="1" /> <property name="viewNames"> <array> <value>*.ftl</value> </array> </property> <!-- <property name="suffix" value=".ftl" /> --> <property name="requestContextAttribute" value="request" /> <property name="exposeSpringMacroHelpers" value="true" /> <property name="exposeRequestAttributes" value="true" /> <property name="exposeSessionAttributes" value="true" /> <property name="allowSessionOverride" value="true" /> <property name="contentType" value="text/html;charset=utf-8" /><!--编码 --> <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> </bean> <!-- ===================== view resolver end ====================== --> <!-- 文件上传支持 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"></property> <property name="maxUploadSize"> <value>31457280</value><!-- 上传文件大小限制为30M,3*1024*1024 --> </property> <property name="maxInMemorySize"> <value>4096</value> </property> </bean> <!-- 属性文件加载 --> <bean id="webPropertyConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:conf/main-setting-web.properties</value> </list> </property> <property name="placeholderPrefix" value="@{" /> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> </bean> <!-- FreeMarker配置文件 --> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <description>Required for Freemarker to work in web tier</description> <property name="configuration" ref="freemarkerConfiguration" /> </bean> <!-- FreeMarker配置文件 --> <bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean"> <description>Using the Config directly so we can use it outside the web tier </description> <!-- 模板加载路径 --> <property name="templateLoaderPaths"> <list> <value>/WEB-INF/freemarker/</value> <!-- <value>/WEB-INF/ftl_macro</value> --> </list> </property> <property name="configLocation"> <value>classpath:conf/freemarker.properties</value> </property> <!--全局变量部分 --> <property name="freemarkerVariables"> 10460 <map> <entry key="xml_escape" value-ref="fmXmlEscape" /> <entry key="html_escape" value-ref="fmHtmlEscape" /> <entry key="base" value="@{base}" /> <entry key="envName" value="@{envName}" /> <entry key="resRoot" value="@{resRoot}" /> <entry key="esbUrl" value="$[esbUrl]" /> <entry key="urasLoginUrl" value="$[uras.login.url]" /> <entry key="loginDesKey" value="$[login.password.des.key]" /> </map> </property> <property name="defaultEncoding" value="utf-8" /> </bean> <!-- 针对xml文件里特殊字符转义 --> <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" /> <!-- 针对html文件里特殊字符转义 --> <bean id="fmHtmlEscape" class="freemarker.template.utility.HtmlEscape" /> </beans>
拦截器的写法
/** * 登陆鉴权拦截器<br> * 〈功能详细描述〉 * * @author 15061841 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class AuthLoginInterceptor implements HandlerInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(AuthLoginInterceptor.class); private static final String DEFAULT_LOGIN_URL = "/login.ftl"; /** * 拦截未登陆跳转登陆页URL */ private String loginUrl; /** * 放行URL */ private List<String> excludeList; @Autowired private AuthRightService authRightService; public String getLoginUrl() { return loginUrl; } public void setLoginUrl(String loginUrl) { this.loginUrl = loginUrl; } public List<String> getExcludeList() { return excludeList; } public void setExcludeList(List<String> excludeList) { this.excludeList = excludeList; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { LOGGER.info("AuthLoginInterceptor.preHandle enter."); // 校验放行URL String uri = request.getServletPath(); if (!CollectionUtils.isEmpty(excludeList) && excludeList.contains(uri)) { return true; } // 请求参数 String reqParam = request.getQueryString(); if (StringUtils.isNotBlank(reqParam)) { uri += "?" + reqParam; } // 1、获取cookie中的loginToken String loginToken = ""; Cookie[] cookies = request.getCookies(); if (null != cookies && cookies.length > 0) { loginToken = getLoginTokenFromCookie(cookies); } // 2、RSF调用中台接口校验loginToken对应的session信息,返回对应userId String userId = authRightService.validateLoginSeesion(loginToken); // 设置默认登陆页面地址 if (StringUtils.isBlank(loginUrl)) { loginUrl = DEFAULT_LOGIN_URL; } // 3、如果登陆session合法则放行,否则跳转登录页面重新登录 boolean result = false; if (StringUtils.isBlank(userId)) { // 跳转登录页面 response.sendRedirect(request.getContextPath() + loginUrl + "?targetUri=" + URLEncoder.encode(uri, "UTF-8")); } else { request.setAttribute("userId", userId); result = true; } return result; } /** * 功能描述: 获取登陆Token<br> * 〈功能详细描述〉 * * @param loginToken * @param cookies * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ private String getLoginTokenFromCookie(Cookie[] cookies) { String loginToken = ""; for (Cookie cookie : cookies) { if ("loginToken".equals(cookie.getName())) { String cookieValue = cookie.getValue(); String[] cookieValues = cookieValue.split("\\|"); if (cookieValues.length > 1) { loginToken = cookieValues[0]; break; } } } return loginToken; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { LOGGER.info("AuthLoginInterceptor.postHandle enter."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { LOGGER.info("AuthLoginInterceptor.afterCompletion enter."); } }
自定义登陆异常
/** * 自定义鉴权异常Resolver处理<br> * 〈功能详细描述〉 * * @author 15061841 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class AuthRightFailedExceptionResolver extends SimpleMappingExceptionResolver { private static final Logger logers = LoggerFactory.getLogger(AuthRightFailedExceptionResolver.class); private static final String ERROR_JSON = "{\"resultCode\":\"no_right\",\"resultMsg\":\"无权限访问\"}"; private static final String LOGIN_FLAG_JSON_APPEND_BEGIN = "\"loginFlag\":\"1\","; private static final String CALLBACK_STR = "callback"; @Override protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // response print json strings String viewName = determineViewName(ex, request); try { // 判断是否鉴权失败异常 if (ex instanceof AuthRightFailedException) { // 如果是FTL页面提示错误 Integer statusCode = determineStatusCode(request, viewName); logers.info("enter doResolveException() authRightFailedException,viewName={},statusCode={}", viewName, statusCode); if (statusCode != null) { applyStatusCodeIfPossible(request, response, statusCode); } if (StringUtils.isNotBlank(viewName) && viewName.endsWith(".ftl")) { logers.info("doResolveException() authRightFailedException ready success!"); return getModelAndView(viewName, ex, request); } } if (ex instanceof AuthRightJsonFailedException) { logers.info("enter doResolveException() authRightJsonFailedException,viewName={}", viewName); PrintWriter out = response.getWriter(); // 如果空并且是鉴权自定义异常 返回默认JSON格式 if (StringUtils.isBlank(viewName)) { viewName = ERROR_JSON; } // 处理未登录返回标识 // 获取cookie中的loginToken,如果loginToken不存在则认为未登陆 String loginToken = getLoginTokenFromCookie(request.getCookies()); if ("null".equals(loginToken) || StringUtils.isBlank(loginToken)) { response.addHeader("passport.login.flag", "1"); // 返回JSON串拼接未登录标识 String[] viewNames = viewName.split("\\{"); viewName = "{" + LOGIN_FLAG_JSON_APPEND_BEGIN + viewNames[1]; } // 处理JSONP viewName = handleJsonp(request, viewName); logers.info("enter doResolveException() authRightJsonFailedException ready success,viewName={}", viewName); // 设置ContentType response.setContentType("application/json"); // 设置UTF-8避免乱码 response.setCharacterEncoding("UTF-8"); response.setHeader("Cache-Control", "no-cache, must-revalidate"); out.print(viewName); out.close(); } // 非鉴权失败异常 业务系统可自行定义Resolve处理 } catch (Exception e) { logers.error("SimpleMappingExceptionJsonResolver.doResolveException() error", e); } return new ModelAndView(); } /** * 功能描述: <br> * 〈功能详细描述〉 * * @param request * @param viewName * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ private String handleJsonp(HttpServletRequest request, String viewName) { // 判断返回格式JSON还是JSONP // URL或者参数包含callback即认为是JSONP,和H5业务系统约定JSONP服务的回调方法名必须为callback, // java业务系统的JSON服务地址必须为xxx_callback开头.htm/do或xxx.htm/do?callback=callback String callbackMehodName = CALLBACK_STR; String reqURI = request.getRequestURI(); String reqParam = request.getQueryString(); if (StringUtils.isNotBlank(reqURI) && reqURI.contains("_callback")) { // 截取 _callback*到.do或.htm之间的字符串认为是JSONP回调函数的方法名 int end = reqURI.indexOf(".do"); if(end == -1) { end = reqURI.indexOf(".htm"); } int begin = reqURI.indexOf("_callback"); callbackMehodName = reqURI.substring(begin + 1, end); return callbackMehodName + "(" + viewName + ")"; } if (StringUtils.isNotBlank(reqParam) && (reqParam.contains("callback=callback") || reqParam.contains(CALLBACK_STR))) { // 获取JSONP回调函数的方法名 callbackMehodName = request.getParameter(CALLBACK_STR); return callbackMehodName + "(" + viewName + ")"; } return viewName; } /** * * 功能描述: 从cookie中获取loginToken<br> * 〈功能详细描述〉 * * @param cookies * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ private String getLoginTokenFromCookie(Cookie[] cookies) { String loginTokenValue = ""; if (null != cookies && cookies.length > 0) { for (Cookie c : cookies) { if ("loginToken".equals(c.getName())) { loginTokenValue = c.getValue(); break; } } } // loginToken格式为token串|userId return loginTokenValue.split("\\|")[0]; } }
自定义异常
/** * 〈一句话功能简述〉<br> * 〈功能详细描述〉 * * @author 15061841 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class AuthRightFailedException extends RuntimeException { /** */ private static final long serialVersionUID = 6533990418559037407L; public AuthRightFailedException() { // 添加自身构造器 } public AuthRightFailedException(String message) { super(message); } public AuthRightFailedException(String message, Throwable cause) { super(message, cause); } public AuthRightFailedException(Throwable cause) { super(cause); } }
AuthRightJsonFailedException public class AuthRightJsonFailedException extends RuntimeException { /** */ private static final long serialVersionUID = 6533990418559037407L; public AuthRightJsonFailedException() { super(); } public AuthRightJsonFailedException(String message) { super(message); } public AuthRightJsonFailedException(String message, Throwable cause) { super(message, cause); } public AuthRightJsonFailedException(Throwable cause) { super(cause); } }
登出功能 步骤 1.清理当前服务端的loginToken 并且 把Cookie值清空
/** * * 功能描述: 退出登录<br> * 〈功能详细描述〉 * * @param response * @param request * @param callback * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @RequestMapping("/logout_{callback}.do") public String logout(HttpServletResponse response, HttpServletRequest request, @PathVariable("callback") String callback) { // 获取cookie中loginToken String loginTokenValue = getLoginTokenFromCookie(request.getCookies()); // 清理服务端的loginToken LoginResponse rsp = loginBusiness.logout(loginTokenValue); if (null != rsp && LOGIN_SUCCESS.equals(rsp.getResultCode())) { // 清除cookie信息 // 设置登录的cookie空 setCookie(null, response, null); } return ajaxJsonp(response, gson.toJson(rsp), callback); }
相关文章推荐
- 关于ehCache配置timeToLiveSeconds失效的问题总结
- 关于AndroidManifest内清单配置问题的总结
- 关于tomcat配置的几个问题总结
- 关于mysql用户登陆、配置问题解决方法
- myeclipse中关于Tomcat和JDK的配置问题总结
- 关于Think3 配置邮箱发送遇到的问题总结
- 重点:关于登陆于注册的问题及个性化配置的问题
- failed to open stream解决办法-关于WIN主机下配置PHP的若干问题解决方案总结
- 今日总结:错误码配置,关于TXT文件下载问题
- 关于AD域登陆问题总结。
- 关于2003 server 远程桌面登陆权限配置的问题
- 关于在ECLIPSE中配置weblogic的问题总结:
- 关于Mac安装MySQL和MySQLWorkbench的初始密码,环境配置问题总结
- 关于java的各种配置问题
- JAVA与C++::关于JNI中文字符串操作问题总结
- 关于DNS服务器的配置问题(1)
- 【关于ASP.NET在IIS一些问题的经验总结】
- 关于windows2000 server自动登陆问题
- 关于"博客园"管理员登陆中校验码不会变动问题(请dudu看看)
- 关于ASPNET在IIS一些问题的经验总结