springboot 整合shiro
时间: 2023-05-31 10:19:31 浏览: 174
### 回答1:
Spring Boot可以很方便地整合Shiro,只需要在pom.xml中添加Shiro和Spring Boot的依赖,然后配置Shiro的相关信息即可。
1. 添加依赖
在pom.xml中添加以下依赖:
```
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
```
2. 配置Shiro
在Spring Boot的配置文件application.properties中添加Shiro的相关配置:
```
# Shiro配置
# Shiro过滤器链配置
shiro.filterChainDefinitions = /login = anon\n/** = authc
# Shiro会话管理器配置
shiro.sessionManager.globalSessionTimeout = 180000
# Shiro缓存管理器配置
shiro.cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
```
3. 编写Shiro配置类
编写一个Shiro配置类,用于配置Shiro的安全管理器、过滤器链等:
```
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
securityManager.setSessionManager(sessionManager());
securityManager.setCacheManager(cacheManager());
return securityManager;
}
@Bean
public ShiroRealm shiroRealm() {
ShiroRealm shiroRealm = new ShiroRealm();
shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return shiroRealm;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");
hashedCredentialsMatcher.setHashIterations(2);
return hashedCredentialsMatcher;
}
@Bean
public SessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(180000);
sessionManager.setSessionDAO(sessionDAO());
return sessionManager;
}
@Bean
public SessionDAO sessionDAO() {
return new MemorySessionDAO();
}
@Bean
public CacheManager cacheManager() {
return new MemoryConstrainedCacheManager();
}
}
```
4. 编写ShiroRealm
编写一个ShiroRealm类,用于验证用户身份和权限:
```
public class ShiroRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User user = (User) principals.getPrimaryPrincipal();
List<Role> roles = userService.getRolesByUserId(user.getId());
for (Role role : roles) {
authorizationInfo.addRole(role.getName());
List<Permission> permissions = userService.getPermissionsByRoleId(role.getId());
for (Permission permission : permissions) {
authorizationInfo.addStringPermission(permission.getName());
}
}
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String username = usernamePasswordToken.getUsername();
User user = userService.getUserByUsername(username);
if (user == null) {
throw new UnknownAccountException();
}
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
}
```
5. 编写登录和注销功能
编写一个登录页面和一个注销功能,用于测试Shiro的整合效果:
```
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping("/login")
public String doLogin(String username, String password) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "redirect:/index";
} catch (UnknownAccountException e) {
return "redirect:/login?error=unknownAccount";
} catch (IncorrectCredentialsException e) {
return "redirect:/login?error=incorrectCredentials";
} catch (LockedAccountException e) {
return "redirect:/login?error=lockedAccount";
} catch (AuthenticationException e) {
return "redirect:/login?error=authenticationError";
}
}
@GetMapping("/logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/login";
}
}
```
以上就是Spring Boot整合Shiro的基本步骤,通过以上步骤可以实现基本的用户认证和授权功能。
### 回答2:
SpringBoot是一款开源的、快速构建可执行Java应用程序的框架,Shiro是一款Java的安全框架。SpringBoot整合Shiro可以为应用程序提供更强大的安全性,让我们了解如何实现SpringBoot与Shiro的整合。
首先,我们需要在pom.xml文件中引入Shiro的依赖,由于我们是基于SpringBoot实现的,因此可以使用SpringBoot提供的starter-shiro依赖,所以只需在pom.xml文件中添加以下依赖即可:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-shiro</artifactId>
</dependency>
```
接下来,我们需要配置Shiro的安全管理器,因为Shiro的默认安全管理器不支持SpringBean的注入,所以我们需要实现一个自定义的安全管理器。我们可以通过继承Shiro的DefaultWebSecurityManager类来创建一个自定义的安全管理器,这个安全管理器需要注入Shiro的Realm,并利用Spring的依赖注入机制进行配置。
```java
@Configuration
public class ShiroConfig {
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
@Bean
public SecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(userRealm);
return manager;
}
}
```
接下来,我们需要创建一个Shiro的Realm,并实现doGetAuthenticationInfo和doGetAuthorizationInfo方法。doGetAuthenticationInfo方法用于对用户进行认证,而doGetAuthorizationInfo方法则用于对用户进行授权。在实现这两个方法之前,我们需要借助于用户的模型类来定义用户的角色和权限信息。
```java
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前登录用户的用户名
String username = (String) principals.getPrimaryPrincipal();
// 获取用户的角色和权限信息
User user = userService.findUserByName(username);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(user.getRoles());
authorizationInfo.setStringPermissions(user.getPermissions());
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户登录信息
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 判断用户名和密码是否正确
User user = userService.findUserByName(username);
if (user == null || !user.getPassword().equals(password)) {
throw new IncorrectCredentialsException("账号名或密码错误");
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),getName());
return authenticationInfo;
}
}
```
最后,我们需要在Controller层处理登录和注销的请求。在登录请求中,我们需要使用Shiro的Subject对象对用户进行认证,而在注销请求中,我们需要利用Shiro的SecurityUtils工具类进行注销操作。
```java
@Controller
public class LoginController {
@PostMapping("/login")
@ResponseBody
public Result login(String username, String password) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
try {
subject.login(token);
return Result.success();
} catch (UnknownAccountException e) {
return Result.fail("账号不存在");
} catch (IncorrectCredentialsException e) {
return Result.fail("账号名或密码错误");
}
}
@PostMapping("/logout")
@ResponseBody
public Result logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return Result.success();
}
}
```
本文介绍了在SpringBoot中如何实现Shiro的安全框架,主要包括如何配置Shiro的安全管理器、如何创建自定义的Realm以及如何在Controller层处理登录和注销的请求。通过整合Shiro,我们可以为应用程序提供更加全面和灵活的安全性。
### 回答3:
Springboot 是一个非常优秀的 Java 企业级开发框架,它凭借其简化的开发流程和强大的功能特性,成为了 Java 开发者们的首选框架。Shiro 是一个广泛应用于安全领域的 Java 安全框架,其主要用于身份认证、授权和会话管理等方面,同样备受 Java 开发者们的青睐。两者结合可以更方便地提供丰富的身份认证和授权功能。
如何使用 Springboot 整合 Shiro 呢?下面我们来逐步实现。
1. 引入 Shiro 依赖
首先,在 Springboot 工程中的 pom.xml 文件中添加 Shiro 依赖:
```
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.2</version>
</dependency>
```
2. 添加 Shiro 配置文件
在 resources 目录下添加 shiro.ini 配置文件,配置用户的权限信息和认证信息等。
3. 配置 ShiroFilterFactoryBean
在 Springboot 中,可以使用 ShiroFilterFactoryBean 定义 Shiro 的过滤操作。具体来说,在 Springboot 工程中的 configuration 包中创建 ShiroConfig 类,并添加以下代码:
```
@Bean
public ShiroFilterFactoryBean shiroFilter() {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager());
shiroFilter.setLoginUrl("/login");
shiroFilter.setUnauthorizedUrl("/error");
Map<String, String> filterMap = new LinkedHashMap<String, String>();
filterMap.put("/logout", "logout");
filterMap.put("/static/**", "anon");
filterMap.put("/login", "anon");
filterMap.put("/**", "authc");
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
```
其中,setSecurityManager() 方法用于设置 Shiro 的 SecurityManager,setLoginUrl() 方法用于设置登录地址,setUnauthorizedUrl() 方法用于设置无权限时的地址。filterMap 定义了 URL 对应的访问权限,"anon" 表示匿名访问,"authc" 表示需要身份认证才能访问。
4. 创建 SecurityManager
在刚才的代码中,我们需要创建 SecurityManager 来管理 Shiro 的安全策略。具体来说,我们需要在我们创建的 ShiroConfig 类中添加以下代码:
```
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm());
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(1800000);
securityManager.setSessionManager(sessionManager);
return securityManager;
}
@Bean
public Realm realm() {
return new UserRealm();
}
```
其中,securityManager 用于管理 Shiro 的所有操作,setRealm() 方法设置 Shiro 权限认证操作的 Realm,它继承了 org.apache.shiro.realm.AuthenticatingRealm。sessionManager 用于管理 Shiro 的会话,设置 GlobalSessionTimeout 时间为 30 分钟。我们还需要创建 UserRealm 类,用于实现 Shiro 的安全操作。
5. 实现认证操作
在 UserRealm 类中,我们需要重写 doGetAuthenticationInfo() 方法,以实现用户的认证操作。具体的认证流程如下:
- 当用户请求 URL 时,Shiro 会检查用户是否登录;
- 如果用户没有登录,Shiro 会重定向到登录页;
- 用户在登录页面中输入用户名和密码,提交表单时,Shiro 会调用 Realm 类中的 doGetAuthenticationInfo() 方法来验证用户名和密码;
- 如果验证通过,Shiro 会把用户传给 SecurityManager,SecurityManager 产生一个会话(或修改会话)并返回一个 SessionID。
6. 实现授权操作
在 UserRealm 类中,我们需要重写 doGetAuthorizationInfo() 方法,以实现用户的授权操作。具体的授权流程如下:
- 在用户登录之后,Shiro 会调用 Realm 类中的 doGetAuthorizationInfo() 方法来验证用户的权限;
- Realm 类必须实现 doGetAuthorizationInfo() 方法,否则 Shiro 会认为用户没有任何权限;
- doGetAuthorizationInfo() 方法获取用户的角色和权限信息,并返回给 Shiro。
最后,我们需要在 Springboot 工程的启动类中添加 @EnableShiro 注解,以启用 Shiro 开发模式。
以上是 Springboot 整合 Shiro 的具体步骤,通过整合 Shiro,我们可以更加方便快捷地实现安全认证和授权功能,使我们的应用更加安全稳定。
阅读全文