1. 登录集成

通过登录接口可以定制自己的登录认证,或者对登录进行拦截,在登录前、登录成功、登录失败的各个环节记录日志。

1.1. 自定义登录认证LoginAuthentication

登录验证器

典型应用场景如下:

  • AD/LDAP统一认证
  • 两步认证,使用手机短信、手机令牌或其他硬件进行双因素认证
  • CA认证实现
/**
     * 认证,策略是:
     * 
     * <ol>
     *   <li>系统框架把登录界面发过来的<code>HttpServletRequest</code>完整的传递给认证实现类</li>
     *   <li>认证实现类完成自己的逻辑</li>
     *   <li>返回值约定
     *      <ol type="i">
     *        <li>当验证通过,需要给框架返回[用户名, 密码],框架将直接跳转到首页</li>
     *        <li>当不验证通过,但要终止本次登录请求,直接throw new LoginAuthenticationException(),用户将跳转到登录页</li>
     *        <li>当不验证通过,返回null,框架将调用下一个认证类认证</li>
     *      </ol>
     *   </li>
     * </ol>
     * 
     * @return 认证通过: 返回[用户名, 密码]; 验证不通过返回null,框架将调用下一个认证类认证
     * @throws LoginAuthenticationException 用户将跳转到登录页
     */
    String[] authenticate(HttpServletRequest request, HttpServletResponse response)
            throws LoginAuthenticationException;

系统缺省提供几个验证器,按顺序如下

验证器 说明
com.seeyon.ctp.portal.sso.login.SSOTicketLoginAuthentication 单点登录认证
com.seeyon.v3x.plugin.ca.CALoginAuthentication 使用CA认证
com.seeyon.ctp.login.IdentificationDogLoginAuthentication 使用身份验证狗认证
com.seeyon.apps.ldap.login.LDAPLoginAuthentication 使用LDAP认证
com.seeyon.ctp.login.auth.DefaultLoginAuthentication 使用协同用户系统认证

各验证器按顺序依次调用认证方法,只要有一个通过则该次登录认证通过。

要实现自己的登录认证,必须:

1 继承com.seeyon.ctp.login.AbstractLoginAuthentication,实现自己的登录验证类

package com.seeyon.apps.login;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.seeyon.ctp.common.constants.Constants;
import com.seeyon.ctp.common.constants.LoginConstants;
import com.seeyon.ctp.login.AbstractLoginAuthentication;
public class CustomLoginAuthentication extends AbstractLoginAuthentication {
    @Override
    public String[] authenticate(HttpServletRequest request,
            HttpServletResponse response) throws LoginAuthenticationException {
        String username = request.getParameter(LoginConstants.USERNAME);// 用户名
        String password = request.getParameter(LoginConstants.PASSWORD);// 密码
        if (username == null || password == null) {
            return null;
        }
        //登录方式,判断是否移动应用登陆
        String userAgentFrom = request.getParameter(Constants.LOGIN_USERAGENT_FROM);
        boolean fromMobile = Constants.login_useragent_from.mobile.name().equals(userAgentFrom) || LoginUtil.isFromM1(userAgentFrom);

        if (check(username, password)) {
            return new String[] { username, password };
        }

        return null;
    }

    private boolean check(String username, String password) {
        // 登录认证逻辑,用户名和密码正确时返回true即可
        return false;
    }
}

注册Spring bean

在插件的springxml文件中,增加

<bean class="com.seeyon.apps.login.CustomLoginAuthentication"/>

1.2. 登录认证拦截LoginInterceptor

对登录认证进行拦截

典型应用场景如下:

  • 记录登录审计日志
  • IP、浏览器控制
 /**
     * 登录之前的操作

     * 
     * 此时AppContext.getCurrentUser()是null的
     * 
     * @param request
     * @param response
     * @return Error标示本次登录终止,返回到登录页;OK正常往下进行
     */
    public LoginResult preHandle(HttpServletRequest request, HttpServletResponse response);

    /**
     * 在登录验证成功后的操作

     * 此时AppContext.getCurrentUser()有值
     * @param request
     * @param response
     * @return Error标示本次登录终止,返回到登录页;OK正常往下进行
     */
    public LoginResult afterComplete(HttpServletRequest request, HttpServletResponse response);

    /**
     * 在登录验证失败后的操作
     * 
     * @param request
     * @param response
     * @return Error不管怎么样都会跳转到登录页面,最好别返回LoginResult.OK他也没有用
     */
    public LoginResult afterFailure(HttpServletRequest request, HttpServletResponse response);

系统缺省通过几个拦截器实现一些功能控制

验证器 说明
com.seeyon.ctp.login.interceptor.VerifyCodeLoginInterceptor 验证码拦截器,在preHandle对用户输入的验证码进行校验
com.seeyon.ctp.login.interceptor.LockLoginInterceptor 锁定用户拦截器
com.seeyon.ctp.login.interceptor.IpcontrolLoginInterceptor IP控制拦截器
com.seeyon.ctp.login.interceptor.MutilBrowserLoginInterceptor 限制管理员只能使用PC,通过IE登录

