省略生成springboot项目的过程
1.导入shiro依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.7.1</version>
</dependency>
2.生成相关的实体类(主要分为User用户,Role角色,Permission权限,UserRole用户角色,RolePermission角色权限,如果使用外键,可以省略用户角色和角色权限这两个实体类)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String userName;
private String password;
}
public class Role{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String roleName;
}
public class UserRoles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long userId;
private Long roleId;
}
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
public class RolePermission {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long permissionId;
private Long roleId;
}
3.生成相关的Dao层,此处省略
4.创建shiro认证类(用于登录认证和权限添加)
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
@Autowired
private PermissionDao permissionDao;
@Autowired
private UserRolesDao userRolesDao;
@Autowired
private RolePermissionDao rolePermissionDao;
/**
* 用户认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
// 加这一步的目的是,在Post请求时会先进行认证,然后再请求
if (authenticationToken.getPrincipal() == null) {
return null;
}
// 获取用户信息
UsernamePasswordToken uptoken= (UsernamePasswordToken) authenticationToken;
String username=uptoken.getUsername();
String password=new String(uptoken.getPassword());
User user = userDao.findByUserName(username);
//返回相关的错误信息
if (user==null){
throw new UnknownAccountException("无此用户的信息");
}
if (!user.getPassword().equals(password)){
throw new UnknownAccountException("密码错误!");
}
return new SimpleAuthenticationInfo(user,password,getName());
}
/**
* 角色权限和对应权限添加
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user= (User) principalCollection.getPrimaryPrincipal();
// 添加角色和权限
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
for (Long roleId : userRolesDao.findByUserId(user.getId())) {
// 添加角色
simpleAuthorizationInfo.addRole(roleDao.findById(roleId).get().getRoleName());
for (Long permissionId : rolePermissionDao.findByRoleId(roleId)) {
// 添加权限
simpleAuthorizationInfo.addStringPermission(permissionDao.findById(permissionId).get().getName());
}
}
return simpleAuthorizationInfo;
}
}
5.Shiro配置类
@Configuration
public class ShiroConfig {
// 将验证方式加入容器
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
// 权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
// ShiroFilter工厂,添加对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterMap = new HashMap<String, String>();
// 登出
filterMap.put("/logout", "logout");
// swagger
filterMap.put("/swagger-ui/**", "anon");
filterMap.put("/swagger-ui.html/**", "anon");
filterMap.put("/v3/**", "anon");
// 对所有用户认证
filterMap.put("/**", "authc");
// 登录
shiroFilterFactoryBean.setLoginUrl("/login");
// 错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setUnauthorizedUrl("url");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
// 加入注解的使用
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
6.Controller类
6.1 登录方法
@PostMapping(value = "/login")
public Map login(@RequestBody User user) {
// 添加用户认证信息
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUserName(), user.getPassword());
Subject currentUser=SecurityUtils.getSubject();
// 进行验证,这里捕获异常返回相关信息
try {
currentUser.login(usernamePasswordToken);
}catch (UnknownAccountException e){
return ReturnMap.returnError(e.getMessage()); //返回错误信息给前端
}
currentUser=SecurityUtils.getSubject();
User userInfo= (User) currentUser.getPrincipal();
return ReturnMap.returnRight(userInfo);
}
6.2 权限方法测试(需要在数据库表中添加好相关的信息,权限名为admin)
@RequiresRoles("admin")
@RequiresPermissions("admin")
@GetMapping(value = "/admin")
public Map admin() {
try {
System.out.println("Success");
}catch (AuthenticationException e){
return ReturnMap.returnError("您无权限操作");
}
return ReturnMap.returnRight("Success");
}