创建Maven项目,引入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- shrio依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
<!--用于slf4j与log4j2保持桥接 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--先定义所有的appender-->
<appenders>
<!--输出控制台的配置-->
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<!--<patternlayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%p] %c %m %n"/>-->
<patternlayout pattern="[%p] %m %n"/>
</console>
</appenders>
<!-- 然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<!-- 日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<loggers>
<root level="DEBUG">
<!--输出到控制台-->
<appender-ref ref="Console"/>
</root>
<!--org.springframework
<logger name="org.springframework" level="INFO"/>-->
</loggers>
</configuration>
User.class
public class User {
private String username;
private String password;
private Integer status; // 用户状态 0: 正常 1:禁用 2:锁定
public User(String username, String password,Integer status) {
this.username = username;
this.password = password;
this.status = status;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
ShiroUtil.class
public class ShiroUtil {
/**
* 初始化shiro运行环境
*/
static {
//1.初始化shiro的安全管理器
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//2.设置用户的权限信息到安全管理器
//Realm realm = new IniRealm("classpath:shiro.ini");
Realm realm = new ShiroRealm();
securityManager.setRealm(realm);
//3. 使用SecurityUtils将securityManager设置到运行环境中
SecurityUtils.setSecurityManager(securityManager);
}
public static Subject login(String username,String password) {
//1. 创建一个Subject实例
Subject subject = SecurityUtils.getSubject();
//2. 创建用于认证的认证的token,记录用户认证的身份和凭证即账号和密码
AuthenticationToken token =
new UsernamePasswordToken(username, password);
//3.主体要进行登录,登录的时候进行认证检查
subject.login(token);
return subject;
}
}
自定义Realm继承AuthorizingRealm
public class ShiroRealm extends AuthorizingRealm {
/**
* 登录认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 1.获取用户输入的用户名
String username = token.getUsername();
// 2.获取用户输入的密码
String password = new String(token.getPassword());
// 3.根据用户名去DB查询对应的用户信息
User user = new User("admin", "123456", 0);
if (!user.getUsername().equals(username)) {
throw new UnknownAccountException("用户名不存在");
}
if (!user.getPassword().equals(password)) {
throw new CredentialsException("密码错误");
}
if (user.getStatus() == 1) {
throw new DisabledAccountException("账号被禁用");
}
if (user.getStatus() == 2) {
throw new LockedAccountException("账号被锁定");
}
System.out.println("认证成功...");
// 创建简单认证信息对象
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), getName());
return info;
}
/**
* 授权
* 将认证通过的用户的角色和权限信息设置到对应用户主体上
*
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = principals.getPrimaryPrincipal().toString();
//模拟从数据库获取当前用户的角色 通过用户名查询该用户拥有的角色名称
Set<String> roleNameSet = new HashSet<>();
roleNameSet.add("系统管理员");
//roleNameSet.add("系统运维");
//模拟从数据库获取当前用户的权限 通过用户名查询该用户拥有的权限名称
Set<String> permissionNameSet = new HashSet<>();
permissionNameSet.add("sys:user:list"); // 查看列表
permissionNameSet.add("sys:user:info"); // 查看用户详情
permissionNameSet.add("sys:user:create");// 创建用户
permissionNameSet.add("sys:user:update");// 修改用户
permissionNameSet.add("sys:user:delete");// 删除用户
// 简单授权信息对象,对象中包含用户的角色和权限信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roleNameSet);
info.addStringPermissions(permissionNameSet);
System.out.println("授权完成....");
return info;
}
}
测试
@Test
public void test02() {
// 登录认证
Subject subject = ShiroUtil.login("admin", "123456");
// 授权资源检查
// 模拟当前用户点击了 <新增用户> 按钮,检查该用户时候拥有新增用户的权限
System.out.println("检查该用户时候拥有新增用户的权限:" + subject.isPermitted("sys:user:create"));
System.out.println("检查该用户时候拥有新增角色的权限:" + subject.isPermitted("sys:role:create"));
System.out.println("检查该用户是否是系统管理员角色:" + subject.hasRole("系统管理员"));
System.out.println("检查该用户是否是系统运维角色:" + subject.hasRole("系统运维"));
// 退出系统
subject.logout();
}
控制台输出:
认证成功...
[DEBUG] Looked up AuthenticationInfo [admin] from doGetAuthenticationInfo
[DEBUG] AuthenticationInfo caching is disabled for info [admin]. Submitted token: [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false].
[DEBUG] Performing credentials equality check for tokenCredentials of type [[C and accountCredentials of type [[C]
[DEBUG] Both credentials arguments can be easily converted to byte arrays. Performing array equals comparison
[DEBUG] Authentication successful for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false]. Returned account [admin]
[DEBUG] No sessionValidationScheduler set. Attempting to create default instance.
[INFO] Enabling session validation scheduler...
[DEBUG] Creating new EIS record for new session instance [org.apache.shiro.session.mgt.SimpleSession,id=null]
[DEBUG] No authorizationCache instance set. Checking for a cacheManager...
[DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained.
授权完成....
检查该用户时候拥有新增用户的权限:true
[DEBUG] No authorizationCache instance set. Checking for a cacheManager...
[DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained.
授权完成....
检查该用户时候拥有新增角色的权限:false
[DEBUG] No authorizationCache instance set. Checking for a cacheManager...
[DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained.
授权完成....
检查该用户是否是系统管理员角色:true
[DEBUG] No authorizationCache instance set. Checking for a cacheManager...
[DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained.
授权完成....
检查该用户是否是系统运维角色:false
[DEBUG] Logging out subject with primary principal admin
[DEBUG] No authorizationCache instance set. Checking for a cacheManager...
[DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained.
[DEBUG] Stopping session with id [fc5a25ba-fd10-482d-9262-f033f724df05]