详解Spring整合Shiro权限管理与数据库设计
引言
本文详细讲解如何使用Spring框架整合Shiro权限管理,并给出完整的数据库设计方案和示例代码。
Shiro简介
Shiro是一个强大的Java安全框架,可以提供身份认证、授权、加密等各种安全相关的功能。Shiro使用非常简单,易于集成到Java应用中。
Spring整合Shiro权限管理
引入Shiro依赖
在pom.xml文件中加入以下依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.2</version>
</dependency>
配置Shiro
在Spring配置文件中加入以下内容:
<!-- Shiro过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<property name="filterChainDefinitions">
<value>
/login.jsp = anon
/doLogin = anon
/logout = logout
/** = authc
</value>
</property>
</bean>
<!-- Shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean>
<!-- Shiro Realm -->
<bean id="myRealm" class="com.example.MyRealm">
<!-- 可以配置一些Realm的属性 -->
</bean>
其中,ShiroFilterFactoryBean是Shiro的核心过滤器,必须配置。securityManager是Shiro的安全管理器,使用DefaultWebSecurityManager即可。MyRealm是我们自己实现的认证和授权逻辑,需要用到时自行编写。
编写MyRealm
public class MyRealm extends AuthorizingRealm {
public void setName(String name) {
super.setName("myRealm");
}
/**
* 认证逻辑
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
// 根据用户名查询用户信息
User user = userDao.findByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户不存在!");
}
// 封装认证信息
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
return info;
}
/**
* 授权逻辑
*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
Set<String> roles = userDao.findRoles(username);
Set<String> permissions = userDao.findPermissions(username);
// 封装授权信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roles);
info.setStringPermissions(permissions);
return info;
}
}
其中,doGetAuthenticationInfo方法实现认证逻辑,doGetAuthorizationInfo方法实现授权逻辑。通过调用userDao的方法查询数据库获取用户信息和权限信息。
编写UserDao接口
public interface UserDao {
User findByUsername(String username);
Set<String> findRoles(String username);
Set<String> findPermissions(String username);
}
这是一个比较简单的DAO接口,用于查询用户信息、角色信息和权限信息。实现可以使用MyBatis、Hibernate等持久层框架。
数据库设计
在使用Shiro进行权限管理时,需要设计数据库表来存储用户信息、角色信息和权限信息。
以MySQL为例,以下是一个简单的数据库设计。
用户表
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名',
`password` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码',
`salt` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '盐值',
`locked` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0未锁定,1锁定',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
角色表
CREATE TABLE `role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色名',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';
用户角色关联表
CREATE TABLE `user_role` (
`user_id` bigint(20) NOT NULL COMMENT '用户id',
`role_id` bigint(20) NOT NULL COMMENT '角色id',
PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色关联表';
权限表
CREATE TABLE `permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '权限名',
`url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'URL',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='权限表';
角色权限关联表
CREATE TABLE `role_permission` (
`role_id` bigint(20) NOT NULL COMMENT '角色id',
`permission_id` bigint(20) NOT NULL COMMENT '权限id',
PRIMARY KEY (`role_id`,`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色权限关联表';
示例
以下是一个简单的示例,演示如何使用Shiro进行身份认证和授权。
登录Controller
@Controller
public class LoginController {
@RequestMapping("/doLogin")
public String doLogin(String username, String password) {
// 封装用户名和密码为Token
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
// 进行登录认证
SecurityUtils.getSubject().login(token);
return "redirect:/index.jsp";
} catch (Exception e) {
e.printStackTrace();
return "redirect:/login.jsp";
}
}
}
权限控制
@Controller
public class UserController {
@RequiresPermissions("user:view")
@RequestMapping("/list")
public String list() {
// 查询用户列表
List<User> userList = userService.findAll();
return "user/list";
}
@RequiresPermissions("user:add")
@RequestMapping("/add")
public String add(User user) {
// 添加用户
return "redirect:/list";
}
@RequiresPermissions("user:delete")
@RequestMapping("/delete")
public String delete(Long userId) {
// 删除用户
return "redirect:/list";
}
}
在UserController中,使用@RequiresPermissions注解指定方法需要的权限。如果当前用户没有该权限,将会抛出UnauthorizedException异常,需要在异常处理器中进行处理。
结语
本文详细讲解了如何使用Spring框架整合Shiro权限管理,并给出了完整的数据库设计方案和示例代码。Shiro是一个非常好用的Java安全框架,可以帮助我们实现身份认证、授权等各种安全相关的功能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解spring整合shiro权限管理与数据库设计 - Python技术站