帮我写一个简单的demo项目,springboot+shiro+jwt+mybatis,数据库表1:user(id, username, password),表2:role(id, rolename),表3:permissions(id, permissionsname),写出所有代码,不需要数据库代码和pmo.xml代码
时间: 2024-02-09 21:07:01 浏览: 141
好的,下面是一个简单的demo项目,基于Spring Boot集成Shiro和JWT进行权限控制,使用MyBatis操作数据库。
1. 创建一个Spring Boot项目,引入相关依赖:
```
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
```
2. 配置Shiro相关的Bean和JWT相关的Bean,创建一个ShiroConfig类,并添加以下内容:
```
@Configuration
public class ShiroConfig {
@Bean
public Realm realm() {
// 创建自定义的Realm
return new MyRealm();
}
@Bean
public SecurityManager securityManager() {
// 创建SecurityManager,并设置Realm
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm());
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter() {
// 创建ShiroFilterFactoryBean,并设置SecurityManager和拦截器
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager());
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/**", "jwt");
shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilter;
}
@Bean
public JwtRealm jwtRealm() {
// 创建JwtRealm
return new JwtRealm();
}
@Bean
public JwtFilter jwtFilter() {
// 创建JwtFilter
return new JwtFilter();
}
}
```
3. 配置MyBatis相关的Bean,创建一个MyBatisConfig类,并添加以下内容:
```
@Configuration
@MapperScan("com.example.demo.mapper")
public class MyBatisConfig {
@Bean
public DataSource dataSource() {
// 创建H2数据库
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("schema.sql")
.build();
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
// 创建SqlSessionFactory,并设置DataSource和Mapper
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactory.setMapperLocations(resolver.getResources("classpath:/mapper/*.xml"));
return sessionFactory.getObject();
}
}
```
4. 创建一个User实体类,包含id、username和password字段。
```
public class User {
private Long id;
private String username;
private String password;
// getter和setter方法省略
}
```
5. 创建一个Role实体类,包含id和roleName字段。
```
public class Role {
private Long id;
private String roleName;
// getter和setter方法省略
}
```
6. 创建一个Permission实体类,包含id和permissionName字段。
```
public class Permission {
private Long id;
private String permissionName;
// getter和setter方法省略
}
```
7. 创建一个UserMapper接口,定义对User表的操作。
```
@Mapper
public interface UserMapper {
User findByUsername(String username);
}
```
8. 创建一个RoleMapper接口,定义对Role表的操作。
```
@Mapper
public interface RoleMapper {
List<Role> findByUserId(Long userId);
}
```
9. 创建一个PermissionMapper接口,定义对Permission表的操作。
```
@Mapper
public interface PermissionMapper {
List<Permission> findByRoleId(Long roleId);
}
```
10. 创建一个UserService类,添加以下内容:
```
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private RoleMapper roleMapper;
@Autowired
private PermissionMapper permissionMapper;
public User findByUsername(String username) {
return userMapper.findByUsername(username);
}
public List<Role> findRolesByUserId(Long userId) {
return roleMapper.findByUserId(userId);
}
public List<Permission> findPermissionsByRoleId(Long roleId) {
return permissionMapper.findByRoleId(roleId);
}
}
```
11. 创建一个JwtUtils类,添加以下内容:
```
public class JwtUtils {
private static final String SECRET_KEY = "mysecretkey"; // 密钥
private static final long EXPIRATION_TIME = 60 * 60 * 24 * 7; // 过期时间,单位为秒
// 生成JWT
public static String generateToken(String username) {
Date now = new Date();
Date expirationDate = new Date(now.getTime() + EXPIRATION_TIME * 1000);
return Jwts.builder()
.setSubject(username)
.setIssuedAt(now)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// 解析JWT
public static Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
// 验证JWT
public static boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
```
12. 创建一个JwtRealm类,继承AuthorizingRealm类,添加以下内容:
```
public class JwtRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
// 支持JwtToken
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JwtToken;
}
// 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
List<Role> roles = userService.findRolesByUserId(1L); // 假设用户ID为1
List<String> roleNames = roles.stream().map(Role::getRoleName).collect(Collectors.toList());
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addRoles(roleNames);
for (Role role : roles) {
List<Permission> permissions = userService.findPermissionsByRoleId(role.getId());
List<String> permissionNames = permissions.stream().map(Permission::getPermissionName).collect(Collectors.toList());
authorizationInfo.addStringPermissions(permissionNames);
}
return authorizationInfo;
}
// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
User user = userService.findByUsername(username);
if (user == null) {
throw new UnknownAccountException();
}
return new SimpleAuthenticationInfo(username, user.getPassword(), getName());
}
}
```
13. 创建一个JwtToken类,实现AuthenticationToken接口,添加以下内容:
```
public class JwtToken implements AuthenticationToken {
private String token;
public JwtToken(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return JwtUtils.parseToken(token).getSubject();
}
@Override
public Object getCredentials() {
return token;
}
}
```
14. 创建一个JwtFilter类,继承BasicHttpAuthenticationFilter类,添加以下内容:
```
public class JwtFilter extends BasicHttpAuthenticationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
String token = getToken(request);
if (token == null || !JwtUtils.validateToken(token)) {
return false;
}
JwtToken jwtToken = new JwtToken(token);
try {
getSubject(request, response).login(jwtToken);
return true;
} catch (Exception e) {
return false;
}
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
response.setContentType("application/json;charset=UTF-8");
try {
PrintWriter out = response.getWriter();
out.write("{\"code\":401,\"message\":\"未登录\"}");
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private String getToken(ServletRequest request) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader("Authorization");
if (StringUtils.isNotEmpty(token) && token.startsWith("Bearer ")) {
return token.substring(7);
}
return null;
}
}
```
15. 创建一个UserController类,添加以下内容:
```
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/login")
public String login(String username, String password) {
User user = userService.findByUsername(username);
if (user == null || !user.getPassword().equals(password)) {
return "{\"code\":401,\"message\":\"用户名或密码错误\"}";
}
String token = JwtUtils.generateToken(username);
return "{\"code\":200,\"message\":\"登录成功\",\"token\":\"" + token + "\"}";
}
@GetMapping("/user")
@RequiresPermissions("user:view")
public String viewUser() {
return "View User";
}
}
```
以上是一个简单的demo项目,实现了基于Spring Boot集成Shiro和JWT进行权限控制,使用MyBatis操作数据库。需要注意的是,这里的代码仅供参考,具体实现还需要根据实际情况进行调整。
阅读全文