Skip to content

Commit

Permalink
SpringBoot2.x 整合Mybatis,Redis(含分布式锁实现/接口限流实现),Shiro(权限安全框架),消息队列功能实现(…
Browse files Browse the repository at this point in the history
…RabbitMQ/Kafka),Thymeleaf,Swagger2等简单案例
  • Loading branch information
g-HJY committed Jul 5, 2022
1 parent db3be8a commit d9ba92c
Show file tree
Hide file tree
Showing 11 changed files with 356 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SpringBootDemo

#### SpringBoot2.x 整合Mybatis,Redis(含分布式锁实现/接口限流实现),消息队列功能实现(RabbitMQ/Kafka),Thymeleaf,Swagger2等简单案例
#### SpringBoot2.x 整合Mybatis,Redis(含分布式锁实现/接口限流实现),Shiro(权限安全框架),消息队列功能实现(RabbitMQ/Kafka),Thymeleaf,Swagger2等简单案例

#### 一.项目运行要求
完整测试本Demo所有功能接口需要安装如下工具:
Expand Down
20 changes: 20 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,26 @@
</dependency>


<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.6.0</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--页面模板依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>



</dependencies>

<build>
Expand Down
69 changes: 69 additions & 0 deletions src/main/java/com/example/demo/shiro/CustomRealm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.example.demo.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

public class CustomRealm extends AuthorizingRealm {

@Autowired
private LoginService loginService;

/**
* @MethodName doGetAuthorizationInfo
* @Description 权限配置类
* @Param [principalCollection]
* @Return AuthorizationInfo
* @Author WangShiLin
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取登录用户名
String name = (String) principalCollection.getPrimaryPrincipal();
//查询用户名称
User user = loginService.getUserByName(name);
//添加角色和权限
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
for (Role role : user.getRoles()) {
//添加角色
simpleAuthorizationInfo.addRole(role.getRoleName());
//添加权限
for (Permissions permissions : role.getPermissions()) {
simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
}
}
return simpleAuthorizationInfo;
}

/**
* @MethodName doGetAuthenticationInfo
* @Description 认证配置类
* @Param [authenticationToken]
* @Return AuthenticationInfo
* @Author WangShiLin
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if (StringUtils.isEmpty(authenticationToken.getPrincipal())) {
return null;
}
//获取用户信息
String name = authenticationToken.getPrincipal().toString();
User user = loginService.getUserByName(name);
if (user == null) {
//这里返回后会报出对应异常
return null;
} else {
//这里验证authenticationToken和simpleAuthenticationInfo的信息
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
return simpleAuthenticationInfo;
}
}
}
72 changes: 72 additions & 0 deletions src/main/java/com/example/demo/shiro/LoginController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.example.demo.shiro;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class LoginController {

@GetMapping("/login")
public String login(User user) {
if (StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassword())) {
return "请输入用户名和密码!";
}
//用户认证信息
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
user.getUserName(),
user.getPassword()
);
try {
//进行验证,这里可以捕获异常,然后返回对应信息
subject.login(usernamePasswordToken);
// subject.checkRole("admin");
// subject.checkPermissions("query", "add");
} catch (UnknownAccountException e) {
log.error("用户名不存在!", e);
return "用户名不存在!";
} catch (AuthenticationException e) {
log.error("账号或密码错误!", e);
return "账号或密码错误!";
} catch (AuthorizationException e) {
log.error("没有权限!", e);
return "没有权限";
}
return "login success";
}

@RequiresRoles("admin")
@GetMapping("/admin")
public String admin() {
return "admin success!";
}

@RequiresPermissions("query")
@GetMapping("/index")
public String index() {
return "index success!";
}

//@RequiresPermissions("add")
@GetMapping("/add")
public String add() {
return "add success!";
}


@GetMapping("/logout")
public String logout() {
return "logout success!";
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/example/demo/shiro/LoginService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.demo.shiro;

/**
* @author HJY
* @date 2022/7/4 18:01
* desc :
*/
public interface LoginService {

User getUserByName(String getMapByName);
}
46 changes: 46 additions & 0 deletions src/main/java/com/example/demo/shiro/LoginServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.example.demo.shiro;

import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Service
public class LoginServiceImpl implements LoginService {

@Override
public User getUserByName(String getMapByName) {
return getMapByName(getMapByName);
}

/**
* 模拟数据库查询
*
* @param userName 用户名
* @return User
*/
private User getMapByName(String userName) {
Permissions permissions1 = new Permissions("1", "query");
Permissions permissions2 = new Permissions("2", "add");
Set<Permissions> permissionsSet = new HashSet<>();
permissionsSet.add(permissions1);
permissionsSet.add(permissions2);
Role role = new Role("1", "admin", permissionsSet);
Set<Role> roleSet = new HashSet<>();
roleSet.add(role);
User user = new User("1", "wsl", "123456", roleSet);
Map<String, User> map = new HashMap<>();
map.put(user.getUserName(), user);

Set<Permissions> permissionsSet1 = new HashSet<>();
permissionsSet1.add(permissions1);
Role role1 = new Role("2", "user", permissionsSet1);
Set<Role> roleSet1 = new HashSet<>();
roleSet1.add(role1);
User user1 = new User("2", "zhangsan", "123456", roleSet1);
map.put(user1.getUserName(), user1);
return map.get(userName);
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/example/demo/shiro/MyExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.demo.shiro;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
@Slf4j
public class MyExceptionHandler {

@ExceptionHandler
@ResponseBody
public String ErrorHandler(AuthorizationException e) {
log.error("没有通过权限验证!", e);
return "没有通过权限验证!";
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/example/demo/shiro/Permissions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.demo.shiro;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Permissions {
private String id;
private String permissionsName;
}
18 changes: 18 additions & 0 deletions src/main/java/com/example/demo/shiro/Role.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.demo.shiro;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.Set;

@Data
@AllArgsConstructor
public class Role {

private String id;
private String roleName;
/**
* 角色对应权限集合
*/
private Set<Permissions> permissions;
}
71 changes: 71 additions & 0 deletions src/main/java/com/example/demo/shiro/ShiroConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.example.demo.shiro;

import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}

//将自己的验证方式加入容器
@Bean
public CustomRealm myShiroRealm() {
CustomRealm customRealm = new CustomRealm();
return customRealm;
}

//权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}

//Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> map = new HashMap<>();
//登出
map.put("/logout", "logout");
//对所有用户认证
map.put("/**", "authc");

//这样以后请求路径中含有/add都能放行,不会再受/login的拦截。
//map.put("/add/**", "anon");

//登录
shiroFilterFactoryBean.setLoginUrl("/login");
//首页
shiroFilterFactoryBean.setSuccessUrl("/index");
//错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}


@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
18 changes: 18 additions & 0 deletions src/main/java/com/example/demo/shiro/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.demo.shiro;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.Set;

@Data
@AllArgsConstructor
public class User {
private String id;
private String userName;
private String password;
/**
* 用户对应的角色集合
*/
private Set<Role> roles;
}

0 comments on commit d9ba92c

Please sign in to comment.