可以通过以下步骤实现登录拦截:

1 继承com.seeyon.ctp.login.AbstractLoginInterceptor,实现自己的登录拦截器类

package com.seeyon.apps.login;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.seeyon.ctp.common.constants.LoginConstants;
import com.seeyon.ctp.login.AbstractLoginInterceptor;
import com.seeyon.ctp.login.LoginAuthenticationException;

public class CustomMutilBrowserLoginInterceptor extends com.seeyon.ctp.login.AbstractLoginInterceptor {
    public CustomMutilBrowserLoginInterceptor() {
    }
    //管理员只能通过IE、PC访问
    public LoginResult afterComplete(HttpServletRequest request,HttpServletResponse response) {
        User currentUser = CurrentUser.get();
        if(currentUser.isAdmin()) {
            Boolean A8Allow4Admin = (Boolean)(BrowserFlag.A8Allow4Admin.getFlag(request));

            //管理员只能从IE上登录
            if (Boolean.FALSE.equals(A8Allow4Admin)) {
                return LoginResult.ERROR_IPCONTROLIPAD;
            }

            //管理员不能从M1上登录
            if(currentUser.isFromM1() || Constants.login_useragent_from.mobile.name().equals(currentUser.getUserAgentFrom())){
                return LoginResult.ERROR_ForbiddenAdminLogin;
            }
        }

        return LoginResult.OK;
    }
}

2 注册Spring bean

在插件的springxml文件中,增加

 <bean class="com.seeyon.apps.login.CustomMutilBrowserLoginInterceptor"/>

1.3. 排序

在大多数场景下,同一套产品只会有一个主要的LoginAuthentication生效,而LoginInterceptor对顺序不敏感,原则上不需要排序。

但如果要对LoginAuthentication和LoginInterceptor进行排序,可以在插件目录定义一个login.xml,如(WEB-INF\cfgHome\plugin\myplugin\login.xml)

<?xml version="1.0" encoding="UTF-8"?>
<login>
    <bean class="com.seeyon.apps.login.CustomLoginInterceptor" before="com.seeyon.ctp.login.interceptor.LockLoginInterceptor"/>
    <bean class="com.seeyon.apps.login.CustomLoginAuthentication" after="com.seeyon.v3x.plugin.ca.CALoginAuthentication"/>
</login>

将CustomLoginInterceptor放到com.seeyon.ctp.login.interceptor.LockLoginInterceptor之前执行。

将CustomLoginAuthentication放到com.seeyon.v3x.plugin.ca.CALoginAuthentication之后执行。

一旦定义了login.xml,对应的bean就无需在spring xml中注册。

1.4. 使用平台认证登录

最简单的方式,是直接使用平台的登录

GET http://127.0.0.1/seeyon/main.do?login_username={loginName}&login_password={password}

然后获取响应的Header中的LoginOK,如果有值说明登录成功。

登录成功后获取Cookie,以后的请求都使用Cookie中的JSESSIONID发起即可。

但这样的方式与PC公用并发,会导致PC的登录被迫下线。

M1、M3和致信都是在后台重写了登录的入口,但这个是内部的实现,有很多控制。

对于移动应用认证,我们建议的开发方式是只通过用户密码校验的REST接口进行身份认证,使用REST接口开发

POST authentication?login_username={loginName}&login_password={password}

成功也会返回LoginOK,但不进行真实的登录。

1.5. 登录提示信息编码

编码 状态 备注 提示信息
1001 exceed_max_member 超出并发数限制 超出了最大登录人数
1002 exceed_max_member_in_account 超出单位并发数限制 超出了您所在单位的最大登录人数
1003 loginUserState.adminKickoff 被管理员强制下线 您被管理员强制下线
1004 LoginOfflineOperation.networkOff 网路故障 网络故障,您被迫下线
1005 loginUserState.changePassword 其他端修改了密码 密码已被修改{0},请重新登录。
1006 loginUserState.kickOff 被其他端下线 您的账号已被下线!
1007 LoginOfflineOperation.loginAnotherone 在另一个地点登录 您的帐号在另一地点登录,您被迫下线
1010 loginUserState.unknown 未知错误 被迫下线,原因:与服务器失去连接
1021 无效的用户名或密码
1022 无效的用户名或密码 该帐号仅剩下{0}次登录尝试机会
1023 账号被锁定,请稍后重试或联系管理员
1024 该帐号已经被禁用.请联系管理员.
1031 您没有在符合的IP范围内登录
1041 管理员不能在该浏览器上登录
1042 管理员不能登录
1045 短信登录验证码不匹配或过期
1047 身份验证狗不可用。
1051 证书已过期。
1052 证书已吊销。
1053 证书被吊销且已过期。
1054 证书服务器错误,请联系管理员。
1055 证书与协同账号没有绑定,请联系管理员。
1056 此IP登录必须拥有账号所对应的CA证书
1057 请安装CA证书或插入CA硬件设备,请联系管理员
1058 此帐号和CA帐号绑定不正确,请联系管理员
1060 域用户验证失败
1061 域用户绑定信息不存在

results matching ""

    No results matching ""