1. 程式人生 > 其它 >一套簡單的登入、鑑權工具

一套簡單的登入、鑑權工具

  前言

  無論是SpringSecruity、Shiro,對於一些小專案來說都太過複雜,有些情況下我們就想使用簡單的登入、鑑權功能,本文記錄手寫一套簡單的登入、鑑權工具

  思路

  1、封裝工具類,整合查詢系統使用者、系統角色,根據登入使用者許可權進行當前URL請求鑑權

  2、在攔截器中呼叫工具類進行鑑權,通過放行、不通過則丟擲對應業務異常資訊

  首先需要三張基礎表:系統使用者表、系統角色表、使用者角色關聯表

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '表id', `nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '暱稱', `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
DEFAULT NULL COMMENT '賬號', `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密碼', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系統使用者表' ROW_FORMAT = Compact; -- ----------------------------
-- Records of sys_user -- ---------------------------- INSERT INTO `sys_user` VALUES ('1', '系統管理員', 'admin', '000000'); INSERT INTO `sys_user` VALUES ('2', '張三-部門經理', 'zhangsan', '111111'); INSERT INTO `sys_user` VALUES ('3', '小芳-前臺接待', 'xiaofang', '222222'); -- ---------------------------- -- Table structure for sys_role -- ---------------------------- DROP TABLE IF EXISTS `sys_role`; CREATE TABLE `sys_role` ( `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '表id', `role_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色名稱', `role_menu` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '角色選單可視許可權(可以不關聯選單,單獨做成選單管理直接與使用者關聯)', `role_url` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '角色URL訪問許可權', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系統角色表' ROW_FORMAT = Compact; -- ---------------------------- -- Records of sys_role -- ---------------------------- INSERT INTO `sys_role` VALUES ('1', '管理員', '[{\"menuName\":\"系統管理\",\"menuPath\":\"/sys/xtgl\"},{\"menuName\":\"使用者管理\",\"menuPath\":\"/sys/yhgl\"},{\"menuName\":\"網站門戶管理\",\"menuPath\":\"/portal/mhgl\"}]', '/sys/*,/portal/mhgl,/getLoginUser'); INSERT INTO `sys_role` VALUES ('2', '部門領導', '[{\"menuName\":\"使用者管理\",\"menuPath\":\"/sys/yhgl\"},{\"menuName\":\"網站門戶管理\",\"menuPath\":\"/portal/mhgl\"}]', '/sys/yhgl,/portal/mhgl,/getLoginUser'); INSERT INTO `sys_role` VALUES ('3', '普通員工', '[{\"menuName\":\"網站門戶管理\",\"menuPath\":\"/portal/mhgl\"}]', '/portal/mhgl,/getLoginUser'); -- ---------------------------- -- Table structure for sys_user_role -- ---------------------------- DROP TABLE IF EXISTS `sys_user_role`; CREATE TABLE `sys_user_role` ( `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '表id', `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '使用者id', `role_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色id', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系統使用者-角色關聯表' ROW_FORMAT = Compact; -- ---------------------------- -- Records of sys_user_role -- ---------------------------- INSERT INTO `sys_user_role` VALUES ('1', '1', '1'); INSERT INTO `sys_user_role` VALUES ('2', '1', '2'); INSERT INTO `sys_user_role` VALUES ('3', '1', '3'); INSERT INTO `sys_user_role` VALUES ('4', '2', '2'); INSERT INTO `sys_user_role` VALUES ('5', '3', '3');

  在工具類中定義三個實體類方便傳參接參(如果嫌麻煩也可以直接使用Map物件),使用自定義DbUtil查詢資料庫表資料(此操作,應交由專案ORM框架負責)

  程式碼編寫

  DbUtil工具類

package cn.huanzi.qch.util;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * 原生jdbc操作資料庫工具類
 */
public class DbUtil {

    //資料庫連線:地址、使用者名稱、密碼
    private final String url;
    private final String username;
    private final String password;

    //Connection連線例項
    private Connection connection;

