spring安全控制权限的解释(springbootsecurity权限)

管理员 2024-11-23 19:02:07 0

权限控制(springboot整合security实现权限控制)

CREATE TABLE `t_sys_user` (`user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',`user_name` varchar(30) NOT NULL COMMENT '用户名',`user_password` varchar(128) NOT NULL COMMENT '用户密码',`salt` varchar(64) DEFAULT NULL COMMENT '加密盐',`user_phone` varchar(20) DEFAULT NULL COMMENT '手机号',`user_emai` varchar(20) DEFAULT NULL COMMENT '邮箱',`user_title` varchar(20) DEFAULT NULL COMMENT '职称',`creater_id` bigint(20) DEFAULT NULL COMMENT '创建人ID',`creater_name` varchar(30) DEFAULT NULL COMMENT '创建人名称',`creater_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`updater_id` bigint(20) DEFAULT NULL COMMENT '更新人ID',`updater_name` varchar(30) DEFAULT NULL COMMENT '更新人名称',`updater_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',`role_ids` varchar(200) DEFAULT NULL,`role_names` varchar(300) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
CREATE TABLE `t_sys_user_role` (`user_role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户角色ID',`user_id` bigint(20) NOT NULL COMMENT '用户ID',`role_id` bigint(20) NOT NULL COMMENT '角色ID',
PRIMARY KEY (`user_role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
CREATE TABLE `t_sys_role` (`role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色ID',`role_name` varchar(100) NOT NULL COMMENT '角色名称',`role_code` varchar(100) NOT NULL COMMENT '角色编码',`creater_id` bigint(20) DEFAULT NULL COMMENT '创建人ID',`creater_name` varchar(30) DEFAULT NULL COMMENT '创建人名称',`creater_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`updater_id` bigint(20) DEFAULT NULL COMMENT '更新人ID',`updater_name` varchar(30) DEFAULT NULL COMMENT '更新人名称',`updater_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',`permission_ids` varchar(200) DEFAULT NULL,`permission_names` varchar(300) DEFAULT NULL,
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
CREATE TABLE `t_sys_role_permission` (`role_permission_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色权限ID',`role_id` bigint(20) NOT NULL COMMENT '角色ID',`permission_id` bigint(20) NOT NULL COMMENT '权限ID',
PRIMARY KEY (`role_permission_id`)
) ENGINE=InnoDB AUTO_INCREMENT=78 DEFAULT CHARSET=utf8;

1.5.权限表

CREATE TABLE `t_sys_permission` (`permission_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '权限ID',`permission_name` varchar(100) NOT NULL COMMENT '权限名称',`permission_code` varchar(100) NOT NULL COMMENT '权限编码',`creater_id` bigint(20) DEFAULT NULL COMMENT '创建人ID',`creater_name` varchar(30) DEFAULT NULL COMMENT '创建人名称',`creater_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`updater_id` bigint(20) DEFAULT NULL COMMENT '更新人ID',`updater_name` varchar(30) DEFAULT NULL COMMENT '更新人名称',`updater_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`permission_id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
org.springframework.bootspring-boot-starter-security
package com.lz.hehuorenservice.system.entity;import com.lz.hehuorenservice.common.entity.BaseEntity;import io.swagger.annotations.ApiModelProperty;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import java.util.*;/** Create by hyhweb on 2021/6/6 16:24 */public class User extends BaseEntity implements UserDetails {/** 用户主键ID */@ApiModelProperty(value = "用户主键ID")private Long userId;/** 用户名 */@ApiModelProperty(value = "用户名")private String userName;/** 用户密码 */@ApiModelProperty(value = "用户密码")private String userPassword;@ApiModelProperty(value = "")private String salt;/** 手机号 */@ApiModelProperty(value = "手机号")private String userPhone;/** 邮箱 */@ApiModelProperty(value = "邮箱")private String userEmai;/** 职称 */@ApiModelProperty(value = "职称")private String userTitle;@ApiModelProperty(value = "角色ID")private String roleIds;@ApiModelProperty(value = "角色名称")private String roleNames;/** 创建人ID */@ApiModelProperty(value = "创建人ID")private Long createrId;/** 创建人名称 */@ApiModelProperty(value = "创建人名称")private String createrName;/** 创建时间 */@ApiModelProperty(value = "创建时间")private Date createrTime;/** 更新人ID */@ApiModelProperty(value = "更新人ID")private Long updaterId;/** 更新人名称 */@ApiModelProperty(value = "更新人名称")private String updaterName;/** 更新时间 */@ApiModelProperty(value = "更新时间")private Date updaterTime;private Set permissions;@Overridepublic Collection getAuthorities() {
List authorities = new ArrayList<>();/*
//绑定角色的授权方法
if(roles !=null){
for (Role sysRole : roles) {
authorities.add(new SimpleGrantedAuthority(sysRole.getRoleCode()));
}
}*/// 绑定权限的授权方法if (permissions != null) {for (String permission : permissions) {
authorities.add(new SimpleGrantedAuthority(permission));
}
}return authorities;
}@Overridepublic String getPassword() {return userPassword;
}@Overridepublic String getUsername() {return userName;
}@Overridepublic boolean isAccountNonExpired() {return true;
}@Overridepublic boolean isAccountNonLocked() {return true;
}@Overridepublic boolean isCredentialsNonExpired() {return true;
}@Overridepublic boolean isEnabled() {return true;
}public Long getUserId() {return userId;
}public void setUserId(Long userId) {this.userId = userId;
}public String getUserName() {return userName;
}public void setUserName(String userName) {this.userName = userName;
}public String getUserPassword() {return userPassword;
}public void setUserPassword(String userPassword) {this.userPassword = userPassword;
}public String getSalt() {return salt;
}public void setSalt(String salt) {this.salt = salt;
}public String getUserPhone() {return userPhone;
}public void setUserPhone(String userPhone) {this.userPhone = userPhone;
}public String getUserEmai() {return userEmai;
}public void setUserEmai(String userEmai) {this.userEmai = userEmai;
}public String getUserTitle() {return userTitle;
}public void setUserTitle(String userTitle) {this.userTitle = userTitle;
}public String getRoleIds() {return roleIds;
}public void setRoleIds(String roleIds) {this.roleIds = roleIds;
}public String getRoleNames() {return roleNames;
}public void setRoleNames(String roleNames) {this.roleNames = roleNames;
}public Long getCreaterId() {return createrId;
}public void setCreaterId(Long createrId) {this.createrId = createrId;
}public String getCreaterName() {return createrName;
}public void setCreaterName(String createrName) {this.createrName = createrName;
}public Date getCreaterTime() {return createrTime;
}public void setCreaterTime(Date createrTime) {this.createrTime = createrTime;
}public Long getUpdaterId() {return updaterId;
}public void setUpdaterId(Long updaterId) {this.updaterId = updaterId;
}public String getUpdaterName() {return updaterName;
}public void setUpdaterName(String updaterName) {this.updaterName = updaterName;
}public Date getUpdaterTime() {return updaterTime;
}public void setUpdaterTime(Date updaterTime) {this.updaterTime = updaterTime;
}public Set getPermissions() {return permissions;
}public void setPermissions(Set permissions) {this.permissions = permissions;
}
}
package com.lz.hehuorenservice.system.service.impl;import com.lz.hehuorenservice.common.service.impl.BaseServiceImpl;import com.lz.hehuorenservice.system.dao.UserDao;import com.lz.hehuorenservice.system.entity.User;import com.lz.hehuorenservice.system.service.UserService;import org.springframework.beans.factory.annotation.Autowired;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 java.util.Set;/** Create by hyhweb on 2021/6/6 16:28 */@Servicepublic class UserServiceImpl extends BaseServiceImplimplements UserService, UserDetailsService {@Autowired UserDao userDao;@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userDao.getUserByName(userName);if (user == null) {throw new UsernameNotFoundException("账户不存在");
}
Set permissions = userDao.getPermissionByUserId(user.getUserId());
user.setPermissions(permissions);return user;
}
}
package com.lz.hehuorenservice.common.config;import com.fasterxml.jackson.databind.ObjectMapper;import com.lz.hehuorenservice.common.bean.CustomAccessDeniedHandler;import com.lz.hehuorenservice.common.bean.CustomAuthenticationEntryPoint;import com.lz.hehuorenservice.common.filter.CustomAuthenticationFilter;import com.lz.hehuorenservice.system.entity.User;import com.lz.hehuorenservice.system.service.impl.UserServiceImpl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.*;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.builders.WebSecurity;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.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.access.AccessDeniedHandler;import org.springframework.security.web.authentication.AuthenticationFailureHandler;import org.springframework.security.web.authentication.AuthenticationSuccessHandler;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.security.web.authentication.logout.LogoutHandler;import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;import org.springframework.web.cors.CorsUtils;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;/** Create by hyhweb on 2021/6/7 8:26 */@Configuration@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired UserServiceImpl userService; // 这个必须是接口的实现类,不能是接口@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(10);// return NoOpPasswordEncoder.getInstance();}/* @Bean
RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
// String hierarchy = "ROLE_dba> ROLE_admin \n ROLE_admin > ROLE_user";
String hierarchy = "ROLE_admin > ROLE_user";
roleHierarchy.setHierarchy(hierarchy);
return roleHierarchy;
}*/@BeanCustomAuthenticationFilter customAuthenticationFilter() throws Exception {CustomAuthenticationFilter filter = new CustomAuthenticationFilter();filter.setAuthenticationSuccessHandler(
new AuthenticationSuccessHandler() {
@Overridepublic void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth)throws IOException, ServletException {Object principal = auth.getPrincipal();
resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();
resp.setStatus(200);Map map = new HashMap<>();map.put("code", "1");map.put("success", true);map.put("message", "登录成功");User user = (User) principal;
user.setUserPassword(null);map.put("data", user);ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();/* resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
Map map = new HashMap();
map.put("message", "登录成功");
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
out.close();*/}
});filter.setAuthenticationFailureHandler(
new AuthenticationFailureHandler() {
@Overridepublic void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e)throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();
resp.setStatus(401);Map map = new HashMap<>();map.put("status", 401);if (e instanceof LockedException) {map.put("msg", "账号被锁定,登录失败");
} else if (e instanceof BadCredentialsException) {map.put("msg", "账号或密码输入错误,请重新登录");
} else if (e instanceof DisabledException) {map.put("msg", "账号被禁用,登录失败");
} else if (e instanceof AccountExpiredException) {map.put("msg", "账号过期,登录失败");
} else if (e instanceof CredentialsExpiredException) {map.put("msg", "密码过期,登录失败");
} else {map.put("msg", "登录失败");
}ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();/*resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
Map map = new HashMap();
map.put("message", "登录失败");
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
out.close();*/}
});filter.setAuthenticationManager(authenticationManagerBean());return filter;
}
@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
}
@Beanpublic AccessDeniedHandler getAccessDeniedHandler() {return new CustomAccessDeniedHandler();
}
@Overridepublic void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/sessionInvalid", "/register", "/app/**", "/login_page")
.antMatchers("/index.html", "/static/**", "/favicon.ico")
.antMatchers("/swagger-ui/**","/swagger/**","/doc.html","/swagger-resources/**","/images/**","/webjars/**","/v3/api-docs","/configuration/ui","/configuration/security");
}
@Overrideprotected void configure(HttpSecurity http) throws Exception {
http.cors() // 开启跨域.and() // 获取一个安全编译器.authorizeRequests() // 授权请求.requestMatchers(CorsUtils::isPreFlightRequest)
.permitAll() // 跨域的请求开放所有权限.anyRequest() // 所有请求.authenticated() // 所有请求都需要认证.and()
.sessionManagement()
.invalidSessionUrl("/session/invalid")
.and()// 获取一个安全编译器.formLogin()// 表单登录配置.loginPage("/login_page")// 登录页面访问地址.loginProcessingUrl("/login")// 配置登录接口地址.usernameParameter("userName")// 配置登录的账号字段.passwordParameter("userPassWord")// 配置登录密码字段.and()// 获取一个安全编译器.logout()// 退出登录配置.logoutUrl("/logout")// 设置退出登录的接口地址.clearAuthentication(true)// 清除所有认证信息.invalidateHttpSession(true)// 让session失效.addLogoutHandler(
new LogoutHandler() {// 退出登录时的处理器@Overridepublic void logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,Authentication authentication) {}
})
.logoutSuccessHandler(
new LogoutSuccessHandler() {// 退出成功后的处理器@Overridepublic void onLogoutSuccess(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,Authentication authentication)throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");PrintWriter out = httpServletResponse.getWriter();Map map = new HashMap<>();map.put("message", "退出成功");map.put("code", "1");map.put("success", true);ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.permitAll() // 设置退出登录的所有权限.and() // 获取一个安全编译器.csrf()
.disable() // 关闭csrf跨站点请求伪造.exceptionHandling()
.authenticationEntryPoint(new CustomAuthenticationEntryPoint());// 自定义认证的入口异常处理方法http.addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
// 重写用户名密码的过滤器,实现前后端分离获取登录的用户名,密码信息http.exceptionHandling().accessDeniedHandler(getAccessDeniedHandler());
// 没有权限访问的处理器
}
}


package com.lz.hehuorenservice.common.bean;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.web.access.AccessDeniedHandler;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;/** Create by hyhweb on 2021/6/7 11:50 */public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Overridepublic void handle(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,AccessDeniedException e)throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");PrintWriter out = httpServletResponse.getWriter();Map map = new HashMap<>();map.put("message", "权限不足,请联系管理员开通权限");map.put("code", 0);map.put("status", 403);map.put("success", false);String result = new ObjectMapper().writeValueAsString(map);
out.write(result);
out.flush();
out.close();
}
}
package com.lz.hehuorenservice.common.bean;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.AuthenticationEntryPoint;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;/** Create by hyhweb on 2021/6/7 11:42 */public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Overridepublic void commence(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,AuthenticationException e)throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");PrintWriter out = httpServletResponse.getWriter();Map map = new HashMap<>();map.put("message", "还没登录,请重新登录");map.put("code", 302);String result = new ObjectMapper().writeValueAsString(map);
out.write(result);
out.flush();
out.close();
}
}
package com.lz.hehuorenservice.common.filter;import org.springframework.http.MediaType;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.InputStream;/** Create by hyhweb on 2021/6/7 12:07 */public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {@Overridepublic Authentication attemptAuthentication(
HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {if (request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE)
|| request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {
UsernamePasswordAuthenticationToken authRequest = null;try (InputStream is = request.getInputStream()) {
ObjectMapper mapper = new ObjectMapper();
Map authenticationBean = mapper.readValue(is, Map.class);
authRequest = new UsernamePasswordAuthenticationToken(
authenticationBean.get("userName"), authenticationBean.get("userPassWord"));/* authRequest =
new UsernamePasswordAuthenticationToken(
request.getParameter("userName"), request.getParameter("userPassWord"));*/} catch (IOException e) {
e.printStackTrace();
authRequest = new UsernamePasswordAuthenticationToken("", "");
} finally {
setDetails(request, authRequest);return this.getAuthenticationManager().authenticate(authRequest);
}
} else {return super.attemptAuthentication(request, response);
}
}
}
@RestController@RequestMapping("/user")@Api(tags = "用户信息")
public class UserController{@Autowired private UserService userService;@ApiOperation(value = "删除单个对象", notes = "删除单个对象接口")@GetMapping("/delete/{id}")@PreAuthorize("hasAuthority('delete')")
public ApiResult deleteById(@PathVariable long id) {return userService.deleteById(id);
}
}


org.springframework.security.access.expression.SecurityExpressionRoot
在controller的方法中使用注释,如下:
@PreAuthorize("表达式('权限值')")

@PreAuthorize("hasAuthority('zixunguanli-xinzeng')")
public ApiResult add(@RequestBody String json) {return infoService.add(JSON.parseObject(json, InfoReq.class));
}

表达式如下:

boolean hasAuthority(String var1);boolean hasAnyAuthority(String... var1);boolean hasRole(String var1);boolean hasAnyRole(String... var1);boolean permitAll();boolean denyAll();boolean isAnonymous();boolean isAuthenticated();boolean isRememberMe();boolean isFullyAuthenticated();boolean hasPermission(Object var1, Object var2);boolean hasPermission(Object var1, String var2, Object var3);

重构
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter的attemptAuthentication方法

相关文章