shiro原理和框架图什么的这就不说了,主要是实际的操作,大家可以参考Shiro 简介看看Shiro的工作原理
1、添加依赖
因为是第一篇,所以还是写上这个
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
2、身份验证
(1)先来个小测试,能不能通过
首先创建一个shiro.ini的文件,里面存的是账号密码
下面是测试程序
package auth;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class AuthenticatetTest {
@Test
public void authenticationTest() {
创建DefaultSecurityManager,以前的IniSecurityManagerFactory被舍弃了
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//创建iniRealm
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
//把iniRealm添加进DefaultSecurityManager
defaultSecurityManager.setRealm(iniRealm);
// 将securityManager设置当前的运行环境中
SecurityUtils.setSecurityManager(defaultSecurityManager);
// 从SecurityUtils里边创建一个subject
Subject subject = SecurityUtils.getSubject();
// 在认证提交前准备token(令牌)
// 这里的账号和密码 将来是由用户输入进去
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
try {
// 执行认证提交
subject.login(token);
} catch (AuthenticationException e) {
//如果你提交的token和shiro.ini里面的数据没有匹配的就会报错
e.printStackTrace();
}
// 是否认证通过
boolean isAuthenticated = subject.isAuthenticated();
System.out.println("是否认证通过:" + isAuthenticated);
// 退出操作
subject.logout();
// 是否认证通过
isAuthenticated = subject.isAuthenticated();
System.out.println("是否认证通过:" + isAuthenticated);
}
}
没问题,下面说一下注意事项
如果你输入的账号密码没有问题,那就subject.isAuthenticated();
就会为true,如果查询不到就会报错,具体谁执行看下面:
ModularRealmAuthenticator接收IniRealm返回Authentication认证信息
- 如果查询到用户账号,就给ModularRealmAuthenticator返回用户信息(账号和密码),之后对IniRealm中的用户密码 (在ini文件中存在)和自己提交的token的密码进行比对,一模一样
subject.isAuthenticated();
就会为true,不一致抛出org.apache.shiro.authc.IncorrectCredentialsException - 如果查询不到账户,就给ModularRealmAuthenticator返回null,并抛出org.apache.shiro.authc.UnknownAccountException
(2)完整的身份验证逻辑
下面是参考官方案例10 Minute Tutorial on Apache Shiro
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class AuthenticatetTest {
@Test
public void authenticationTest() {
//获取本地资源文件,设置realm为本地的资源文件
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
defaultSecurityManager.setRealm(iniRealm);
SecurityUtils.setSecurityManager(defaultSecurityManager);
//获取对象主体
Subject currentUser = SecurityUtils.getSubject();
//获取session
Session session = currentUser.getSession();
session.setAttribute( "someKey", "aValue" );
//判断是否登陆过
if ( !currentUser.isAuthenticated() ) {
//没有登陆. 就登陆
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "1234");
//请记住我,也就是shiro操作cookie实现自动登录,这可以先不了解,
token.setRememberMe(true);
try {
currentUser.login( token );
System.out.println( "User [" + currentUser.getPrincipal() + "] logged in successfully." );
//退出
currentUser.logout();
System.out.println( "User [" + currentUser.getPrincipal() + "] logged in successfully." );
} catch ( UnknownAccountException e ) {
System.out.println("用户名不存在"+e);
} catch ( IncorrectCredentialsException e ) {
System.out.println("密码不正确"+e);
} catch ( LockedAccountException e ) {
System.out.println("账户被锁定?"+e);
} catch ( AuthenticationException e ) {
System.out.println("AuthenticationException"+e);
}
}
//正常退出
System.exit(0);
}
}