一 建表
权限管理需实现5张表:用户表、角色表、用户角色对应表、权限表、权限角色对应表
用户表
CREATE TABLE platform_user (
id bigint(20) NOT NULL AUTO_INCREMENT,
username varchar(50) NOT NULL,
password varchar(100) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
角色表
CREATE TABLE platform_role (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT=‘这只是角色表’;
用户角色对应表
CREATE TABLE platform_role_user (
id int(11) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
role_id int(11) NOT NULL,
PRIMARY KEY (id),
KEY FKt6466kf26ep5v3rfcya2sxi53 (role_id),
KEY FKfwy3bmkplk822fdp5o1btjyyv (user_id),
CONSTRAINT FKfwy3bmkplk822fdp5o1btjyyv FOREIGN KEY (user_id) REFERENCES platform_user (id),
CONSTRAINT FKt6466kf26ep5v3rfcya2sxi53 FOREIGN KEY (role_id) REFERENCES platform_role (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
权限表
CREATE TABLE platform_sys_permission (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
description varchar(50) NOT NULL,
url varchar(100) NOT NULL,
pid int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT=‘权限表’;
注意:如果存在子权限,一定要把最大的权限放在最后,否则在下面权限判定时,会出问题。
5. 权限角色对应表
CREATE TABLE `platform_permission_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_id` int(11) NOT NULL,
`permission_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `role_id` (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT='角色权限管理表';
二 实体类
User.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = “username”,nullable = false,length = 50)
private String userName;
@Column(name = “password”,nullable = false,length = 100)
private String password;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = “platform_role_user”, joinColumns = @JoinColumn(name = “user_id”, referencedColumnName = “id”), inverseJoinColumns = @JoinColumn(name = “role_id”, referencedColumnName = “id”))
private List roles;
省略 get set
Role.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
RoleUser.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "user_id")
private Long userId;
@Column(name = "role_id")
private Integer roleId;
Permission.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 权限名
*/
@Column(name = "name",nullable = false)
private String name;
/**
* 权限描述
*/
@Column(name = "description", nullable = false)
private String description;
/**
* 权限的url
*/
@Column(name = "url", nullable = false)
private String url;
/**
* 父节点id
*/
@Column(name = "pid")
private Integer pid;
PermissionRole.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "role_id")
private Integer roleId;
@Column(name = "permission_id")
private Integer permissionId;
三 security 配置类
/**
@author: 易明星
@Modified By:
@Date: Create in 13:27 2019/6/24
@Description: 权限配置
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
@Autowired
private CustomUserDetailService userDetailService;
/**
/**
/**
四 service
CustomUserDetailService.java
@Service
public class CustomUserDetailService implements UserDetailsService {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);
@Autowired
private UserRepository userRepository;
@Autowired
private PermissionDao permissionDao;
/**
* 根据用户名来取得用户信息,判断用户存不存在,同时取得该用户的权限
* 这里不判断密码是否正确
* @param name
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user = userRepository.findByUserName(name);
/**
* 权限
*/
if (null!=user){
List permissions = permissionDao.findByAdminUserId(user.getId());
List grantedAuthorities = new ArrayList <>();
for (Permission permission : permissions) {
if (permission != null && permission.getName()!=null) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
//1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。
grantedAuthorities.add(grantedAuthority);
}
}
logger.log(Level.INFO,"name="+user.getUserName()+"\t "+"权限="+grantedAuthorities);
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);
}else {
throw new UsernameNotFoundException("admin: " + name + " do not exist!");
}
/**
* 不管权限
*/
/*if (user==null){
logger.error("Not Found name "+ name);
throw new UsernameNotFoundException("Not Found name "+ name);
}
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);*/
}
private static List getAuthorities (List roles) {
List authorities = new ArrayList<>();
for (Role role:roles){
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
}
MyAccessDecisionManager.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:17 2019/6/25
@Description:
*/
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {
/**
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class> clazz) {
return true;
}
}
MyInvocationSecurityMetadataSourceService.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:22 2019/6/25
@Description:
*/
@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);
@Autowired
private PermissionDao permissionDao;
private Map
/**
}
/**
@Override
public Collection getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class> clazz) {
return true;
}
五 自定义security 过滤器 拦截 url请求
MyFilterSecurityInterceptor.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:20 2019/6/25
@Description: 自定义security的过滤器
*/
@Service
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
@Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
@Override
public void destroy() {
}
@Override
public Class> getSecureObjectClass() {
return FilterInvocation.class;
一 建表
权限管理需实现5张表:用户表、角色表、用户角色对应表、权限表、权限角色对应表
用户表
CREATE TABLE platform_user (
id bigint(20) NOT NULL AUTO_INCREMENT,
username varchar(50) NOT NULL,
password varchar(100) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
角色表
CREATE TABLE platform_role (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT=‘这只是角色表’;
用户角色对应表
CREATE TABLE platform_role_user (
id int(11) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
role_id int(11) NOT NULL,
PRIMARY KEY (id),
KEY FKt6466kf26ep5v3rfcya2sxi53 (role_id),
KEY FKfwy3bmkplk822fdp5o1btjyyv (user_id),
CONSTRAINT FKfwy3bmkplk822fdp5o1btjyyv FOREIGN KEY (user_id) REFERENCES platform_user (id),
CONSTRAINT FKt6466kf26ep5v3rfcya2sxi53 FOREIGN KEY (role_id) REFERENCES platform_role (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
权限表
CREATE TABLE platform_sys_permission (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
description varchar(50) NOT NULL,
url varchar(100) NOT NULL,
pid int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT=‘权限表’;
注意:如果存在子权限,一定要把最大的权限放在最后,否则在下面权限判定时,会出问题。
5. 权限角色对应表
CREATE TABLE platform_permission_role (
id int(11) NOT NULL AUTO_INCREMENT,
role_id int(11) NOT NULL,
permission_id int(11) NOT NULL,
PRIMARY KEY (id),
KEY role_id (role_id)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT=‘角色权限管理表’;
二 实体类
User.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = “username”,nullable = false,length = 50)
private String userName;
@Column(name = “password”,nullable = false,length = 100)
private String password;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = “platform_role_user”, joinColumns = @JoinColumn(name = “user_id”, referencedColumnName = “id”), inverseJoinColumns = @JoinColumn(name = “role_id”, referencedColumnName = “id”))
private List roles;
省略 get set
Role.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
RoleUser.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "user_id")
private Long userId;
@Column(name = "role_id")
private Integer roleId;
Permission.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 权限名
*/
@Column(name = "name",nullable = false)
private String name;
/**
* 权限描述
*/
@Column(name = "description", nullable = false)
private String description;
/**
* 权限的url
*/
@Column(name = "url", nullable = false)
private String url;
/**
* 父节点id
*/
@Column(name = "pid")
private Integer pid;
PermissionRole.java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "role_id")
private Integer roleId;
@Column(name = "permission_id")
private Integer permissionId;
三 security 配置类
/**
@author: 易明星
@Modified By:
@Date: Create in 13:27 2019/6/24
@Description: 权限配置
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
@Autowired
private CustomUserDetailService userDetailService;
/**
/**
/**
四 service
CustomUserDetailService.java
@Service
public class CustomUserDetailService implements UserDetailsService {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);
@Autowired
private UserRepository userRepository;
@Autowired
private PermissionDao permissionDao;
/**
* 根据用户名来取得用户信息,判断用户存不存在,同时取得该用户的权限
* 这里不判断密码是否正确
* @param name
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user = userRepository.findByUserName(name);
/**
* 权限
*/
if (null!=user){
List permissions = permissionDao.findByAdminUserId(user.getId());
List grantedAuthorities = new ArrayList <>();
for (Permission permission : permissions) {
if (permission != null && permission.getName()!=null) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
//1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。
grantedAuthorities.add(grantedAuthority);
}
}
logger.log(Level.INFO,"name="+user.getUserName()+"\t "+"权限="+grantedAuthorities);
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);
}else {
throw new UsernameNotFoundException("admin: " + name + " do not exist!");
}
/**
* 不管权限
*/
/*if (user==null){
logger.error("Not Found name "+ name);
throw new UsernameNotFoundException("Not Found name "+ name);
}
return new org.springframework.security.core.userdetails.User(
user.getUserName(),
user.getPassword(),
grantedAuthorities);*/
}
private static List getAuthorities (List roles) {
List authorities = new ArrayList<>();
for (Role role:roles){
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
}
MyAccessDecisionManager.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:17 2019/6/25
@Description:
*/
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {
/**
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class> clazz) {
return true;
}
}
MyInvocationSecurityMetadataSourceService.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:22 2019/6/25
@Description:
*/
@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
private final static Logger logger = LogManager.getLogger(CustomUserDetailService.class);
@Autowired
private PermissionDao permissionDao;
private Map
/**
}
/**
@Override
public Collection getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class> clazz) {
return true;
}
五 自定义security 过滤器 拦截 url请求
MyFilterSecurityInterceptor.java
/**
@author: 易明星
@Modified By:
@Date: Create in 11:20 2019/6/25
@Description: 自定义security的过滤器
*/
@Service
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
@Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
@Override
public void destroy() {
}
@Override
public Class> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
}
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
}