类似百科式的网站建设南通市建设工程网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:30
当前位置: 首页 > news >正文
类似百科式的网站建设,南通市建设工程网站,食品网站app建设方案,商业计划书范文RBAC 权限#xff1a; 一、关系#xff1a; 这基于角色的访问控制的结构就叫RBAC结构。 二、RBAC 重要对象#xff1a; 用户#xff08;Employee#xff09;#xff1a;角色施加的主体#xff1b;用户通过拥有某个或多个角色以得到对应的权限。角色#xff08;Role 一、关系 这基于角色的访问控制的结构就叫RBAC结构。 二、RBAC 重要对象 用户Employee角色施加的主体用户通过拥有某个或多个角色以得到对应的权限。角色Role表示一组权限的集合。权限Permission一个资源代表一个权限是否能访问该资源就是看是否有该权限。 三、权限认证方式 –其实就是控制用户访问我们的controller层中的方法。— 可以自定义一个注解在需要权限的方法上面贴一个注解在不需要权限的方法上就不贴注解。例子 RequiredPermission (name权限名称,expression权限表达式) //–expression是我们判断的依据。 public User list(){//查询所有学生} 步骤 1.自定义注解; Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface RequiredPermission {String name();//—-权限名称String expression();//—-权限表达式 }2.将自定义注解贴在需要校验权限请求方法上面 RequstMapping(/list) RequiredPermission (name员工新增或修改,expressiondepartment:list) public void saveOrUpdate(Role role) {if (role.getId() ! null) { // 修改roleService.update(role);} else { // 新增roleService.save(role);}}注意 在权限系统开发中,一般权限系统有一个权限加载的功能。如果没有权限加载的功能的话要把系统中所有的权限信息保存到数据库中。假如有 10个Controller接口每个接口中有5个方法贴了自定义注解 RequiredPermission 这样的话得我们自己手动新增50次而如果通过权限加载这个功能的话就只需要点击这个功能按钮。这个按钮就可以把我们系统中所有贴了该注解的权限信息保存到数据库中。权限加载的功能实现 实现权限加载步骤:0. 先把数据库中所有的权限表达式查询出来
- 先拿到所有Controller – 通过Spring容器去拿
- 通过contoller去拿到每一个controller方法
- 通过方法去拿方法上的注解RequirdPermission
- 判断如果注解不为空并且注解中权限表达式不在数据库中,拿到注解中name,expression,封装到Permission对象中
- 把permission对象保存到数据库权限信息表中方式一
Service
Slf4j
public class PermissionServiceImpl implements IPermissionService {Autowiredprivate PermissionMapper permissionMapper;Autowiredprivate ApplicationContext context; //获取Spring Ioc 容器overridepublic void reload() {//0 先把数据库中所有的权限表达式查询出来ListString expression permissionMapper.selectExpression();// 1 从spring容器中去拿到所有的controLLerMapString, Obiect beansithAnnotation context.getBeanswithAnnotation(Controller.class);// map key 把controller类名小写字符串 value才是我们想要的controllerCollectionObject controllers beanswithAnnotation.values();// 2 根据controller 拿到每一个方法for (Object controller : controllers) {//拿到controller对象通过反射去获取字节码对象在获取自身所有的方法Method[] methods controller.getClass().getDeclaredMethods();for (Method method : methods){// 3 根据方法拿到方法上注解 RequiredPermissionRequiredPermission annotation method.getAnnotation(RequiredPermission.class);//判断注解是否为空,将在数据库中查询的权限表达式第0步与注解上表达式比对获取list中不包含的权限表达式if(annotation!null !expression.contatins(annotation.expression())){// 4 判断注解是否为空 ,如果不为空数据封装到Permission对象中Permission p new Permission();String name annotation.name():String expression annotation.expression();p.setExpression(expression);p.setName(name);// 5.把数据保存到数据库中permissionMapper.insert(p);}}}
}方式二 Service Slf4j public class PermissionServiceImpl implements IPermissionService {Autowiredprivate PermissionMapper permissionMapper;Autowired//SpringMVC处理器映射器 通过处理器映射器获取Controller注解类中的方法信息封装到HandlerMethod中private RequestMappingHandlerMapping requestMappingHandlerMapping;//SpringMVC处理器映射器 overridepublic void reload() {//0 先把数据库中所有的权限表达式查询出来ListString expression permissionMapper.selectExpression();// 在启动的时候requestMappingHandlerMapping 会把controller中所有的方法封装HandlerMethod 中MapRequestMappingInfo, HandlerMethod map requestMappingHandlerMapping.getHandlerMethods();CollectionHandlerMethod handlerMethods map.values();for (HandlerMethod handlerMethod : handlerMethods) {// 到方法Method method handlerMethod.getMethod();// 方法上的注解//3 根据方法拿到方法上注RequiredPermissionRequiredPermission annotation method.getAnnotation(RequiredPermission.class);if(annotation!null 8 !expressions.contains(annotation.expression())){// 4 断注解是否为空 如果不为空把权限表达式数据封装到Permission对象中Permission p new Permission();String name annotation.name();String expression annotation.expression();p.setName(name);p.setExpression(expression);// 5 把数据保存到数据库中permissionMapper.insert(p);} } }权限新增删除 角色(Role) 角色中间表(role_permission) 权限(permission) 即其通过对角色新增或删除权限通过中间表来关联,并在中间表上新增和删除。在中间表上对外键 role_id与permission_id 之间的关系来增加或删除。用户(Employee) 用户中间表(Employee_role) 角色(role)删除的时候不仅删除用户或角色表中的信息还要删除中间表中的信息。 四、登录校验 Data public class JsonResult {private boolean success;private String msg;public JsonResult(boolean success, String msg) {this.success success;this.msg msg;} }1.controller层 Controller public class LoginController {Autowiredprivate IEmployeeService employeeService;Autowiredprivate IPermissionService permissionService;RequestMapping(/login)ResponseBody// {success:true,msg:登录成功}// {success:false,msg:登录失败}public JsonResult login(String username, String password) {try{Employee employee employeeService.login(username, password); return new JsonResult(true, 操作成功);}catch{e.printStackTrace();return new JsonResult(false, e.getMessage);}}2.service层 Service public class EmployeeServiceImpl implements IEmployeeService {Overridepublic Employee login(String username, String password) {//校验参数非空判断if(StringUtils.isEmpty(username) || StringUtil.isEmpty(password)){throw new RuntimeException(账号或者密码不能为空);}//根据账号和密码上数据库中进行查询Employee employee employeeMapper.selectByUsernameAndPassword(username, password);//如果为空抛出异常if(employee null){throw new RuntimeException(账号或者密码错误);}return employee;} }3.前端 \((.submitBtn).click(function () (// 发送ajax请求 \).post(/login,$(#loginForm).serialize(),function (data) {// data - JsonResultif(data.success)(Location.href/department/list;}else(Swal.fire({text: data.msg})}}) })4.*注意这样的话还是不行用户可以直接输入网址进入页面所以要对url进行拦截进行登录校验 步骤 第一步: 用户开始时登录的时候如果用户登录成功则把用户信息放到ssesion中。 第二步: 定义一个拦截器对每一次用户请求的资源进行拦截。 第三步: 对拦截器进行配置。 1要拦截哪些资源 2排除哪些资源路径第一步用户信息放到ssesion中 Controller public class LoginController {Autowiredprivate IEmployeeService employeeService;Autowiredprivate IPermissionService permissionService;RequestMapping(/login)ResponseBody// {success:true,msg:登录成功}// {success:false,msg:登录失败}public JsonResult login(HtttpSession session, String username, String password) {try{Employee employee employeeService.login(username, password); //验证用户身份成功之后将用户的信息保存到session中session.setAttribute(USER_IN_SESSION, employee);return new JsonResult(true, 操作成功);}catch{e.printStackTrace();return new JsonResult(false, e.getMessage);}}第二步: 定义一个拦截器 public class CheckLoginInterceptor implements HandlerInterceptor{public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 0bject handler) throws{// 查询session 中保存用户信息Employee employee (Employee) request.getSession().getAttribute( USER_IN_SESSION);// 判断如果存在就放行,如果不存在跳转到登灵界面中if(employee!nul1){return true;}response.sendRedirect( s:/static/login.html); //重定向到登录界面return false;}第三步: 对拦截器进行配置 Configuration public class WebConfig implements WebMvcConfigurer (Beanpublic CheckLoginInterceptor checkLoginInterceptor(){return new CheckLoginInterceptor();}Overridepublic void addInterceptors(InterceptorRegistry registry){ registry.addInterceptor(checkLoginInterceptor()). addPathPatterns(/).//将拦截器注入到容器中excludePathPatterns(/static/**,/login,/logout);//放行那些资源} 五、退出登录 就是把session中登录的信息删除掉 RequestMapping(/logout) public String logout(HttpSession session){session.removeAttribute(USER_IN_SESSION);return redirect:/static/login.html;//重定向 }六、权限拦截 分析 步骤 1 上session去获取当前登录用户信息 2 判断用户是否是超级管理员-如果是直接放行 3 拿到当前访问方法 4 获取方法上的注解RequiredPermission 5 判断注解是否为空 -直接放行 6 要把当前登录的用户所拥有的权限表达式给查询出来 7 如果注解中权限表示式是在从数据库中查询出来权限表达式集合中说明用户拥有这个权限的 -放行 8 没有这个权限跳转到没有权限界面中,进行拦截1.定义一个拦截器 *拓展 拦截器中 preHandle 方法的参数列表中有一个参数叫:Object handler 的参数: 通过反射 handler.getClass打印输出为:class org.springframework.web.method.HanderMethod(真实类型) 在 SpringMvc 中: 有一个处理器映射器。处理器映射器会把我们所有贴有Controller注解的类中的方法的信息,封装到HanderMethod中。所以在拦截器中我们可以通过 HanderMethod 这个去获得贴有Controller注解的类中的方法的信息/ *权限校验拦截器 / public class CheckPermissionIntercetor implements HandlerInterceptor{Autowird private IPermissionService permissionService;public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){// 1.从session中去拿当前用户登录信息Employee employee (Employee) request.getSession().getAtribute(USER_IN_SESSION);// 2.判断是否是超级超级管理员if(employee.isAdmin()){return true;}// 3.获取到当前访问方法 不明白看拓展;HandlerMethod handlerMethod (Handlerethod)handlerMethod method handlerMethod.getMethod();// 4.通过方法拿方法上的注解RequiredPermission annotation method.getAnnotation(RequiredPermission.class);// 5.判断注解如果为空表示访问方法时不需要权限if(annotation null){return true;} // 6.把用户所拥有的所有权限表达式集合给查询出来ListString list permissionService.getExpressionByEmpId(employee.getId());// 7.判断注解中的权限表达式是否在集合中if(list.contatins(annotation.expression())){return true;}// 8. 如果不包含则表示没有权限 跳转到没有权限的页面中response.sendRedirect(/permission/nopermission);//url从定向}2.编写url从定向接口 RequestMapping(/nopermission) public String nopermission(){return 自己定义的页面路径; }3.将拦截器注入到容器中 Configuration public class WebConfig implements WebMvcConfigurer (//登录拦截器Beanpublic CheckLoginInterceptor checkLoginInterceptor(){return new CheckLoginInterceptor();}//权限拦截器Beanpublic CheckPermissionIntercetor checkPermissionIntercetor(){return new CheckPermissionIntercetor();}//登录拦截器注入Overridepublic void addInterceptors(InterceptorRegistry registry){ registry.addInterceptor(checkLoginInterceptor()). addPathPatterns(/).//将拦截器注入到容器中excludePathPatterns(/static/,/login,/logout);//放行那些资源} //登录拦截器注入Overridepublic void addInterceptors(InterceptorRegistry registry){ registry.addInterceptor(CheckPermissionIntercetor()). addPathPatterns(/).//将拦截器注入到容器中excludePathPatterns(/static/,/login,/logout);//放行那些资源} } 七、统一异常处理 如何解决 手动 try 弊端是到处是重复代码系统的代码耦合度高工作量大且不好统一维护的工作量也很大。 利用 Spring MVC 的方式 Spring MVC 为 Controller 处理方法执行出现异常提供了全局统一处理可以使用 ExceptionHandler 配合 ControllerAdvice 注解实现异常处理可减少代码量提高拓展性和可维护性。添加处理控制器异常处理类确保 Spring 配置中要能扫描到这个类。针对不同异常进行不同处理针对不同处理方法响应的内容需要进行不同处理比如原来方法响应 HTML 依然响应 HTML若原来方法响应 JSON 依然响应 JSON。
/
- 对控制器进行增强处理 / ControllerAdvice public class RuntimeExceptionHandler {/** 该方法是用于捕获并处理某种异常* e现在出现的异常对象* method现在出现异常的那个处理方法*/ExceptionHandler(RuntimeException.class)public String exceptionHandler(RuntimeException e, HandlerMethod method, HttpServletResponse response) {e.printStackTrace(); // 方便开发的时候找 bug// 若原本控制器的方法是返回 JSON现在出异常也应该返回 JSON// 获取当前出现异常的方法判断是否有 ResponseBody 注解有就代表需要返回 JSONif(method.hasMethodAnnotation(ResponseBody.class)){try {response.setContentType(application/json;charsetUTF-8);response.getWriter().print(JSON.toJSONString(new JsonResult(false, 系统异常请联系管理员)));} catch (IOException e1) {e1.printStackTrace();}return null;}// 若原本控制器的方法是返回 HTML现在也应该返回 HTMLreturn common/error;} }2、自定义异常 在开发中还可以根据自己业务的异常情况来自定义业务逻辑异常类一般继承于 java.lang.RuntimeException。 public class LogicException extends RuntimeException {public LogicException(String errorMsg){super(errorMsg);} }比如虽然登录出错也响应 JSON 数据但其需要提示的消息更详细所以通过自定义异常再利用 Spring MVC 全局处理异常方式针对这个异常进行专门处理。可参考另一篇博客SpringBoot统一异常处理
- 上一篇: 雷州手机网站建设wordpress建地方门户
- 下一篇: 类似凡科网的网站高中网站制作
相关文章
-
雷州手机网站建设wordpress建地方门户
雷州手机网站建设wordpress建地方门户
- 技术栈
- 2026年03月21日
-
雷神代刷网站推广小生互联免费主机
雷神代刷网站推广小生互联免费主机
- 技术栈
- 2026年03月21日
-
乐亭网站建设wordpress顶部空白
乐亭网站建设wordpress顶部空白
- 技术栈
- 2026年03月21日
-
类似凡科网的网站高中网站制作
类似凡科网的网站高中网站制作
- 技术栈
- 2026年03月21日
-
类似建设通的网站哪个网站做分享赚佣金
类似建设通的网站哪个网站做分享赚佣金
- 技术栈
- 2026年03月21日
-
类似于QQ空间的wordpress主题百度关键词优化首选667seo
类似于QQ空间的wordpress主题百度关键词优化首选667seo
- 技术栈
- 2026年03月21日
