VoK 系统功能权责划分 ( II ) - day14

限制可执行权限

VoK-Security 提供三个限定权限的 annotation

  • @AllowRoles - 须带参数roles, 若未带参数,则无任何使用者拥有进入此画面权限
  • @AllowAll - 所有使用者皆有权限,无论有无登入
  • @AssowAllUsers - 所有已登入使用者皆有权限

根据昨天所设定的角色分配,分配新增/修改/删除学生权限。

  1. 请打开 EditStudent.kt,在 class 前加上 annotation
@Route("edit-student", layout = MainLayout::class)
@AllowRoles("administrator")
class EditStudent : KComposite(), HasUrlParameter<Long> {
  1. 删除学生写在 AllStudentsView.kt 里,但此画面任一登入使用者皆有观看权限,需要使用其他方法限制权限。
    if (Session.loginService.isUserInRole("administrator")) {
        addButtonColumn(VaadinIcon.TRASH, "delete") {
            confirmDialog(text = "是否确定删除${it.name}的资料?") {
                it.delete()
                this.refresh()
            }
        }
    }

第一行,判断登入使用者是否具有 administrator 权限

设定

加好角色限制annotation後,需要设定在UI跳转到画面前进行检查。

设定已登入使用者资讯

Bootstrap.kt contextInitialized()方法加上

    VaadinOnKotlin.loggedInUserResolver = object : LoggedInUserResolver{
        override fun isLoggedIn(): Boolean = Session.loginService.isLoggedIn
        override fun getCurrentUserRoles(): Set<String> = Session.loginService.getCurrentUserRoles()
    }

启动检查机制

请开启MainLayout.kt,在beforeEnter()方法加上检查

    override fun beforeEnter(event: BeforeEnterEvent) {
        if (event.navigationTarget != LoginView::class.java && !Session.loginService.isLoggedIn){
            event.rerouteTo(LoginView::class.java)
        }else{
            VokSecurity.checkPermissionsOfView(event.navigationTarget)
        }
    }

MainLayout启动检查的方式仅适用layout为 MainLayout之画面 @Route(path, layout = MainLayout::class)。倘若希望整个系统执行时,无论有无指定 layout 皆须事先判断则采用注册 Listener方法。

注册Listener

  1. 实作Listner。请开新档 SysInitListener.kt
package com.example.vok

import com.vaadin.flow.server.ServiceInitEvent
import com.vaadin.flow.server.VaadinServiceInitListener
import eu.vaadinonkotlin.vaadin10.Session
import eu.vaadinonkotlin.vaadin10.VokSecurity

class SysInitListener: VaadinServiceInitListener {
    override fun serviceInit(event: ServiceInitEvent) {
        event.source.addUIInitListener { uiInitEvent ->
            uiInitEvent.ui.addBeforeEnterListener { beforeEnterEvent ->
                if (!Session.loginService.isLoggedIn && beforeEnterEvent.navigationTarget != LoginView::class.java){
                    beforeEnterEvent.rerouteTo(LoginView::class.java)
                }else{
                    VokSecurity.checkPermissionsOfView(beforeEnterEvent.navigationTarget)
                }
            }
        }
    }
}
  1. 注册Listener。Vaadin 是基於 Java Servlet 的框架,RequestHandlers、BootstrapListeners、DependencyFilters 都配置在 VaadinServiceInitListener。在 web/src/main/resource/META-INF/services/ 开启新档 com.vaadin.flow.server.VaadinServiceInitListener,写入含 package的class name即可。
com.example.vok.SysInitListener

最後记得在每个画面赋予适合权限,否则会出 AccessRejectedException


<<:  第 14 天 我不是要压榨你我是给你个成长的机会|Reactive Form

>>:  那些被忽略但很好用的 Web API / CustomEvent

#16 No-code 之旅 — Project Setup

嗨嗨~ 今天比较晚下班,还没写文章也还没写专案XD 今天先建立专案好了~ 周末再赶进度! Setup...

Day 14 实作 database migration

前言 昨天讲完了 manage.py 跟我们新加入的几个自订指令,今天我们还是离不开 manage....

Day27 海鲜义大利炖饭Risotto

在地狱厨房中,常常看到有人因为Risotto翻车导致戈登大吼骂人的画面,决定来挑战看看传统义大利炖...

DAY23-JAVA的例外

例外 在钻写程序的时候,经常无法考虑的面面俱到,因此各种不寻常的状况也跟着发生,下面是几种常见的例子...

ISO 27001 机房管理部份之三

ISO 27001 机房管理部份之三 稽核分三种 : 内部稽核 (例如 : 稽核组长、稽核小组) 外...