1. 创建项目并引入依赖
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.5.3</version></dependency>
2. 引入shiro配置文件
配置文件:名称随意,以 .ini 结尾,放在 resources 目录下
注意:在实际的项目开发中并不会使用这种方式,这种方法可以用来初学时练手
[users]jack=123marry=456alice=789

3.开发认证代码
package com.cedric;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
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.subject.Subject;
public class TestAuthenticator {
public static void main(String[] args) {
//1.创建安全管理器对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//2.给安全管理器设置realm
securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
//3.SecurityUtils给全局安全工具类设置安全管理器
SecurityUtils.setSecurityManager(securityManager);
//4.关键对象 subject主体
Subject subject = SecurityUtils.getSubject();
//5.创建令牌
UsernamePasswordToken token = new UsernamePasswordToken("jack","123");
try{
subject.login(token); // 用户认证
System.out.println("认证状态:" + subject.isAuthenticated());
} catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("认证失败:用户名不存在");
} catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("认证失败:密码错误");
}
}
}
4.常见的异常类型
- DisabledAccountException(帐号被禁用)
- LockedAccountException(帐号被锁定)
- ExcessiveAttemptsException(登录失败次数过多)
- ExpiredCredentialsException(凭证过期)等
4.5 自定义Realm
通过分析源码可得:
认证:
1.最终执行用户名比较是 在SimpleAccountRealm类 的 doGetAuthenticationInfo 方法中完成用户名校验
2.最终密码校验是在 AuthenticatingRealm类 的 assertCredentialsMatch方法 中
总结:
AuthenticatingRealm 认证realm doGetAuthenticationInf
AuthorizingRealm 授权realm doGetAuthorizationInfo
自定义Realm的作用:放弃使用.ini文件,使用数据库查询
上边的程序使用的是Shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。
4.5.1.shiro提供的Realm
根据认证源码认证使用的是SimpleAccountRealm

SimpleAccountRealm的部分源码中有两个方法一个是 认证 一个是 授权
源码部分:
public class SimpleAccountRealm extends AuthorizingRealm {
//.......省略
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
SimpleAccount account = getUser(upToken.getUsername());
if (account != null) {
if (account.isLocked()) {
throw new LockedAccountException("Account [" + account + "] is locked.");
}
if (account.isCredentialsExpired()) {
String msg = "The credentials for account [" + account + "] are expired";
throw new ExpiredCredentialsException(msg);
}
}
return account;
}
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = getUsername(principals);
USERS_LOCK.readLock().lock();
try {
return this.users.get(username);
} finally {
USERS_LOCK.readLock().unlock();
}
}
}
