Làm chủ Grails: Chứng thực và phân quyền

31 6 0
Làm chủ Grails: Chứng thực và phân quyền

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Đảm bảo an ninh cho các ứng dụng Grails của bạn Scott Davis , Tổng Biên tập, AboutGroovy.com Tóm tắt: Grails cung cấp tất cả các khối xây dựng cơ bản bạn cần để lắp ghép thành một ứng dụng Web an toàn, các khối này được sắp xếp từ mức thẩm định quyền đơn giản thông qua cơ chế đăng nhập đến việc phân quyền dựa trên vai trò, và trong phần Làm chủ Grails, Scott Davis cung cấp cho bạn những bài học thực hành về đảm bảo an ninh cho ứng dụng Grails của bạn. Bạn...

Làm chủ Grails: Chứng thực phân quyền Đảm bảo an ninh cho ứng dụng Grails bạn Scott Davis , Tổng Biên tập, AboutGroovy.com Tóm tắt: Grails cung cấp tất khối xây dựng bạn cần để lắp ghép thành ứng dụng Web an toàn, khối xếp từ mức thẩm định quyền đơn giản thông qua chế đăng nhập đến việc phân quyền dựa vai trò, phần Làm chủ Grails, Scott Davis cung cấp cho bạn học thực hành đảm bảo an ninh cho ứng dụng Grails bạn Bạn học trình gắn vào (plug-in) cho bạn mở rộng khả đảm bảo an ninh cho ứng dụng bạn theo nhiều hướng Trong viết này, tiếp tục việc xây dựng "blog siêu nhỏ" có tên Blogito Tơi sử dụng lại Users viết trước (" Rewiring Grails with custom URIs and codecs") trường name phần URI đầy đủ Đã đến lúc thực thi hệ thống User đầy đủ Bạn học cách để tạo chế đăng nhập, hạn chế hoạt động người dùng dựa vào việc User có đăng nhập hay khơng, chí thêm vào số quyền dựa vai trò User Để bắt đầu, người sử dụng cần có cách đăng nhập vào blog cho họ bổ sung entry Việc thẩm định quyền Việc thẩm định quyền có lẽ ý tưởng tốt máy chủ blog hỗ trợ nhiều người dùng Dĩ nhiên bạn khơng muốn người dùng có tên John Doe lại tình cờ bổ sung entry lên blog hệt người dùng tên Jane Smith Việc thiết lập sở cho việc thẩm định quyền trả lời câu hỏi: "Bạn ai?" Ngay sau đó, bạn có thêm chút quyền nữa, trả lời cho câu hỏi: "Bạn phép làm gì?" Ví dụ biểu diễn tệp grails-app/domain/User.groovy mà bạn tạo vào lần trước: Ví dụ Lớp User class User { static constraints = { login(unique:true) password(password:true) name() } static hasMany = [entries:Entry] String login String password String name String toString(){ name } } Các trường login password đặt vị trí Tất bạn cần cung cấp điều khiển (controller) mẫu biểu (form) Hãy tạo tệp grails-app/controllers/UserController.groovy thêm vào đoạn mã, ví dụ 2: Ví dụ Thêm xác thực quyền login , logout cho điều khiển UserController class UserController { def scaffold = User def login = {} def authenticate = { def user = User.findByLoginAndPassword(params.login, params.password) if(user){ session.user = user flash.message = "Hello ${user.name}!" redirect(controller:"entry", action:"list") }else{ flash.message = "Sorry, ${params.login} Please try again." redirect(action:"login") } } def logout = { flash.message = "Goodbye ${session.user.name}" session.user = null redirect(controller:"entry", action:"list") } } Một lệnh login rỗng đơn giản kết thúc sau gọi Có nghĩa việc viếng thăm trang http://localhost:9090/blogito/user/login trình duyệt trả tệp grails-app/views/user/login.gsp (Bạn tạo tệp lập tức.) Việc kết thúc authenticate sử dụng phương thức GORM thuận tiện — findByLoginAndPassword() — để tìm thơng tin kiểu như: tìm User sở liệu, mà giá trị login password khớp với giá trị đưa vào trường mẫu biểu làm cho chúng khả dụng thông qua ánh xạ băm params Nếu User tồn tại, thêm vào phiên làm việc (session) Ngược lại, quay lại mẫu biểu đăng nhập cho User hội khác để cung cấp thông tin xác thực Lệnh đăng xuất logout đưa lời chào tạm biệt User, xóa thơng tin người sử dụng phiên làm việc sau chuyển đến hành động list EntryController Đã đến lúc bạn tạo tệp login.gsp Bạn gõ lại đoạn mã ví dụ bạn có thể: Gõ grails generate-views User cửa sổ dòng lệnh (command line) Sao chép tệp create.gsp vào tệp login.gsp Sửa chút để có mã kết Ví dụ login.gsp Login Login ${flash.message} Login: Password: Chú ý action mẫu biểu authenticate, so khớp tên bao đóng UserController.groovy Các tên thành phần nhập liệu — login password — phù hợp với tham số params.login params.password bao đóng authenticate Gõ grails run-app thực việc thẩm định quyền bạn lặp lại vài lần Thử đăng nhập với tên người dùng jsmith password foo (Nhớ " Rewiring Grails with custom URIs and codecs (Mắc nối Grail với URI tùy chỉnh mã hóa/giải mã)" bạn khởi tạo Blogito với cặp người dùng grails-app/conf/BootStrap.groovy.) Việc đăng nhập bạn bị lỗi, hình 1: Hình Thơng báo lỗi đăng nhập Thử lại với tên đăng nhập jsmith password wordpass Lần việc đăng nhập thành công Nếu thông báo chào mừng khơng xuất grails-app/views/entry/list.gsp — đơn giản bạn — chép khối từ tệp login.gsp dán vào đầu tệp list.gsp Đăng nhập lại với tên jsmith để kiểm chứng thông báo xuất giống hình 2: Hình Một thông báo động xác thực việc đăng nhập thành công Đến bạn chắn quyền hạn thực thi, bạn nên tạo thẻ TagLib cho việc đăng nhập đăng xuất dễ dàng Việc tạo quyền hạn TagLib Sự phân quyền mịn Sự phân quyền thô đề xuất beforeInterceptor khởi đầu cho việc phân quyền, bạn thêm móc nối (hooks) phân quyền cho riêng bao đóng Ví dụ, thể đây, User — người đăng nhập không riêng tác giả — sửa đổi Entry Bạn đóng lỗ hổng an ninh cách thêm bốn dịng lệnh sau vào vị trí thích hợp bao đóng edit tệp EntryController.groovy, ví dụ 8: Ví dụ Thêm quyền cho bao đóng edit def edit = { def entryInstance = Entry.get( params.id ) //limit editing to the original author if( !(session.user.login == entryInstance.author.login) ){ flash.message = "Sorry, you can only edit your own entries." redirect(action:list) } if(!entryInstance) { flash.message = "Entry not found with id ${params.id}" redirect(action:list) } else { return [ entryInstance : entryInstance ] } } Bạn (và nên) khóa bao đóng delete update cách dùng bốn dịng lệnh nói Nếu bạn khơng lịng với việc chép dịng lệnh dán vào nhiều nơi khác (việc khơng nên), bạn tạo phương thức đơn giản gọi phương thức ba bao đóng Nếu bạn thấy bạn sử dụng phương thức beforeInterceptor phương thức riêng thơng qua nhiều điều khiển (controllers), bạn đẩy cách xử lý thường gặp vào điều khiển chủ đơn có thêm điều khiển khác mở rộng cần cách sử dụng lớp Java Bạn thêm thứ vào hạ tầng sở thẩm định quyền để làm cho mạnh hơn: vai trò Việc thêm vai trò Việc gán vai trò cho Users cách thuận lợi để nhóm người dùng thành nhóm Bạn gán quyền cho nhóm thay cho người sử dụng Ví dụ: tạo User Chỉ việc kiểm tra người đăng nhập khơng đảm bảo an tồn Tơi thích giới hạn khả người dùng cách giao quyền quản lý tài khoản User cho người quản trị Ví dụ việc thêm trường vai trò (role) cho User, ràng buộc việc giới hạn giá trị cho author admin: Ví dụ Việc thêm trường vai trò cho User class User { static constraints = { login(unique:true) password(password:true) name() role(inList:["author", "admin"]) } static hasMany = [entries:Entry] String login String password String name String role = "author" String toString(){ name } } Chú ý giá trị role mặc định gán author Các ràng buộc inList có hộp kết hợp (combo box) với hai lựa chọn Hình cho thấy điều hoạt động: Hình Giới hạn vai trò cho người dùng mới, author admin Tạo admin User tệp grails-app/conf/BootStrap.groovy, ví dụ 10 Đừng quên thêm author role vào hai Users tồn Ví dụ 10 Thêm admin User import grails.util.GrailsUtil class BootStrap { def init = { servletContext -> switch(GrailsUtil.environment){ case "development": def admin = new User(login:"admin", password:"password", name:"Administrator", role:"admin") admin.save() def jdoe = new User(login:"jdoe", password:"password", name:"John Doe", role:"author") //snip def jsmith = new User(login:"jsmith", password:"wordpass", name:"Jane Smith", role:"author") //snip break case "production": break } } def destroy = { } } Và cuối cùng, thêm đoạn mã ví dụ 11 để giới hạn tất User không hoạt động người có vai trị admin: Ví dụ 11 Giới hạn việc quản lý tài khoản User vai trò admin class UserController { def beforeInterceptor = [action:this.&auth, except:["login", "authenticate", "logout"]] def auth() { if( !(session?.user?.role == "admin") ){ flash.message = "You must be an administrator to perform that task." redirect(action:"login") return false } } //snip } Để kiểm tra việc phân quyền dựa vai trò, đăng nhập vào blog với tên jsmith sau thử vào trang http://localhost:9090/blogito/user/create Bạn bị chuyển sang hình đăng nhập hình 5: Hình Việc chặn truy cập với tài khoản khơng có quyền người quản trị Bây đăng nhập admin Bạn truy xuất đến tất bao đóng Chuyển blog lên mức việc sử dụng trình gắn vào (plug-ins) Các hệ thống xác thực phân quyên "siêu nhỏ" cho ứng dụng blog "siêu nhỏ" có Bạn mở rộng dễ dàng theo hướng Có lẽ bạn thích Users có khả quản lý tài khoản họ tác động vào tài khoản người khác Có thể admins nên quyền sửa đổi tất Entries entry riêng họ Trong trường hợp bạn khơng có nhiều hai cách bố trí dịng lệnh để thêm chức Một lỗi đơn giản thường gặp thiếu khả đáp ứng u cầu Blogito có 200 dịng lệnh — tính lệnh kiểm tra tích hợp kiểm tra đơn vị Gõ grails stats cửa sổ dòng lệnh để xác nhận điều Kết hiển thị ví dụ 12 Nhưng việc thiếu phức tạp Blogito khơng có nghĩa blog không sẵn sàng cho cao điểm Ví dụ 12 Kích thước ứng dụng "siêu nhỏ" $ grails stats + + -+ -+ | Name | Files | LOC | + + -+ -+ | Controllers | 2| | Domain Classes | | Tag Libraries | | Unit Tests 2| 2| | | Integration Tests 95 | 5| | 1| 32 | 21 | 20 | 10 | + + -+ -+ | Totals | 12 | 178 | + + -+ -+ Ngay từ viết loạt viết này, mục đích tơi cho bạn thấy sức mạnh vốn có lõi Grails biểu diễn ngắn gọn ngôn ngữ Groovy Chẳng hạn, bạn hiểu mã lệnh Grails, thật dễ dàng để băm mật lưu sở liệu thay hiển thị nguyên dịng chữ (Để biết thêm thơng tin HashCodec, xem Tài nguyên.) Tạo grailsapp/utils/HashCodec.groovy thêm đoạn mã vào ví dụ 13: Ví dụ 13 Việc tạo HashCodec đơn giản import java.security.MessageDigest import sun.misc.BASE64Encoder import sun.misc.CharacterEncoder class HashCodec { static encode = { str -> MessageDigest md = MessageDigest.getInstance('SHA') md.update(str.getBytes('UTF-8')) return (new BASE64Encoder()).encode(md.digest()) } } Với việc đặt lệnh HashCodec chỗ, thay đổi đơn giản việc tham chiếu, từ User.password bao đóng login, save update điều khiển UserController thành User.password.encodeAsHash() Một điều đáng ngạc nhiên với 10 dịng lệnh thơi, bạn nâng ứng dụng lên mức phức tạp Nhưng cần giảm bớt dịng lệnh thơi gây chồng chéo số điểm Trong trường hợp Grails, câu hỏi kinh điển "xây dựng hay mua" chuyển thành "xây dựng hay tải trình gắn vào." Một số trình gắn vào trang http://grails.org/plugin/list#security+tags cố gắng giải thách thức việc thẩm định quyền xác thực theo cách xử lý nhanh grails install-plugin Ví dụ, trình cắm vào Authentication đề xuất vài đặc tính hấp dẫn như: cho phép Users đăng ký tài khoản thay bắt admin tạo tài khoản người ủy quyền Bạn cấu hình trình cắm vào để gửi thơng báo xác thực đến User nói rằng, "Một tài khoản người dùng tạo sử dụng địa thư điện tử Nhấn chuột vào liên kết để xác thực tài khoản bạn." Trình cắm vào OpenID đưa cách tiếp cận khác Thay bắt buộc người dùng cuối tạo tổ hợp tên người dùng mật mà họ chắn bị quên, thẩm định quyền ủy nhiệm cho nhà cung cấp OpenID mà họ chọn Trình cắm vào Lightweight Directory Access (LDAP - Giao thức truy cập thư mục đơn giản) đưa cách tiếp cận tương tự, cho phép ứng dụng Grails thúc đẩy sở hạ tầng LDAP mà bạn có Sự thẩm định quyền trình gắn vào OpenID giới hạn thân vào câu chuyện thẩm định quyền Các giải pháp thẩm định khác đề xuất giải pháp phân quyền Trình cắm vào JSecurity đưa tồn khung làm việc bảo mật vào trình chạy, đề xuất lớp miền soạn sẵn cho Users, Roles, Permissions Trình cắm vào Spring Security thúc đẩy phát triển thư viện Spring Security (trước Acegi Security), cho phép bạn sử dụng lại mã nguồn chương trình tài liệu an ninh Spring Security mà bạn có Như bạn biết, có nhiều chiến lược xác thực phân quyền có sẵn Grails yêu cầu chúng ứng dụng khác nhiều Với bước thực thẩm định quyền khả có thể, độ phức tạp chương trình bạn nâng lên mức phức tạp tương ứng Tôi sử dụng nhiều loại trình gắn vào mà tơi liệt kê ứng dụng mình, sau biết chắn lợi ích thiết thực chiến lược phân quyền thủ cơng đơn giản mà tơi trình bày với bạn đầu viết Kết luận Đến bạn có blog Blogito đảm bảo mặt an ninh Users có hai cách để đăng nhập đăng xuất, đồng thời có tập liên kết thuận tiện để làm việc Cảm ơn bạn tạo LoginTagLib Trong số trường hợp, cần đăng nhập đơn giản vào ứng dụng đảm bảo độ an toàn, biểu thị beforeInterceptor điều khiển EntryController làm nhiệm vụ xác nhận thẩm quyền Trong trường hợp khác, vai trò làm xuất lớp phức tạp khác mẫu biểu thực phân quyền Việc thêm vai trò đơn giản cho User cho phép bạn hạn chế việc quản lý người dùng truy cập vào khu vực quản trị Sau có blog Blogito an tồn rồi, viết Làm chủ Grails tập trung vào nhiệm vụ tới — việc cung cấp cách thức để xác thực người dùng quyền tải tệp cách người sử dụng cuối thuê bao kênh thông tin Atom Với hỗ trợ này, Blogito thực trở thành ứng dụng blog Đến đó, vui với việc làm chủ Grails Mục lục  Việc thẩm định quyền  Việc tạo quyền hạn TagLib  Cơ việc phân quyền  Sự phân quyền mịn  Việc thêm vai trò  Chuyển blog lên mức việc sử dụng trình gắn vào (plug-ins)  Kết luận ... việc làm chủ Grails Mục lục  Việc thẩm định quyền  Việc tạo quyền hạn TagLib  Cơ việc phân quyền  Sự phân quyền mịn  Việc thêm vai trò  Chuyển blog lên mức việc sử dụng trình gắn vào (plug-ins)... trình gắn vào OpenID giới hạn thân vào câu chuyện thẩm định quyền Các giải pháp thẩm định khác đề xuất giải pháp phân quyền Trình cắm vào JSecurity đưa toàn khung làm việc bảo mật vào trình chạy,... cấp cho bạn phương tiện hoàn hảo để thực hoạt động phân quyền trước bao đóng đích gọi Thêm đoạn mã ví dụ vào điều khiển EntryController: Ví dụ Thêm phân quyền vào điều khiển EntryController class

Ngày đăng: 11/05/2021, 02:45