ssm框架下,controller接收到登录请求交给Service并开始处理流程:

1.Service的login方法:

@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    SysUserMapper mapper;

    @Override
    public LoginResult login(SysUser sysUser) {
        LoginResult loginResult = new LoginResult();
        try {
            List<SysUser> sysUsers = mapper.selectByExample(sysUser.getUsername());
            BackUserToken backUserToken=new BackUserToken(sysUser.getUsername(), sysUser.getPwd(),sysUsers);
            SecurityUtils.getSubject().login(backUserToken);
            loginResult.setStatus(RespMSG.STATUS_SUCCESS);
            loginResult.setMsg(RespMSG.MSG_SUCCESS);
            loginResult.setSysUser(sysUsers.get(0));
            return loginResult;
        } catch (UnknownAccountException e) {
            loginResult.setStatus(RespMSG.STATUS_NON_EXISTENT);
            loginResult.setMsg(RespMSG.MSG_NON_EXISTENT);
            return loginResult;
        } catch (AccountException e) {
            e.printStackTrace();
//            loginResult.setStatus(RespMSG.);
//            loginResult.setMsg(RespMSG.MSG_NON_EXISTENT);
//            return loginResult;
        } catch (DeadlineException e) {
            loginResult.setStatus(RespMSG.STATUS_OVERDUE);
            loginResult.setMsg(RespMSG.MSG_OVERDUE);
            return loginResult;
        } catch (AccountRepeatException e) {
            loginResult.setStatus(RespMSG.STATUS_REPETITION);
            loginResult.setMsg(RespMSG.MSG_REPETITION);
            return loginResult;
        } catch (IncorrectCredentialsException e) {
            loginResult.setStatus(RespMSG.STATUS_WRONG_PWD);
            loginResult.setMsg(RespMSG.MSG_WRONG_PWD);
            return loginResult;
        }
        loginResult.setMsg(RespMSG.MSG_UNKNOW);
        loginResult.setStatus(RespMSG.STATUS_UNKNOW);
        return loginResult;
    }

}
BackUserToken集成了UsernamePasswordToken,主要是构造参数多了一个List<SysUser>.因为我需要在service中将登录用户的详细
信息返回给客户端,同时将登录用户的信息传递给Realm进行登录验证。

关键方法是:

SecurityUtils.getSubject().login(backUserToken);

其具体实现是:

2.DelegatingSubject implements Subject

public class DelegatingSubject implements Subject {
   public void login(AuthenticationToken token) throws AuthenticationException {
        ...
        Subject subject = this.securityManager.login(this, token);
        ...
    }
}

token继续传递:

3.DefaultSecurityManager

public class DefaultSecurityManager extends SessionsSecurityManager {

    public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
        ...
            info = this.authenticate(token);
	...
        return loggedIn;
    }

}

向下继续

4.AuthenticatingSecurityManager

public abstract class AuthenticatingSecurityManager extends RealmSecurityManager {

    public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
        return this.authenticator.authenticate(token);
    }

}

继续向下

5.AbstractAuthenticator

public abstract class AbstractAuthenticator implements Authenticator, LogoutAware {

    public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
        ...
        info = this.doAuthenticate(token);
        ...
        return info;
        }
    }

}

6.ModularRealmAuthenticator

public class ModularRealmAuthenticator extends AbstractAuthenticator {

    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        this.assertRealmsConfigured();
        Collection<Realm> realms = this.getRealms();
        return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken) : this.doMultiRealmAuthentication(realms, authenticationToken);
    }

}

还是在ModularRealmAuthenticator中

protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
          ...
            AuthenticationInfo info = realm.getAuthenticationInfo(token);
          ...

    }

继续

7.AuthenticatingRealm

public abstract class AuthenticatingRealm extends CachingRealm implements Initializable {

    public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        ...
        info = this.doGetAuthenticationInfo(token);
        ...
        return info;
    }

}

然后进入最后一步,在继承了AuthorizingRealm的自定义的realm中进行处理。

8.自定义realm举例

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
        BackUserToken token = (BackUserToken) authenticationToken;
        List<SysUser> sysUsers = token.getUser();
        if (sysUsers == null || sysUsers.size() == 0) {
            throw new UnknownAccountException();
        }
        if (sysUsers.size() > 1) {
            //用户重复
            throw new AccountRepeatException();
        }
        if (用户已过期) {
            if (sysUsers.get(0).getIsAbleDate() == null||sysUsers.get(0).getIsAbleDate().getTime() < new Date().getTime()) {
                //用户过期(自定义异常)
                throw new DeadlineException();
            }
        }
        SysUser sysUser = sysUsers.get(0);
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                sysUser,
                sysUser.getPwd(),
                getName()
        );
        return authenticationInfo;

    }

最新文章

  1. 我的MYSQL学习心得(二) 数据类型宽度
  2. Android IOS WebRTC 音视频开发总结(十五)-- 培训课程大纲
  3. MYSQL外键约束的参照操作
  4. JAVA日历
  5. 【转】iOS Provisioning Profile(Certificate)与Code Signing详解 -- 待看
  6. 使用charles proxy for Mac来抓取手机App的网络包
  7. 【递归】Vijos P1114 FBI树(NOIP2004普及组第三题)
  8. hdoj 3549 Flow Problem(最大网络流)
  9. Android获取SD卡中选中图片的路径(URL)
  10. Oralce生成前N年的年数据
  11. java设计模式案例详解:观察者模式
  12. Anaconda使用
  13. https----------如何在phpstudy环境下配置apache的https访问以及访问http自动跳转成https
  14. Mybatis笔记三:全局配置文件
  15. zsh,oh-my-zsh,antigen使用记录
  16. DNA sequence open reading frames (ORFs) | DNA序列的开放阅读框ORF预测
  17. 一个基于DPI技术实现了内网资产识别的应用
  18. jQuery(七):节点操作
  19. springboot logback + log4j2日志管理
  20. Django 之 CBV &amp; FBV

热门文章

  1. Airless Bottle-Can Be Used On Any Cream Product
  2. 吴裕雄 python 神经网络——TensorFlow 数据集高层操作
  3. JS vue 组件创建过程
  4. java程序设计课期中考试——数据库的增删改查和简单的js界面
  5. 【JS 日期】获取当前日期时间
  6. MariaDB-Galera部署
  7. java窗口程序字符串时间转成时间戳
  8. c#DDOS代码
  9. 开启Linux服务器vnc远程服务详细步骤
  10. Linux 下面搭建KMS服务器