principals即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。credentials是证明/凭证,即只有主体知道的安全值,如密码/数字证书等。最常见的principals和credentials组合就是用户/密码了。
下面我们来看一个认证的例子,由于我们是用maven构建的实例,所以需要在pom.xml中添加依赖:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
另外,准备一些用户微分凭据,shiro.ini:
?
1
2
3
[users]
zhang=123
wang=123
测试用例:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package org.shiro;
import junit.framework.Assert;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;
public class ShiroTest1{
@Test
public void shiro_test1(){
//获取SecurityManager工厂,此处使用ini配置文件初始化SecurityManager
Factory
new IniSecurityManagerFactory("classpath:shiro.ini");
//得到SecurityManager实例并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang","123");
try {
subject.login(token);
} catch (AuthenticationException e) {
System.err.println(e.getMessage());
}
//断言用户已经登录
Assert.assertEquals(true, subject.isAuthenticated());
//退出
subject.logout();
}
}
从上例中,我们可以看到shiro的身份认证流程,如果还没有明白,可以看看下图:
首先调用Subject.login(token)进行登录,其会自动委托给SecurityManager,调用之前必须通过SecurityUtils.setSecurityManager()设置
2. SecurityManager负责真正的身份验证逻辑,它会委托给Authenticator进行身份验证
3. Authenticator才是真正的身份验证者,shiro API中核心的身份认证入口点,此处可以自定义插入自己的实现
4. Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证。
5. Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此外可以配置多个Realm,将按照相应的顺序及策略进行访问。