• Thiết kế Ctrình phân quyền
  • Thiết kế Ctrình phân quyền

    Noname > 15-08-10, 01:48 PM

    Phân quyền trong Access

    Trong Access đã hỗi trợ phân quyền bằng cách tạo file workGroup *.mdw, *.mda. tuy nhiên cách này hơi nhiêu khê ở chỗ là máy sử dụng phải map tới file này thì mới xài được.
    Vì vậy một cách khác mọi người quan tâm là phân quyền trực tiếp trong chương trình access của mình. Nếu mình post 1 đoạn chương trình lên cho mọi người tham khảo thì quá dễ dàng, nhưng điều đó không mang ý nghĩa học tập. Vì vậy, mình quyết định sẽ tiến hành Phân tích bài toán và thiết lập từng bước sao cho dễ hiểu nhất, ai biết Access cũng có thể làm được.


    I/Mô tả:

    Chương trình sẽ yêu cầu đăng nhập mỗi khi mở, nếu không có user name thì chỉ vào được quyền hạn chế dành cho khách.

    II/ Thiết kế và giải thuật:

    Mô tả ý tưởng:

    - Khi bạn đăng nhập vào, chương trình sẽ ghi nhận username của bạn trong một biến toàn cục(public).
    Sau đó sẽ qua một function để biết bạn thuộc group nào.( mình chia group thành các cấp khác nhau, cấp cao thì quyền nhiều hơn cấp dưới)

    - Ở mỗi process cụ thể sẽ cho biết cấp tối thiểu để được đăng nhập vào process đó.

    Chuẩn bị table:
    - Table cần có là danh sách user: tblDSUser(ID,pass)
    - Table lưu cấp của các user: tblWorkGroup(WgLevel, WgName,user)
    Trong đó : username là khóa ngoại liên kết với tblDSUser

    Dữ liệu nhập thử:

    tblDSUser
    ID --- Pass

    Admin ---- Admin
    Duytuan ---- tuan
    Guest ----

    tblWorkGroup

    WGLevel---WgName---User
    9---Admin --- Admin
    8---User --- Duytuan
    0---Guest---guest

    Việc đều tiên là bạn vào khai báo một biến toàn cục tên là user, cách làm như sau:
    Vào menu Tool => marcr Visual basic editor

    Một cửa sổ VB xuất hiện, tại đây bạn vào menu Inser => module
    Trong Module mới tạo, bạn khai báo một biến toàn cục để lưu tên user hiện hành:

    Mã:
    Public username as string


    OK, bây giờ bạn đã đủ đồ nghề để tạo form đăng nhập.
    [Hình: loginForm.jpg]



    Đầu tiên, bạn tạo 1 form, đặt tên nó là frmLogin

    1/Vẽ 1 lable với caption như sau “Xin mời nhập Username,pass hoặc nhấn vào guest để ghé thử”

    2/Vẽ 1 combobox đặt tên là: cbbusername,
    thuộc tính row source: SELECT tblDSUser.ID, tblDSUser.Pass FROM tblDSUser;

    3/ Vẽ một textbox đặt tên là txtPassWord
    Input mask kiểu Password

    4/ Vẽ 1 text box đặt tên là txtPassTemp
    Thuộc tính visible là No
    5/ vẽ một nút đặt tên là cmdLogin
    6/Vẽ một nút đặt tên là cmdGuest
    Vậy là xong phần giao diện, bây giờ là cái ruột

    Mô tả:
    Sau khi cập nhật tên user thì txtPassTemp sẽ lấy về cái password , và field này user hoàn toàn không nhìn thấy. Mục đích là để so sánh pass này với cái pass của user nhập vào. Đúng thì tiếp tục log vào form chính, đồng thời gán biến username bằng tên đăng nhập, sai thì báo lỗi.

    Như vậy, hành động after Update của ComboBox nhập user như sau:


    Trích:
    Mã:
    Private Sub cbbUsername_AfterUpdate()
    Me.txtPassTemp.Value = cbbUserName.Column(1)
    ‘ lấy về password
    End Sub

    Bây giờ ta xử lý nút Login,

    đầu tiên bạn khoan đã xử. Bạn tạo 1 form đặt tên là frmMain rồi chừa trống đấy, form này để dành sau khi login thì nó sẽ gọi lên.

    Bây giờ ta quay lại với nút login.
    Nó phải làm các việc sau:+
    - Kiểm tra password nhập vào có đúng với field : txtPassTemp hay không, nếu đúng thì làm cái việc là gán biến toàn cục username bằng giá trị của ô CbbUsername.
    - Chào mừng user đó đăng nhập
    - Mở form frmMain
    - Đóng form frmLogin lại
    Nếu sai thì báo là nhập sai

    Đoạn code xử lý như sau:


    Trích:
    Mã:
    Private Sub cmdLogin_Click()
    If Me.txtPassWord.Value = Me.txtPassTemp.Value Then
    Username = Me.cbbUserName
    MsgBox "Welcom To " & Username
    DoCmd.OpenForm "frmMain"
    DoCmd.Close acForm, "frmLogin"
    Else
    MsgBox "Login Fail, check your Username and your password"
    End If
    End Sub
    Bây giờ tới nút cmdGuest

    Tương tự nhưng không cần kiểm tra gì cả, tên username được gán bằng tên Guest và vào thẳng form main

    Trích:
    Mã:
    Private Sub CmdGuest_Click()
    Username = "Guest"
    MsgBox "Welcom To " & Username
    DoCmd.OpenForm "frmMain"
    DoCmd.Close acForm, "frmLogin"
    End Sub

    Trong khi chờ đợi các bạn cứ thiết kế Main form như hình nhé, nội dung thì thứ 2 No lên phân tích tiếp

    [Hình: MainForm.jpg]
    Hôm trước mình nhầm lẫn một chút ở khâu chuẩn bị table

    Trích:
    Mã:
    Chuẩn bị table:
    - Table cần có là danh sách user: tblDSUser(ID,pass)
    - Table lưu cấp của các user: tblWorkGroup(WgLevel, WgName,user)
    Trong đó : username là khóa ngoại liên kết với tblDSUser
    sai ở table tblWorkGroup, vì như vậy thì ở mỗi level ta chỉ tạo được một user thôi
    Mình xin đính chính lại table này
    Mã:
    tblWorkGroup(WgLevel, WgName,user)

    Đầu tiên, để chuẩn bị cái ruột cho mainform, chúng ta phải có một đoạn code để lấy về level của user hiện hành.
    Các bạn còn nhớ cái module mà bạn đã khai báo biến toàn cục: username chứ?
    bây giờ mở nó lên, viết tiếp vào đoạn code lấy về level user

    Trích:
    Mã:
    Function checkuser() As Integer
    On Error GoTo Err ' nếu user vào trực tiếp bằng quyền guest thì cho level là 0
    Dim rs1 As Recordset
    Dim sql As String
    sql = " select max(WGlevel) from tblWorkGroup where user= '" & Username & "'"
    Set rs1 = CurrentDb.OpenRecordset(sql)
    rs1.MoveFirst
    checkuser = rs1(0).Value
    Exit Function

    Err:
    checkuser = 0
    Exit Function

    End Function
    OK, bây giờ đồ nghề đầy đủ, các bạn vẽ mainform rồi chứ/? Đặt tên cái form đó là frmMain.
    Các nút trên form đặt tên lần lượt là: cmdAdmin,cmdUser,cmdGuest
    Trong chương trình của mình sẽ chia làm 9 cấp độ đăng nhập, quyền cao nhất Admin,sẽ vào với level 9, các user tùy theo là trưởng phòng hay nhân viên sẽ có level 1-8
    Guest sẽ vào với level 0. Giải thuật của ta ứng với mỗi nút là sẽ tạo ra yêu cầu level tối thiểu. Đối với user Admin thì tối thiểu phải level 9
    OK.
    Bây giờ ta xử lý nút cmd Admin như sau

    Trích:
    Mã:
    Private Sub cmdAdmin_Click()
    Dim userRequest As String ‘ biến yêu cầu user tối thiểu
    userRequest = 9
    If userRequest <= checkuser Then
    MsgBox "Xin chao ban đa dang nhap vao quyen admin"
    Else
    MsgBox "ban khonn duoc dang nhap function nay"
    End If
    End Sub
    Tương tự với Nút user, ở ví dụ này, nút user yêu cầu phải level 8 mới vào được. bạn có thể hạ thấp level yêu cầu xuống cho nhân viên.
    Trích:
    Mã:
    Private Sub cmdUser_Click()
    Dim userRequest As String
    userRequest = 8
    If userRequest <= checkuser Then
    MsgBox "Xin chao ban da dang nhap vao quyen user"
    Else
    MsgBox "ban khong duoc dang nhap function nay"
    End If
    End Sub
    Và nút guest cũng tương tự
    Trích:
    Mã:
    Private Sub CmdGuest_Click()
    Dim userRequest As String
    userRequest = 0
    If userRequest <= checkuser Then
    MsgBox "Xin chao dang nhap vao quyen khach"
    Else
    MsgBox "ban khogn duoc dang nhap function nay"
    End If
    End Sub
    Hihi, đáng lẽ có thể sửa quyền khách cho hợp lý hơn, nhưng mình copy paster cho nhanh

    Hướng dẫn cơ bản tương đối ổn rồi, bây giờ ta “ màu mè” một chút là khi vào chương trình bắt buột phải login vào cái frmLogin, cách nào ư? Nhiều lắm, nhưng mình thích dùng cái marcro.
    Bạn tạo một marcro, đặt tên nó là AutoExec
    Thằng này sẽ tự chạy mỗi khi ta vào chương trình.
    Nội dung của marcro AutoExec chỉ có 1 hành động dòng như sau:

    Open form
    Form name: frmLogin
    View: form
    Windows mode: Dialog

    Sở dĩ tôi bảo các bạn dùng marcro là vì cái Dialog này, nó bắt buột phải đăng nhập mới vào, còn không thì nhấn guest.
    Sau đó ta vào menu Tool =>startup bỏ chọn hết tất cả để nó không cho các user táy máy khi đăng nhập.
    Chưa xong đâu, bạn quay lại cái Module, mở nó lên, vào menu Tool => “tên chương trình” properties nhảy qua tab protection, cài password cho cái source của bạn luôn. Cho mấy tay táy máy khỏi link vào import mấy cái table quý hóa của mình.
    OK.
    Đóng chương trình và mở lại. Thử với các quyền thử xem!

    Và bây giờ bạn muốn edit chương trình thì làm thế nào? Dễ thôi! Nhấn phím shift trong khi mở nó sẽ không load macro AutoExec nữa, vào cửa sổ design như bình thường!
    Vậy chương trình không an toàn về bảo mật? Ồ không đâu, tôi sẽ giới thiệu trong bài khác về cách vô hiệu hóa phím shift, và khi muốn mở lại thì phải Enable phím shift

    Nếu các bạn chưa tin về tính bảo mật? Hãy thử chương trình Demo của Noname xem! trừ khi bạn đăng nhập vào quyền admin, còn lại các user kia thì không sửa xóa gì chương trình được cả
    http://duyeagle.googlepages.com/phanquyen.rar

  • RE: Thiết kế Ctrình phân quyền

    Noname > 15-08-10, 01:48 PM

    Dưới đây và 1 ví dụ demo về phân quyền của bạn Haquocquan, cũng rất hay đáng để ta tham khảo>

    Pass như sau:
    Khi đăng nhập:
    - User: QUAN ---- Password: ladieskiller
    - Các user khác: password: 123
    Còn khi vào các mục khác có yêu cầu password: ladieskiller
    http://sites.google.com/site/thuvienthut...ects=0&d=1
  • RE: Thiết kế Ctrình phân quyền

    ncxn > 13-09-10, 05:47 PM

    hì hì, hổng có chương trình gì mà login vô có dzụ Admin, user và guest é. Ngừ ta chỉ làm txtPass và txtUser và cmdLogin , nếu chương trình lớn hơn thì thêm cái cbox để chọn database
    -----------
    Về yêu cầu phân quyền ứng dụng thì ông suy nghĩ theo hướng này nà:
    1. Tập hợp toàn bộ các ứng đối tượng trong chương trình( form, report, query, table) và các thuộc tính do người viết chương trình định nghĩa: xem, thêm, sửa, xóa . Đó là cái cơ bản nhất khi muốn viết hệ thống phân quyền
    2. Lập luận rằng mỗi một user khi vào chương trình được cấp cho các thuộc tính tương ứng với đối tượng nào đó thôi
    ví dụ: userA được quyền xem, thêm, sửa fromX thì khi user này login vào ( cấp cho nó cái biến toàn cục currentUser = userA) khi đó chương trình sẽ tạo ra tem_Query (query có hiệu lực khi user còn hoạt động trên Clien) có dạng userA(FormX, xem=true, thêm= true, sửa = true, xóa=false)
    3. Khi đó ta tạo một function (curentUser) để xử lý các thuộc tính xem, sửa, thêm, xóa là xong . Chú ý rằng function này viết dựa trên cái tem_Query kia là được.

    -----------
    hì hì,mình cũng chưa làm lần nào nhưng thấy các chương trình họ đều làm theo hướng này
  • RE: Thiết kế Ctrình phân quyền

    Noname > 13-09-10, 08:47 PM

    (13-09-10, 05:47 PM)ncxn Đã viết: hì hì, hổng có chương trình gì mà login vô có dzụ Admin, user và guest é. Ngừ ta chỉ làm txtPass và txtUser và cmdLogin , nếu chương trình lớn hơn thì thêm cái cbox để chọn database
    -----------
    Về yêu cầu phân quyền ứng dụng thì ông suy nghĩ theo hướng này nà:
    1. Tập hợp toàn bộ các ứng đối tượng trong chương trình( form, report, query, table) và các thuộc tính do người viết chương trình định nghĩa: xem, thêm, sửa, xóa . Đó là cái cơ bản nhất khi muốn viết hệ thống phân quyền
    2. Lập luận rằng mỗi một user khi vào chương trình được cấp cho các thuộc tính tương ứng với đối tượng nào đó thôi
    ví dụ: userA được quyền xem, thêm, sửa fromX thì khi user này login vào ( cấp cho nó cái biến toàn cục currentUser = userA) khi đó chương trình sẽ tạo ra tem_Query (query có hiệu lực khi user còn hoạt động trên Clien) có dạng userA(FormX, xem=true, thêm= true, sửa = true, xóa=false)
    3. Khi đó ta tạo một function (curentUser) để xử lý các thuộc tính xem, sửa, thêm, xóa là xong . Chú ý rằng function này viết dựa trên cái tem_Query kia là được.

    -----------
    hì hì,mình cũng chưa làm lần nào nhưng thấy các chương trình họ đều làm theo hướng này


    Như ý của bạn cũng hay, và mình cũng làm rồi, vài hệ thống lớn người ta cũng làm rồi! Ưu điểm là dễ thiết kế. big green
    Khuyết điểm nếu công ty bạn có nhiều user, nhiều nhóm user thì làm vậy người quản trị sẽ tốn nhiều thời gian cho mỗi người. Trong khi đó nếu phân quyền theo group, thì bạn chỉ việc gán user đó cho 1 group, và quyền hạn là quyền bạn cấp cho group đó. Bằng chứng là hệ thống user của diễn đàn này và cách cấp phát user của Windows. (nếu bạn làm với file server không thể không biết chức năng này).
    Cái này mình chỉ hướng dẫn theo cách cơ bản nhất. Quan trọng là ở giải thuật. Và khi làm được thì có thể tự phát triển theo hướng riêng mình!
    Thân!
  • RE: Thiết kế Ctrình phân quyền

    ncxn > 14-09-10, 10:46 AM

    Group thì chỉ cần viết cái function kia dành cho Group rồi add user vào Group là được.
    Lúc này User sẽ thừa hưởng toàn bộ các quyền được cấp cho Group , hơn nữa 1 user có thể nằm trong nhiều Group (kiêm nhiệm) và có thể không nằm trong Gr nào nhưng vẫn được cấp quyền sử dụng
    Cái này có lợi thế là : người quản trị có thể tạo luôn group -- cấp quyền cho nó xong rồi tạo user add vào group là xong
    ------Hì hì cái ncxn muốn làn người dùng có thể thao tác hoàn toàn chứ không làm sẵn cố định một chức năng nào. (Trừ khi điều đó là bắt buộc)
    ncnx cũng mới tìm hiểu về access nhưng xem ra hạn chế cũng không nhỏ nhỉ.
    Đang mò cái vụ menu : suy nghĩ thế này
    Tạo một table chứa dữ liệu các menu

    tblMenu(ID, level, name, label, object, object_type, action, action_type, enable)

    - level:
    ----1
    ------11
    ------12
    ----------121
    ----------122
    -----2
    ... Nói chung thuật toán này cũng không khó
    - name, label : thì chỉ là tên của nó thôi
    - object, object_type : ví dụ fromA thì type là from
    - action, action_type : ví dụ fromA có action là click và type là view (chẳn hạn nếu report thì cho print luôn)
    - enable (true/false): nếu true thì user được cấp quyền sẽ thấy menu này (field này sẽ update theo bản phân quyền của user khi user login vào chương trình). True: cho hiện menu/ false: ngược lại
    ---------
    Mấy cái object, type sẽ tự động tập hợp khi user tạo menu mới
    ---------
    Đó như vậy người dùng cũng có thể tạo/xóa menu cho riêng mình hìhi
    Khả thi không nhỉ
  • RE: Thiết kế Ctrình phân quyền

    Noname > 14-09-10, 11:25 AM

    (14-09-10, 10:46 AM)ncxn Đã viết: Group thì chỉ cần viết cái function kia dành cho Group rồi add user vào Group là được.
    Lúc này User sẽ thừa hưởng toàn bộ các quyền được cấp cho Group , hơn nữa 1 user có thể nằm trong nhiều Group (kiêm nhiệm) và có thể không nằm trong Gr nào nhưng vẫn được cấp quyền sử dụng
    Cái này có lợi thế là : người quản trị có thể tạo luôn group -- cấp quyền cho nó xong rồi tạo user add vào group là xong
    ------Hì hì cái ncxn muốn làn người dùng có thể thao tác hoàn toàn chứ không làm sẵn cố định một chức năng nào. (Trừ khi điều đó là bắt buộc)
    ncnx cũng mới tìm hiểu về access nhưng xem ra hạn chế cũng không nhỏ nhỉ.
    Đang mò cái vụ menu : suy nghĩ thế này
    Tạo một table chứa dữ liệu các menu

    tblMenu(ID, level, name, label, object, object_type, action, action_type, enable)

    - level:
    ----1
    ------11
    ------12
    ----------121
    ----------122
    -----2
    ... Nói chung thuật toán này cũng không khó
    - name, label : thì chỉ là tên của nó thôi
    - object, object_type : ví dụ fromA thì type là from
    - action, action_type : ví dụ fromA có action là click và type là view (chẳn hạn nếu report thì cho print luôn)
    - enable (true/false): nếu true thì user được cấp quyền sẽ thấy menu này (field này sẽ update theo bản phân quyền của user khi user login vào chương trình). True: cho hiện menu/ false: ngược lại
    ---------
    Mấy cái object, type sẽ tự động tập hợp khi user tạo menu mới
    ---------
    Đó như vậy người dùng cũng có thể tạo/xóa menu cho riêng mình hìhi
    Khả thi không nhỉ
    Vấn đề không phải là ở Access mà là ở giải thuật. Nếu chỉ thao tác thuần túy trên dữ liệu thì mình nghĩ Access rất nhanh và mạnh rồi! (còn bảo mật thì đành nhờ bác SQL server làm back-end thôi
    Nếu bạn có demo hay, hoan nghênh bạn chia xẻ! happy
  • RE: Thiết kế Ctrình phân quyền

    no1blue > 08-12-10, 12:01 AM

    trong bài này
    em làm xong hết cái form login ấy
    thì cho dù em nhập kỉu j thì kỉu
    nó cũng báo Login Fail, check your Username and your password
    mà dòng nào nghĩa là sao em ko hỉu ???
    Trong đó : username là khóa ngoại liên kết với tblDSUser
  • RE: Thiết kế Ctrình phân quyền

    haquocquan > 13-12-10, 11:52 PM

    (08-12-10, 12:01 AM)no1blue Đã viết: trong bài này
    em làm xong hết cái form login ấy
    thì cho dù em nhập kỉu j thì kỉu
    nó cũng báo Login Fail, check your Username and your password
    mà dòng nào nghĩa là sao em ko hỉu ???
    Trong đó : username là khóa ngoại liên kết với tblDSUser

    Bạn đưa bài của bạn lên đi, mọi người hỗ trợ
  • RE: Thiết kế Ctrình phân quyền

    no1blue > 14-12-10, 12:25 AM

    CHO EM HỎI XÍU
    EM MUỐN LÀ KHI MÌNH PHÂN QUYỀN XONG RỒI ẤY
    MUỐI KO CHO GUEST XEM CÁC FUNCTION CỦA ADMIN THÌ PHẢI CHỈNH CODE NHƯ THẾ NÀO ??
  • RE: Thiết kế Ctrình phân quyền

    Noname > 14-12-10, 12:31 AM

    Thì kiểm tra user đó có phải admin không, nếu không phải thì hiện câu thông báo không có quyền truy cập! Thế thôi!
    If...then
    Lệnh thế này
    else
    Lệnh thế nọ
    End if