springsecurity動態數據查詢

請先閱讀下面內容
sprinboot整合springsecurity

1、數據庫準備

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(10) NOT NULL,
  `permName` varchar(50) DEFAULT NULL,
  `permTag` varchar(50) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL COMMENT '請求url',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT INTO `sys_permission` VALUES ('1', '查詢訂單', 'showOrder', '/showOrder');
INSERT INTO `sys_permission` VALUES ('2', '添加訂單', 'addOrder', '/addOrder');
INSERT INTO `sys_permission` VALUES ('3', '修改訂單', 'updateOrder', '/updateOrder');
INSERT INTO `sys_permission` VALUES ('4', '刪除訂單', 'deleteOrder', '/deleteOrder');

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(10) NOT NULL,
  `roleName` varchar(50) DEFAULT NULL,
  `roleDesc` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('1', 'admin', '管理員');
INSERT INTO `sys_role` VALUES ('2', 'add_user', '添加管理員');

-- ----------------------------
-- Table structure for sys_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
  `role_id` int(10) DEFAULT NULL,
  `perm_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_3` (`role_id`),
  KEY `FK_Reference_4` (`perm_id`),
  CONSTRAINT `FK_Reference_4` FOREIGN KEY (`perm_id`) REFERENCES `sys_permission` (`id`),
  CONSTRAINT `FK_Reference_3` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` VALUES ('1', '2');
INSERT INTO `sys_role_permission` VALUES ('1', '3');
INSERT INTO `sys_role_permission` VALUES ('1', '4');
INSERT INTO `sys_role_permission` VALUES ('2', '1');
INSERT INTO `sys_role_permission` VALUES ('2', '2');

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(10) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `realname` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `createDate` date DEFAULT NULL,
  `lastLoginTime` date DEFAULT NULL,
  `enabled` int(5) DEFAULT NULL,
  `accountNonExpired` int(5) DEFAULT NULL,
  `accountNonLocked` int(5) DEFAULT NULL,
  `credentialsNonExpired` int(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', 'admin', '超級管理員', '207acd61a3c1bd506d7e9a4535359f8a', '2018-11-13', '2018-11-13', '1', '1', '1', '1');
INSERT INTO `sys_user` VALUES ('2', 'userAdd', '添加用戶', '207acd61a3c1bd506d7e9a4535359f8a', '2018-11-13', '2018-11-13', '1', '1', '1', '1');

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `user_id` int(10) DEFAULT NULL,
  `role_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_1` (`user_id`),
  KEY `FK_Reference_2` (`role_id`),
  CONSTRAINT `FK_Reference_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`),
  CONSTRAINT `FK_Reference_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ('1', '1');
INSERT INTO `sys_user_role` VALUES ('2', '2');

2、mybatis引入

pom依賴添加

<!-- springboot 整合mybatis框架 -->
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.2</version>
</dependency>
<!-- alibaba的druid數據庫連接池 -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid-spring-boot-starter</artifactId>
	<version>1.1.9</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>

配置文件添加

####整合數據庫層    
  datasource:
    name: test
    url: jdbc:mysql://127.0.0.1:3306/rbac_db
    username: root
    password: root
    # druid 連接池
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver

3、添加工具類

MD5Util

package com.mine.tools;

import java.security.MessageDigest;

public class MD5Util {
	private static final String SALT = "salt";

	public static String encode(String password) {
		password = password + SALT;
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		char[] charArray = password.toCharArray();
		byte[] byteArray = new byte[charArray.length];

		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16) {
				hexValue.append("0");
			}

			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}

	public static void main(String[] args) {
		System.out.println(MD5Util.encode("123456"));

	}
}

4、添加實體

User

package com.mine.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import lombok.Data;

@Data
public class User implements UserDetails {
	private static final long serialVersionUID = -8383306719730946639L;

	private Integer id;
	private String username;
	private String realname;
	private String password;
	private Date createDate;
	private Date lastLoginTime;
	private boolean enabled;
	private boolean accountNonExpired;
	private boolean accountNonLocked;
	private boolean credentialsNonExpired;
	// 用戶所有權限
	private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

	public Collection<? extends GrantedAuthority> getAuthorities() {
		return authorities;
	}
}

Role

package com.mine.model;

import lombok.Data;

@Data
public class Role {
	private Integer id;
	private String roleName;
	private String roleDesc;
}

Permission

package com.mine.model;

import lombok.Data;

@Data
public class Permission {
	private Integer id;
	// 權限名稱
	private String permName;
	// 權限標識
	private String permTag;
	// 請求url
	private String url;
}

