学习目标
(如果没有了解可以去我主页看看 第一至八章的内容来学习)Apache Shiro 是一个强大易用的Java安全框架,提供了认证、授权、会话管理和加密等功能。对于任何一个应用程序,Shiro都可以提供全面的安全管理服务,并且对于其他安全框架,Shiro要简单易用的多。本章主要给大家介绍Shiro的架构,讲解认证功能并和SpringBoot集成实现动态认证。
9.1 Shiro简介
Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、会话管理和加密等功能。对于任意一个应用程序,Shiro 都可以提供全面的安全管理服务,对比Spring Security,可能没有Spring Security功能强大,但是我们在实际工作中可能并不需要那么复杂的功能,所以使用简单易用的Shiro就已经足够了。本教程也只介绍基本的Shiro使用,不会过多分析源码等,重在使用。
9.1.1 Shiro特性
Apache Shiro 是一个强大的 Java 安全框架,提供了身份验证、授权、加密和会话管理等功能。Shiro 的特性包括:
- 身份验证(Authentication):验证用户身份。
- 授权(Authorization):确定用户是否有权限访问某些资源。
- 加密(Cryptography):保护数据的安全。
- 会话管理(Session Management):管理用户会话。
下面是一个简单的 Java 示例,展示了如何使用 Shiro 进行身份验证和授权。
1. 添加 Shiro 依赖
首先,在你的 Maven 项目中添加 Shiro 依赖。如果你使用的是 Gradle,请相应调整。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.8.0</version>
</dependency>
2. . 配置 Shiro
创建一个 Shiro 配置类:
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroWebConfiguration;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShiroConfig extends ShiroWebConfiguration {
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置自定义的 Realm
securityManager.setRealm(myRealm());
return securityManager;
}
@Bean
public MyRealm myRealm() {
return new MyRealm();
}
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.addPathDefinition("/login", "anon");
chainDefinition.addPathDefinition("/**", "authc");
return chainDefinition;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
3. 创建自定义 Realm
自定义 Realm 用于处理身份验证和授权逻辑:
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
// 基于用户名获取权限和角色
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(Arrays.asList("user")); // 示例角色
authorizationInfo.setStringPermissions(Arrays.asList("read", "write")); // 示例权限
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
// 模拟从数据库中获取用户信息
if ("john".equals(username)) {
return new SimpleAuthenticationInfo(username, "password123", getName());
} else {
throw new UnknownAccountException("No account found for user [" + username + "]");
}
}
}
4. 使用 Shiro 进行身份验证和授权
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
public class ShiroExample {
public static void main(String[] args) {
// 获取当前的 Subject
Subject currentUser = SecurityUtils.getSubject();
// 创建令牌
UsernamePasswordToken token = new UsernamePasswordToken("john", "password123");
try {
// 登录
currentUser.login(token);
System.out.println("User logged in successfully.");
// 检查是否有某个角色
boolean hasRole = currentUser.hasRole("user");
System.out.println("User has role 'user': " + hasRole);
// 检查是否有某个权限
boolean

最低0.47元/天 解锁文章

6922

被折叠的 条评论
为什么被折叠?



