为Java后端项目添加Shiro进行身份验证,授权操作:
步骤1.引入相关依赖:
html
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.9.1</version> <!-- 确保使用最新版本 -->
</dependency>
步骤2.配置shiro.ini
在resources目录下进行添加shiro.ini文件
html
[main]
# Realm配置
myRealm = org.apache.shiro.realm.jdbc.JdbcRealm
myRealm.dataSource = myDataSource
# 使用自定义Realm
securityManager.realms = $myRealm
[users]
# 用户名 = 密码, 角色
admin = secret, admin
guest = guest, guest
[roles]
# 角色 = 权限
admin = *
guest = read
user = read
步骤3.配置ShiroConfig
在config目录下创建ShiroConfig.java文件
java
package com.cetide.oj.config;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public Realm myRealm() {
// 返回你自己的 Realm 实现
return new MyRealm();
}
@Bean
public ModularRealmAuthenticator authenticator() {
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
authenticator.setRealms(Arrays.asList(myRealm()));
return authenticator;
}
@Bean
public ModularRealmAuthorizer authorizer() {
ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
authorizer.setRealms(Arrays.asList(myRealm()));
return authorizer;
}
@Bean
public SecurityManager securityManager(DataSource dataSource) {
JdbcRealm realm = new JdbcRealm();
realm.setDataSource(dataSource);
// 配置Realm的用户查询和角色查询
realm.setPermissionsLookupEnabled(true); // 启用权限查找
// 你可以在这里设置自定义的SQL查询以获取用户和角色信息
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm);
return securityManager;
}
@Bean
public DefaultSessionManager sessionManager() {
DefaultSessionManager sessionManager = new DefaultSessionManager();
return sessionManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(securityManager);
// 配置访问路径
Map<String, String> filterChainDefinitionMap = new HashMap<>();
filterChainDefinitionMap.put("/admin/**", "roles[admin]");
filterChainDefinitionMap.put("/guest/**", "roles[guest]");
filterChainDefinitionMap.put("/**", "anon"); // 允许匿名访问
filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return filterFactoryBean;
}
}
步骤4.配置自定义MyRealm
java
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 info = new SimpleAuthorizationInfo();
if ("admin".equals(username)) {
info.addRole("admin");
info.addStringPermission("*"); // admin有所有权限
} else if ("guest".equals(username)) {
info.addRole("guest");
info.addStringPermission("read"); // guest仅有读取权限
}
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 模拟数据库查询
if ("admin".equals(username) && "123456".equals(password)) {
return new SimpleAuthenticationInfo(username, password, getName());
} else {
throw new UnknownAccountException("用户名或密码错误");
}
}
}
步骤5.引入到Controller中
java
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@PostMapping("/login")
public String login(String username, String password) {
Subject currentUser = SecurityUtils.getSubject();
if (!currentUser.isAuthenticated()) {
// 创建一个用户认证的token
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
// 执行登录操作
currentUser.login(token);
if (currentUser.hasRole("admin")) {
return "admin"; // 返回管理员视图
}
return "403"; // 无权限视图
} catch (Exception e) {
e.printStackTrace();
return "loginError"; // 登录失败,返回错误视图
}
}
return "redirect:/"; // 已经登录,重定向到主页
}
@RequestMapping("/logout")
public String logout() {
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.isAuthenticated()) {
currentUser.logout(); // 执行注销
}
return "redirect:/"; // 注销后重定向到主页
}
@GetMapping("/")
public String home() {
return "index"; // 返回主页视图
}
@GetMapping("/admin")
public String admin() {
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.hasRole("admin")) {
return "admin"; // 返回管理员视图
}
return "403"; // 无权限视图
}
@GetMapping("/guest")
public String guest() {
return "guest"; // 返回访客视图
}
}