5、添加mapper

UserMapper

package com.mine.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import com.mine.model.Permission;
import com.mine.model.User;

public interface UserMapper {
	// 查詢用戶信息
	@Select(" select * from sys_user where username = #{userName}")
	User findByUsername(@Param("userName") String userName);

	// 查詢用戶的權限
	@Select(" select permission.* from sys_user user" + " inner join sys_user_role user_role"
			+ " on user.id = user_role.user_id inner join "
			+ "sys_role_permission role_permission on user_role.role_id = role_permission.role_id "
			+ " inner join sys_permission permission on role_permission.perm_id = permission.id where user.username = #{userName};")
	List<Permission> findPermissionByUsername(@Param("userName") String userName);
}

PermissionMapper

package com.mine.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Select;

import com.mine.model.Permission;

public interface PermissionMapper {
	// 查詢所有權限
	@Select(" select * from sys_permission ")
	List<Permission> findAllPermission();
}

6、啓動類修改

添加註解

@MapperScan("com.mine.mapper")

7、密碼加密類添加

MyPasswordEncoder

package com.mine.encoder;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import com.mine.tools.MD5Util;

@Component
public class MyPasswordEncoder implements PasswordEncoder {

	public String encode(CharSequence rawPassword) {
		System.out.println("rawPassword" + rawPassword);
		return MD5Util.encode((String)rawPassword);
	}

	public boolean matches(CharSequence rawPassword, String encodedPassword) {
		System.out.println("rawPassword" + rawPassword + ",encodedPassword" + encodedPassword);
		return this.encode(rawPassword).equals(encodedPassword);
	}

}

8、添加用戶信息查詢接口

MyUserDetailsService

package com.mine.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.mine.mapper.UserMapper;
import com.mine.model.Permission;
import com.mine.model.User;

@Service
public class MyUserDetailsService implements UserDetailsService {

	@Autowired
	private UserMapper userMapper;

	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// 1.根據數據庫查詢,用戶是否登陸
		User user = userMapper.findByUsername(username);
		// 2.查詢該用戶信息權限
		if (user != null) {
			// 設置用戶權限
			List<Permission> listPermission = userMapper.findPermissionByUsername(username);
			System.out.println("用戶信息權限:" + user.getUsername() + ",權限:" + listPermission.toString());
			if (listPermission != null && listPermission.size() > 0) {
				List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
				for (Permission permission : listPermission) {
					// 添加用戶權限
					authorities.add(new SimpleGrantedAuthority(permission.getPermTag()));
				}
				// 設置用戶權限
				user.setAuthorities(authorities);
			}

		}
		return user;
	}
}

PermissionService

package com.mine.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mine.mapper.PermissionMapper;
import com.mine.model.Permission;

@Service
public class PermissionService {
	@Autowired
	private PermissionMapper permissionMapper;

	public List<Permission> findAllPermission() {
		return permissionMapper.findAllPermission();
	}
}

9、SecurityConfig動態化改造

  • 賬號與賬號擁有權限動態化
  • 所有權限加載動態化

SecurityConfig

package com.mine.config;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.stereotype.Component;

import com.mine.encoder.MyPasswordEncoder;
import com.mine.handler.MyAuthenticationFailureHandler;
import com.mine.handler.MyAuthenticationSuccessHandler;
import com.mine.model.Permission;
import com.mine.service.MyUserDetailsService;
import com.mine.service.PermissionService;

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Autowired
	private MyAuthenticationSuccessHandler successHandler;

	@Autowired
	private MyAuthenticationFailureHandler failureHandler;

	@Autowired
	private MyUserDetailsService userDetailsService;

	@Autowired
	private MyPasswordEncoder passwordEncoder;

	@Autowired
	private PermissionService permissionService;

	// 用戶認證信息
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
	}

	// 配置HttpSecurity 攔截資源
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http
				.authorizeRequests();
		// 1.讀取數據庫權限列表
		List<Permission> listPermission = permissionService.findAllPermission();
		for (Permission permission : listPermission) {
			// 設置權限
			authorizeRequests.antMatchers(permission.getUrl()).hasAnyAuthority(permission.getPermTag());
		}

		authorizeRequests.antMatchers("/login").permitAll().antMatchers("/logFail").permitAll().antMatchers("/**")
				.fullyAuthenticated().and().formLogin().successHandler(successHandler).failureHandler(failureHandler)
				.loginPage("/login").and().csrf().disable();
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章