    public DbUtil(String url, String username, String password){
        this.url = url;
        this.username = username;
        this.password = password;
    }
    public DbUtil(String url, String username, String password, String driver){
        this(url,username,password);

        //載入驅動
        try {
            /*
                同時需要引入相關驅動依賴

                1、MySQL:
                com.mysql.cj.jdbc.Driver

                2、Oracle:
                oracle.jdbc.driver.OracleDriver

                3、pgsql:
                org.postgresql.Driver

             */
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 獲取 Connection 連線
     */
    private Connection getConnection() {
        if(connection == null){
            try {
                connection= DriverManager.getConnection(url, username, password);
                connection.setAutoCommit(true);
            } catch (SQLException e) {
                System.err.println("獲取Connection連線異常...");
                e.printStackTrace();
            }
        }
        return connection;
    }

    /**
     * 設定是否自動提交事務
     * 當需要進行批量帶事務的操作時,關閉自動提交手動管理事務,將會大大提高效率!
     */
    public void setAutoCommit(boolean autoCommit){
        try {
            this.getConnection().setAutoCommit(autoCommit);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 關閉自動提交事務時,需要手動管理事務提交、回滾
     */
    public void commit(){
        try {
            this.getConnection().commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void rollback(){
        try {
            this.getConnection().rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 關閉 Connection 連線
     */
    public void close(){
        if(connection != null){
            try {
                connection.close();
                connection = null;
            } catch (SQLException e) {
                System.err.println("關閉Connection連線異常...");
                e.printStackTrace();
            }
        }
    }

    /**
     * 查詢
     * 查詢語句
     */
    public ArrayList<HashMap<String,Object>> find(String sql, Object[] params) {
        ArrayList<HashMap<String, Object>> list = new ArrayList<>();

        //獲取連線
        Connection conn = this.getConnection();
        PreparedStatement ps;
        ResultSet rs;

        try {
            //設定SQL、以及引數
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }

            //執行查詢
            rs = ps.executeQuery();

            //獲取查詢結果
            ResultSetMetaData rm = rs.getMetaData();
            int columnCount = rm.getColumnCount();

            //封裝結果集
            while (rs.next()) {
                HashMap<String, Object> map = new HashMap<>(columnCount);
                for (int i = 1; i <= columnCount; i++) {
                    String name = rm.getColumnName(i).toLowerCase();
                    Object value = rs.getObject(i);

                    map.put(name,value);
                }
                list.add(map);
            }

        } catch (Exception e) {
            System.err.println("執行 jdbcUtil.find() 異常...");
            e.printStackTrace();
        }

        return list;
    }
    public HashMap<String,Object> findOne(String sql, Object[] params){
        ArrayList<HashMap<String, Object>> list = this.find(sql, params);
        return list.size() > 0 ? list.get(0) : null;
    }
    public ArrayList<HashMap<String,Object>> find(String sql) {
        return this.find(sql,null);
    }
    public HashMap<String,Object> findOne(String sql) {
        return this.findOne(sql,null);
    }

    /**
     * 執行
     * 新增/刪除/更新 等SQL語句
     */
    public boolean execute(String sql, Object[] params){
        boolean flag = false;

        //獲取連線
        Connection conn = this.getConnection();
        PreparedStatement ps;

        try {
            //設定SQL、以及引數
            ps = conn.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }

            //執行
            flag = ps.execute();
        } catch (SQLException e) {
            System.err.println("執行 jdbcUtil.update() 異常...");
            e.printStackTrace();
        }

        return flag;
    }
    public boolean execute(String sql){
        return this.execute(sql,null);
    }
}

  SecurityUtil工具類

package cn.huanzi.qch.util;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 一套簡單的登入、鑑權工具
 */
public class SecurityUtil {

    /**
     * 單例模式-餓漢
     */
    private static final SecurityUtil instance = new SecurityUtil();
    private SecurityUtil (){}
    public static SecurityUtil getInstance() {
        return instance;
    }

    /**
     * 無需登入即可訪問的URL
     * PS:建議從配置檔案讀取
     */
    private static final String[] URLS = {
            //登入頁、登入請求、登出請求
            "/loginPage",
            "/login",
            "/logout",

            //靜態資源,例如:js、css等
            "/assets/**",

            //一些特殊無需許可權控制的地址、api
            "/portal/index",
    };

    /**
     * 使用者角色資訊一般情況下是不輕易更改,可以將結果儲存到快取物件
     */
    private static HashMap<String,List<Role>> userRoleMap = new HashMap<>(10);

    //查詢資料庫操作,應交由專案ORM框架負責
    private final DbUtil dbUtil = new DbUtil("jdbc:mysql://localhost/jfinal_demo","root","123456");

    /**
     * 鑑權中心
     * PS:返回值型別有待商榷
     */
    public String auc(HttpServletRequest request){
        //請求URL地址
        String requestUri = request.getRequestURI();

        SecurityUtil securityUtil = SecurityUtil.getInstance();

        //是否為無需登入即可訪問URL
        if(SecurityUtil.checkUrl(requestUri,SecurityUtil.URLS)){
            //允許訪問!
            return "SUCCEED";
        }

        //是否為登入使用者
        SecurityUtil.User loginUser = securityUtil.getLoginUser(request);
        if(loginUser == null){
            //未登入或登入憑證過期!
            return "UNAUTHORIZED";
        }

        //該登入使用者是否有權訪問當前URL
        if(!SecurityUtil.checkUrl(requestUri,securityUtil.getRoleUrlByUserId(loginUser.getId()))){
            //抱歉,你無許可權訪問!
            return "FORBIDDEN";
        }

        //允許訪問!
        return "SUCCEED";
    }

    /**
     * 檢查requestUri是否包含在urls中
     */
    public static boolean checkUrl(String requestUri,String[] urls){
        //對/進行特殊處理
        if("/".equals(requestUri) && !Arrays.asList(urls).contains(requestUri)){
            return false;
        }

        String[] requestUris = requestUri.split("/");
        for (String url : urls) {
            if (check(requestUris, url.split("/"))) {
                return true;
            }
        }

        return false;
    }
    private static boolean check(String[] requestUris,String[] urls){
        for (int i1 = 0; i1 < requestUris.length; i1++) {
            //判斷長度
            if (i1 >= urls.length){
                return false;
            }

            //處理/*、/**情況
            if("**".equals(urls[i1])){
                return true;
            }
            if("*".equals(urls[i1])){
                continue;
            }

            //處理帶字尾
            if(requestUris[i1].contains(".") && urls[i1].contains(".")){
                String[] split = requestUris[i1].split("\\.");
                String[] split2 = urls[i1].split("\\.");

                // *.字尾的情況
                if("*".equals(split2[0]) && split[1].equals(split2[1])){
                    return true;
                }
            }

            //不相等
            if(!requestUris[i1].equals(urls[i1])){
                return false;
            }

        }

        return true;
    }

    /**
     * 從request設定、獲取當前登入使用者
     * PS:登入使用者可以放在session中,也可以做做成jwt
     */
    public void setLoginUser(HttpServletRequest request,User loginUser){
        request.getSession().setAttribute("loginUser",loginUser);
    }
    public User getLoginUser(HttpServletRequest request){
        return (User)request.getSession().getAttribute("loginUser");
    }
    public List<Role> getLoginUserRole(HttpServletRequest request){
        User loginUser = this.getLoginUser(request);
        return loginUser != null ? getRoleByUserId(loginUser.getId()) : null;
    }

    /**
     * 根據使用者id,獲取使用者允許訪問URL
     */
    public String[] getRoleUrlByUserId(String userId){
        StringBuilder roleUrl = new StringBuilder();
        for (SecurityUtil.Role role : this.getRoleByUserId(userId)) {
            roleUrl.append(",").append(role.getRoleUrl());
        }
        return roleUrl.toString().split(",");
    }

    /**
     * 獲取使用者、使用者角色
     * PS:這些查詢資料庫操作,應交由專案ORM框架負責
     */
    public User getUserByUserNameAndPassword(String username,String password){
        //PS:密碼應該MD5加密後密文儲存,匹配時先MD5加密後匹配,本例中儲存的是明文,就不進行MD5加密了
        User user = null;
        HashMap<String, Object> map = dbUtil.findOne("select * from sys_user where user_name = ? and password = ?", new String[]{username, password});
        if(map != null){
            user = new User(map.get("id").toString(),map.get("nick_name").toString(),map.get("user_name").toString(),map.get("password").toString());
        }

        //關閉資料庫連線
        dbUtil.close();

        return user;
    }
    public List<Role> getRoleByUserId(String userId){
        //先從快取中獲取
        List<Role> roles = userRoleMap.get(userId);
        if(roles != null){
            return roles;
        }

        //查詢資料庫
        List<Role> roleList = null;
        List<HashMap<String, Object>> list = dbUtil.find("select r.* from sys_role r join sys_user_role ur on r.id = ur.role_id where ur.user_id = ?", new String[]{userId});
        if(list != null){
            roleList = new ArrayList<>(list.size());
            for (HashMap<String, Object> map : list) {
                roleList.add(new Role(map.get("id").toString(),map.get("role_name").toString(),map.get("role_menu").toString(),map.get("role_url").toString()));
            }
        }

        //關閉資料庫連線
        dbUtil.close();

        //放到快取中
        userRoleMap.put(userId,roleList);

        return roleList;
    }

    /*
        3張基礎表

        sys_user 系統使用者表
            id        表id
            nick_name 暱稱
            user_name 賬號
            password  密碼

        sys_role 系統角色表
            id        表id
            role_name 角色名稱
            role_menu 角色選單可視許可權(可以不關聯選單,單獨做成選單管理直接與使用者關聯)
            role_url  角色URL訪問許可權

        sys_user_role 系統使用者-角色關聯表
            id      表id
            user_id 使用者id
            role_id 角色id
     */
    public class User{
        private String id;//表id
        private String nickName;//暱稱
        private String userName;//賬號
        private String password;//密碼

        public User(String id, String nickName, String userName, String password) {
            this.id = id;
            this.nickName = nickName;
            this.userName = userName;
            this.password = password;
        }

        public String getId() {
            return id;
        }

        public String getNickName() {
            return nickName;
        }

        public String getUserName() {
            return userName;
        }

        public String getPassword() {
            return password;
        }
    }
    public class Role{
        private String id;//表id
        private String RoleName;//角色名稱
        private String RoleMenu;//角色選單可視許可權(可以不關聯選單,單獨做成選單管理直接與使用者關聯)
        private String RoleUrl;//角色URL訪問許可權

        public Role(String id, String roleName, String roleMenu, String roleUrl) {
            this.id = id;
            RoleName = roleName;
            RoleMenu = roleMenu;
            RoleUrl = roleUrl;
        }

        public String getId() {
            return id;
        }

        public String getRoleName() {
            return RoleName;
        }

        public String getRoleMenu() {
            return RoleMenu;
        }

        public String getRoleUrl() {
            return RoleUrl;
        }
    }
    public class UserRole{
        private String id;//表id
        private String UserId;//使用者id
        private String RoleId;//角色id
    }
}

  資料庫目前用的是mysql,使用時要記得新增驅動依賴

  SpringBoot整合

  程式碼

  PS:我們自定義DbUtil工具類獲取連線操作,SpringBoot專案需要帶上時區、字符集引數

jdbc:mysql://localhost/jfinal_demo?serverTimezone=GMT%2B8&characterEncoding=utf-8

  新建一個springboot專案或在我們的springBoot專案中隨便挑一個來測試

  首先需要將springboot-exceptionhandler專案中自定義統一異常處理相關程式碼拷貝過來,方便捕獲我們丟擲的業務異常

  然後新建一個AccessAuthorityFilter攔截器

/**
 * SpringBoot測試鑑權攔截器
 */
@WebFilter(filterName = "AccessAuthorityFilter",urlPatterns = {"/**"})
@ServletComponentScan
@Component
public class AccessAuthorityFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //請求頭
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        SecurityUtil securityUtil = SecurityUtil.getInstance();

        //鑑權中心
        String auc = securityUtil.auc(request);
        if("UNAUTHORIZED".equals(auc)){
            throw new ServiceException(ErrorEnum.UNAUTHORIZED);
        }
        if("FORBIDDEN".equals(auc)){
            throw new ServiceException(ErrorEnum.FORBIDDEN);
        }

        //執行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

  寫幾個測試介面,包括login登入、logout登出等

/**
 * 測試介面
 */
@RestController
public class TestController {

    /**
     * 簡單登入、登出、獲取登入使用者
     */
    @GetMapping("/login")
    public String login(HttpServletRequest request,String username, String password){
        SecurityUtil securityUtil = SecurityUtil.getInstance();
        SecurityUtil.User user = securityUtil.getUserByUserNameAndPassword(username, password);
        if(user != null){
            securityUtil.setLoginUser(request,user);
            return "登入成功!";
        }else{
            return "賬號或密碼錯誤...";
        }
    }
    @GetMapping("/logout")
    public String logout(HttpServletRequest request){
        SecurityUtil securityUtil = SecurityUtil.getInstance();
        SecurityUtil.User loginUser = securityUtil.getLoginUser(request);
        securityUtil.setLoginUser(request,null);

        return "登出成功!";
    }
    @GetMapping("/getLoginUser")
    public HashMap<String, Object> getLoginUser(HttpServletRequest request){
        SecurityUtil securityUtil = SecurityUtil.getInstance();
        SecurityUtil.User loginUser = securityUtil.getLoginUser(request);
        List<SecurityUtil.Role> loginUserRole = securityUtil.getLoginUserRole(request);

        HashMap<String, Object> map = new HashMap<>(2);
        map.put("loginUser",loginUser);
        map.put("loginUserRole",loginUserRole);
        return map;
    }

    /**
     * 登入、鑑權測試介面
     */
    @GetMapping("/sys/xtgl")
    public String xtgl() {
        return "系統管理...";
    }
    @GetMapping("/sys/yhgl")
    public String yhgl() {
        return "使用者管理...";
    }
    @GetMapping("/portal/mhgl")
    public String mhgl() {
        return "網站門戶管理...";
    }
    @GetMapping("/portal/index")
    public String portalIndex() {
        return "網站門戶首頁...";
    }
}

  效果

  未登入時,只有配置在無需登入即可訪問的URL才能允許訪問

  登入後,除了無需許可權的URL,還可以訪問角色允許訪問的URL,登出後恢復登入前狀態

  SpringBoot專案比較常規大家用的也比較多,程式碼就不上傳了

  JFinal整合

  程式碼

  建立一個訪問許可權攔截器AccessAuthorityInterceptor

package cn.huanzi.qch.interceptor;

import cn.huanzi.qch.common.model.ErrorEnum;
import cn.huanzi.qch.common.model.ServiceException;
import cn.huanzi.qch.util.SecurityUtil;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.log.Log;

import javax.servlet.http.HttpServletRequest;

/**
 * 訪問許可權攔截器
 */
public class AccessAuthorityInterceptor implements Interceptor {
    private static final Log log = Log.getLog(AccessAuthorityInterceptor.class);

    @Override
    public void intercept(Invocation invocation) {
        //請求頭
        HttpServletRequest request = invocation.getController().getRequest();

        SecurityUtil securityUtil = SecurityUtil.getInstance();

        //鑑權中心
        String auc = securityUtil.auc(request);
        if("UNAUTHORIZED".equals(auc)){
            throw new ServiceException(ErrorEnum.UNAUTHORIZED);
        }
        if("FORBIDDEN".equals(auc)){
            throw new ServiceException(ErrorEnum.FORBIDDEN);
        }

        invocation.invoke();
    }
}

  AppConfig中註冊攔截器

/**
 * API 引導式配置
 */
public class AppConfig extends JFinalConfig {

    //省略其他程式碼...
    
    /**
     * 配置路由
     */
    public void configRoute(Routes me) {
        //省略其他程式碼...

        // 此處配置 Routes 級別的攔截器,可配置多個
        me.addInterceptor(new AccessAuthorityInterceptor());
    }
    
    //省略其他程式碼...
}

  寫幾個測試介面,包括login登入、logout登出等

/**
 * 使用者表 Controller
 *
 * 作者:Auto Generator By 'huanzi-qch'
 * 生成日期:2021-07-29 17:32:50
 */
@Path(value = "/user",viewPath = "/user")
public class UserController extends CommonController<User,UserServiceImpl> {
    //省略其他程式碼...

    /**
     * 簡單登入、登出、獲取登入使用者
     */
    @ActionKey("/login")
    public void login() {
        String username = get("username");
        String password = get("password");

        SecurityUtil securityUtil = SecurityUtil.getInstance();
        SecurityUtil.User user = securityUtil.getUserByUserNameAndPassword(username, password);
        if(user != null){
            securityUtil.setLoginUser(this.getRequest(),user);
            renderText("登入成功!");
        }else{
            renderText("賬號或密碼錯誤...");
        }
    }
    @ActionKey("/logout")
    public void logout() {
        SecurityUtil securityUtil = SecurityUtil.getInstance();
        SecurityUtil.User loginUser = securityUtil.getLoginUser(this.getRequest());
        securityUtil.setLoginUser(this.getRequest(),null);

        renderText("登出成功!");
    }
    @ActionKey("/getLoginUser")
    public void getLoginUser() {
        SecurityUtil securityUtil = SecurityUtil.getInstance();
        SecurityUtil.User loginUser = securityUtil.getLoginUser(this.getRequest());
        List<SecurityUtil.Role> loginUserRole = securityUtil.getLoginUserRole(this.getRequest());

        HashMap<String, Object> map = new HashMap<>(2);
        map.put("loginUser",loginUser);
        map.put("loginUserRole",loginUserRole);
        renderJson(map);
    }

    /**
     * 登入、鑑權測試介面
     */
    @ActionKey("/sys/xtgl")
    public void xtgl() {
        renderText("系統管理...");
    }
    @ActionKey("/sys/yhgl")
    public void yhgl() {
        renderText("使用者管理...");
    }
    @ActionKey("/portal/mhgl")
    public void mhgl() {
        renderText("網站門戶管理...");
    }
    @ActionKey("/portal/index")
    public void portalIndex() {
        renderText("網站門戶首頁...");
    }
}

  效果

  未登入時,只有配置在無需登入即可訪問的URL才能允許訪問

  登入後,除了無需許可權的URL,還可以訪問角色允許訪問的URL,登出後恢復登入前狀態

  JFinal專案的整合程式碼在我的jfinal-demo專案中:不想用Spring全家桶?試試這個國產JFinal框架

  後記

  一套簡單的登入、鑑權工具暫時先記錄到這,後續再進行補充

版權宣告

作者:huanzi-qch 出處:https://www.cnblogs.com/huanzi-qch 若標題中有“轉載”字樣,則本文版權歸原作者所有。若無轉載字樣,本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利.

AD廣告位(長期招租,如有需要請私信)

【基塔後臺】免費後臺管理系統,低程式碼快速搭建管理後臺

【騰訊雲】雲產品限時秒殺,爆款1核2G雲伺服器,首年74元!
【騰訊雲】境外1核2G伺服器低至2折,半價續費券限量免費領取!
【騰訊雲】星星海SA2雲伺服器,1核2G首年99元起,高性價比首選!
【騰訊雲】中小企業福利專場,多款剛需產品,滿足企業通用場景需求,雲伺服器2.5折起!

【阿里雲】新老使用者同享,上雲優化聚集地!
【阿里雲】最新活動頁,上新必買搶先知,勁爆優惠不錯過!
【阿里雲】輕量應用伺服器2核2G 低至60元/年起!香港與海外伺服器最低24元/月起!
【阿里雲】ECS例項升級、續費,享低至 6.3折 限時折扣!

捐獻、打賞

請注意:作者五行缺錢,如果喜歡這篇文章,請隨意打賞!

支付寶

微信


QQ群交流群

QQ群交流群
有事請加群,有問題進群大家一起交流!