介绍
在Web应用程序中,用户认证是一个非常重要的功能。Spring Boot提供了与Shiro集成的便捷方式,以便快速实现安全的用户认证。Shiro是一个功能强大且灵活的开源安全框架,它提供了认证、授权、加密和会话管理等功能。
本文将介绍如何使用Spring Boot和Shiro来实现用户认证的功能,并且通过演示具体的代码示例来帮助读者更好地理解。
环境配置
在开始之前,确保你已经安装并配置好了以下环境:
- Java开发环境
- Maven构建工具
- Spring Boot
添加依赖
首先,在你的Maven项目的pom.xml
文件中,添加以下依赖:
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Shiro Starter -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>
这样,你的项目就添加了Spring Boot和Shiro的相关依赖。
配置Shiro
接下来,你需要创建一个Shiro配置类来配置Shiro的相关信息。在src/main/java
目录下创建一个新的Java类,命名为ShiroConfig
。
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
factoryBean.setLoginUrl("/login");
factoryBean.setUnauthorizedUrl("/403");
// 设置过滤器链
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/**", "authc");
factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return factoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public Realm realm() {
return new MyRealm();
}
}
这个配置类使用@Configuration
注解告诉Spring Boot,这是一个配置类。其中,shiroFilterFactoryBean
方法用于配置Shiro的过滤器链,securityManager
方法用于创建Shiro的安全管理器,realm
方法用于创建自定义的Realm。
实现自定义的Realm
在上面的配置类中,我们使用了自定义的Realm,这是为了定义Shiro的认证逻辑。在src/main/java
目录下创建一个新的Java类,命名为MyRealm
。
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 设置用户的角色和权限
authorizationInfo.addRole("admin");
authorizationInfo.addStringPermission("user:create");
authorizationInfo.addStringPermission("user:delete");
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
// 模拟从数据库中获取用户信息
if (!"admin".equals(username)) {
throw new UnknownAccountException();
}
// 返回认证信息
return new SimpleAuthenticationInfo(username, "password", getName());
}
}
在这个自定义的Realm中,我们通过重写doGetAuthorizationInfo
方法和doGetAuthenticationInfo
方法来定义Shiro的授权和认证逻辑。
在doGetAuthorizationInfo
方法中,我们设置了用户的角色和权限。具体的角色和权限信息应该从数据库中获取,这里我们仅作演示之用。
在doGetAuthenticationInfo
方法中,我们模拟从数据库中获取用户信息,并返回认证信息。
创建登录页面
创建一个新的HTML文件,名为login.html
,在src/main/resources/static/
目录下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="/login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<br>
<input type="submit" value="Login">
</form>
</body>
</html>
这个登录页面包含了一个表单,用于用户输入用户名和密码。提交表单后,页面会将表单数据发送到/login
接口。
创建登录成功页面
创建一个新的HTML文件,名为success.html
,在src/main/resources/static/
目录下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Success</title>
</head>
<body>
<h1>Login Successful!</h1>
</body>
</html>
这个页面显示了登录成功的消息。
创建登录失败页面
创建一个新的HTML文件,名为failure.html
,在src/main/resources/static/
目录下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Failure</title>
</head>
<body>
<h1>Login Failure!</h1>
</body>
</html>
这个页面显示了登录失败的消息。
编写控制器
创建一个新的Java类,命名为LoginController
,在src/main/java
目录下。
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping("/login")
public String doLogin(String username, String password, HttpServletRequest request) {
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject currentUser = SecurityUtils.getSubject();
try {
currentUser.login(token);
return "redirect:/success";
} catch (UnknownAccountException e) {
return "redirect:/failure";
}
}
@GetMapping("/success")
public String success() {
return "success";
}
@GetMapping("/failure")
public String failure() {
return "failure";
}
}
在这个控制器中,login
方法返回login.html
页面,用于展示登录页面。
doLogin
方法接收表单数据,并通过SecurityUtils.getSubject().login(token)
进行用户认证。如果认证成功,就重定向到success
页面;如果认证失败,就重定向到failure
页面。
success
方法返回success.html
页面,用于展示登录成功的消息。
failure
方法返回failure.html
页面,用于展示登录失败的消息。
运行应用程序
现在,你可以运行你的应用程序了。执行以下Maven命令来启动应用程序:
mvn spring-boot:run
然后,在浏览器中访问http://localhost:8080/login
,你将看到登录页面。输入用户名和密码进行登录,系统将根据输入的信息进行用户认证。如果认证成功,将重定向到成功页面;否则将重定向到失败页面。
结论
本文介绍了如何使用Spring Boot和Shiro来实现用户认证的功能。通过自定义Realm来定义Shiro的授权和认证逻辑,通过配置类来配置Shiro的相关信息,通过控制器来处理登录请求。
Shiro是一个功能强大且灵活的安全框架,可以帮助我们实现多种安全功能。希望本文能帮助读者更好地理解和使用Spring Boot和Shiro来进行用户认证。
如果你想了解更多关于Spring Boot和Shiro的内容,请查阅官方文档和其他相关资源。
参考链接:
本文来自极简博客,作者:糖果女孩,转载请注明原文链接:Spring Boot Shiro用户认证