提交 e13d534e 编写于 作者: S studyingpanda

chen

上级 f31cd070
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server : 本机
Source Server Type : MySQL
Source Server Version : 50724
Source Host : localhost:3306
Source Server Version : 50722
Source Host : 127.0.0.1:3306
Source Schema : shop
Target Server Type : MySQL
Target Server Version : 50724
Target Server Version : 50722
File Encoding : 65001
Date: 22/05/2020 23:16:37
Date: 24/05/2020 17:46:19
*/
SET NAMES utf8mb4;
......@@ -23,17 +23,48 @@ SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `api`;
CREATE TABLE `api` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of api
-- ----------------------------
INSERT INTO `api` VALUES (1, 'addGooods');
INSERT INTO `api` VALUES (2, 'removeGoods');
INSERT INTO `api` VALUES (3, 'editGoods');
INSERT INTO `api` VALUES (4, 'viewGoods');
INSERT INTO `api` VALUES (1, 'viewGoods');
INSERT INTO `api` VALUES (2, 'addGoods');
-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '唯一标志',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名称',
`num` bigint(255) NULL DEFAULT NULL COMMENT '库存数量',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, '手机', -80);
-- ----------------------------
-- Table structure for order
-- ----------------------------
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '唯一标识',
`goods_id` bigint(20) NULL DEFAULT NULL COMMENT '商品id',
`count` bigint(20) NULL DEFAULT NULL COMMENT '购买数量',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 45 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of order
-- ----------------------------
INSERT INTO `order` VALUES (43, 1, 1);
INSERT INTO `order` VALUES (44, 1, 1);
-- ----------------------------
-- Table structure for role
......@@ -41,7 +72,7 @@ INSERT INTO `api` VALUES (4, 'viewGoods');
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '角色名称',
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '角色名称',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
......@@ -57,8 +88,8 @@ INSERT INTO `role` VALUES (2, '游客');
DROP TABLE IF EXISTS `roleapi`;
CREATE TABLE `roleapi` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`roleId` bigint(11) DEFAULT NULL,
`apiId` bigint(11) DEFAULT NULL,
`roleId` bigint(11) NULL DEFAULT NULL,
`apiId` bigint(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
......@@ -67,9 +98,7 @@ CREATE TABLE `roleapi` (
-- ----------------------------
INSERT INTO `roleapi` VALUES (1, 1, 1);
INSERT INTO `roleapi` VALUES (2, 1, 2);
INSERT INTO `roleapi` VALUES (3, 1, 3);
INSERT INTO `roleapi` VALUES (4, 1, 4);
INSERT INTO `roleapi` VALUES (5, 2, 4);
INSERT INTO `roleapi` VALUES (3, 2, 1);
-- ----------------------------
-- Table structure for user
......@@ -77,16 +106,16 @@ INSERT INTO `roleapi` VALUES (5, 2, 4);
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '',
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '',
`roleId` bigint(20) DEFAULT NULL,
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '',
`password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '',
`roleId` bigint(20) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'admin', 'admin', 1);
INSERT INTO `user` VALUES (2, 'guest', 'guest', 2);
INSERT INTO `user` VALUES (1, 'admin', '$2a$10$D0OvhHj2Lh92rNey1EFmM.OqltxhH1vZA8mDpxz7jEofDEqLRplQy', 1);
INSERT INTO `user` VALUES (2, 'guest', '$2a$10$D0OvhHj2Lh92rNey1EFmM.OqltxhH1vZA8mDpxz7jEofDEqLRplQy', 2);
SET FOREIGN_KEY_CHECKS = 1;
package com.imooc.springbootsecurity;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class ApiDao {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 获取所有api
*/
public List<String> getApiPaths() {
String sql = "select path from api";
return jdbcTemplate.queryForList(sql, String.class);
}
}
package com.imooc.springbootsecurity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 商品控制器类
*/
@RestController
public class GoodsController {
/**
* 添加商品
*/
@GetMapping("/addGoods")
public String addGoods() {
return "success";
}
/**
* 删除商品
*/
@GetMapping("/removeGoods")
public String removeGoods() {
return "success";
}
/**
* 修改商品
*/
@GetMapping("/editGoods")
public String editGoods() {
return "success";
}
/**
* 查看商品
*/
@GetMapping("/viewGoods")
public String viewGoods() {
return "success";
}
}
package com.imooc.springbootsecurity;
/**
* 后端接口返回的统一业务逻辑对象
*/
public class ResultBo<T> {
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
/**
* 错误码 0表示没有错误(异常) 其他数字代表具体错误码
*/
private int code;
/**
* 后端返回消息
*/
private String msg;
/**
* 后端返回的数据
*/
private T data;
/**
* 无参数构造函数
*/
public ResultBo() {
this.code = 0;
this.msg = "操作成功";
}
/**
* 带数据data构造函数
*/
public ResultBo(T data) {
this();
this.data = data;
}
/**
* 存在异常的构造函数
*/
public ResultBo(Exception ex) {
this.code = 99999;// 其他未定义异常
this.msg = ex.getMessage();
}
}
\ No newline at end of file
package com.imooc.springbootsecurity;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
@EnableWebSecurity // 启用安全管理
public class SecurityConfig {
@Autowired
private SecurityService securityService;
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() {
return new WebSecurityConfigurerAdapter() {
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
// 从数据库中获取权限列表
List<String> paths = securityService.getApiPaths();
for (String path : paths) {
// 对/xxx/**路径的访问,需要具备xxx权限
// 例如访问/addGoods,需要具备addGoods权限
httpSecurity.authorizeRequests().antMatchers("/" + path + "/**").hasAuthority(path);
}
// 未登录时自动跳转/notLogin
httpSecurity.authorizeRequests().and().formLogin().loginPage("/notLogin")
// 登录处理路径、用户名、密码
.loginProcessingUrl("/login").usernameParameter("username").passwordParameter("password")
.permitAll()
// 登录成功处理
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Authentication authentication)
throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
ResultBo result = new ResultBo<>();
ObjectMapper mapper = new ObjectMapper();
PrintWriter out = httpServletResponse.getWriter();
out.write(mapper.writeValueAsString(result));
out.close();
}
})
// 登录失败处理
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, AuthenticationException e)
throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
ResultBo result = new ResultBo<>(new Exception("登录失败"));
ObjectMapper mapper = new ObjectMapper();
PrintWriter out = httpServletResponse.getWriter();
out.write(mapper.writeValueAsString(result));
out.flush();
out.close();
}
});
// 禁用csrf(跨站请求伪造)
httpSecurity.authorizeRequests().and().csrf().disable();
}
};
}
@Bean
public UserDetailsService userDetailsService() {
return username -> {
List<UserDo> users = securityService.getUserByUsername(username);
if (users == null || users.size() == 0) {
throw new UsernameNotFoundException("用户名错误");
}
String password = users.get(0).getPassword();
List<String> apis = securityService.getApisByUsername(username);
// 将用户名username、密码password、对应权限列表apis放入组件
return User.withUsername(username).password(password).authorities(apis.toArray(new String[apis.size()]))
.build();
};
}
public static void main(String[] args) {
// 输出 $2a$10$kLQpA8S1z0KdgR3Cr6jJJ.R.QsIT7nrCdAfsF4Of84ZBX2lvgtbE.
System.out.println(new BCryptPasswordEncoder().encode("123"));
}
}
......@@ -5,16 +5,22 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 商品服务类
*/
@Service
public class UserService {
public class SecurityService {
@Autowired
private UserDao userDao;
@Autowired
private ApiDao apiDao;
public List<UserDo> getUserByUsername(String username) {
return userDao.getUsersByUsername(username);
}
public List<String> getApisByUsername(String username) {
return userDao.getApisByUsername(username);
}
public List<String> getApiPaths() {
return apiDao.getApiPaths();
}
}
package com.imooc.springbootsecurity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
/**
* 未登录时调用该方法
*/
@RequestMapping("/notLogin")
public ResultBo notLogin() {
return new ResultBo(new Exception("未登录"));
}
/**
* 查看商品
*/
@RequestMapping("/viewGoods")
public ResultBo viewGoods() {
return new ResultBo<>("viewGoods is ok");
}
/**
* 添加商品
*/
@RequestMapping("/addGoods")
public ResultBo addGoods() {
return new ResultBo<>("addGoods is ok");
}
}
......@@ -11,15 +11,18 @@ import org.springframework.stereotype.Repository;
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 根据用户名获取用户信息
*/
public List<UserDo> getUsersByUsername(String username) {
String sql = "select id, username, password from user where username = ?";
return jdbcTemplate.query(sql, new String[] { username }, new BeanPropertyRowMapper<>(UserDo.class));
}
/**
* 根据用户名获取其可访问的api列表
*/
public List<String> getApisByUsername(String username) {
String sql = "select path from user left join roleapi on user.roleId=roleapi.roleId left join api on roleapi.apiId=api.id where username='?' ";
String sql = "select path from user left join roleapi on user.roleId=roleapi.roleId left join api on roleapi.apiId=api.id where username=? ";
return jdbcTemplate.queryForList(sql, new String[] { username }, String.class);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册