shiro身份验证源码分析(个人原创)

流程解析

首先调用login方法进行身份认证
根据applicationContext.xml的配置文件去查询认证器ModularRealmAuthenticator
ModularRealmAuthenticator中执行认证方法doAuthenticate
首先判断是单realm的验证还是多realm的验证(此处配置了多realm)
则执行doMultiRealmAuthentication(如果是单realm的话执行doSingleRealmAuthentication)
首先加载认证认证策略(此处我们配置了AtLeastOneSuccessfulStrategy)
然后开始for循环所有的realm,此处首先验证supportToken(我们自定义的realms里面实现的三个方法)
[重点]getAuthenticationInfo(token)获得我们从数据库中加载的用户信息,这里我们会传入token参数
     也就是前台界面传进来的用户名密码(token),此时拿到了前台的以及数据库的用户信息,然后开始进行密码比较
1    function doMultiRealmAuthentication
2    for (Realm realm : realms) {
3       aggregate = strategy.beforeAttempt(realm, token, aggregate);
4        if (realm.supports(token)) {
5            AuthenticationInfo info = realm.getAuthenticationInfo(token);
6        7    }
     其中第5行进行了密码比对 HashedCredentialsMatcher doCredentialsMatchtokeninfo)
     过程:realm.getAuthenticationInfo(token);(此过程涉及缓存cacheAuthenticatingRealm.getAuthenticationInfotoken)
        首先从缓存中查询此token对应的account信息
            如果查到直接启用,否则执行自定义的info = doGetAuthenticationInfo(token);
            从数据库中取得account信息
        然后缓存查到的tokenaccount信息
        然后执行assertCredentialsMatch(token, info);
        其中开始先创建CredentialsMatcher密码匹配器,doCredentialsMatch(token, info);
        执行HashedCredentialsMatcher.doCredentialsMatch开始密码比对
 
 
其他重点注释:
 
 
 
 
                                    shiro

url匹配模式:
    ?:匹配一个字符,如:/admin1,但是不能匹配/admin,/admin/
    * :匹配0个或者多个字符,如:/admin,/admin123,但是不能匹配admin/a
    **:匹配多重路径,如:/admin,admin/a/b

shiro用户认证流程

1. 获取当前的 Subject. 调用 SecurityUtils.getSubject();
2. 测试当前的用户是否已经被认证. 即是否已经登录. 调用 Subject isAuthenticated()
3. 若没有被认证, 则把用户名和密码封装为 UsernamePasswordToken 对象
    1). 创建一个表单页面
    2). 把请求提交到 SpringMVC Handler(上面三步都是在handler里面完成的)
    3). 获取用户名和密码.
4. 执行登录: 调用 Subject login(AuthenticationToken) 方法.
5. 自定义 Realm 的方法, 从数据库中获取对应的记录, 返回给 Shiro.
    1). 实际上需要继承 org.apache.shiro.realm.AuthenticatingRealm     2). 实现 doGetAuthenticationInfo(AuthenticationToken) 方法.
6. shiro 完成对密码的比对.

密码的比对:
通过 AuthenticatingRealm credentialsMatcher 属性来进行的密码的比对!

1. 如何把一个字符串加密为 MD5
2. 替换当前 Realm credentialsMatcher 属性. 直接使用 HashedCredentialsMatcher 对象, 并设置加密算法即可.


1. 授权需要继承 AuthorizingRealm , 并实现其 doGetAuthorizationInfo 方法
2. AuthorizingRealm 类继承自 AuthenticatingRealm, 但没有实现 AuthenticatingRealm 中的
doGetAuthenticationInfo, 所以认证和授权只需要继承 AuthorizingRealm 就可以了. 同时实现他的两个抽象方法.

1. 为什么使用 MD5 盐值加密:
2. 如何做到:
1). doGetAuthenticationInfo 方法返回值创建 SimpleAuthenticationInfo 对象的时候, 需要使用
SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName) 构造器
2). 使用 ByteSource.Util.bytes() 来计算盐值.
3). 盐值需要唯一: 一般使用随机字符串或 user id
4). 使用 new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); 来计算盐值加密后的密码的值.

 
 

猜你喜欢

转载自blog.csdn.net/fenglixiong123/article/details/77102718