关于登陆的配置问题总结

来源:互联网 发布:监控系统怎么连接网络 编辑:程序博客网 时间:2024/05/21 15:05

spring-servelet.xml

<?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">            <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);    }}
AuthRightJsonFailedExceptionpublic 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);    }
原创粉丝点击