集成ACEGI 进行权限控制
生活随笔
收集整理的這篇文章主要介紹了
集成ACEGI 进行权限控制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一. 簡單介紹
?1.1 本文目的
集成Acegi到自己的項目中, 并且將用戶信息和權限放到數據庫, 提供方法允許權限動態變化,變化后自動加載最新的權限 本文介紹Acegi例子的時候采用的是acegi-security-samples-tutorial-1.0.6.war 閱讀本文需要對Spring有一定的了解, 如果你還沒有接觸過, 有些地方可能不容易理解, 這時候可能需要參考本文后附的Spring地址, 先了解一下Spring的基本知識. 本文使用的是Mysql數據庫, 如果你使用其他的數據庫, 可能需要修改相應的SQL.1.2 安裝與配置
項目主頁: [url]http://www.acegisecurity.org/[/url] 下載地址: [url]http://sourceforge.net/project/showfiles.php?group_id=104215[/url] 解壓文件后, 將acegi-security-samples-tutorial-1.0.6.war復制Your_Tomcat_Path/webapps/ 啟動Tomcat, 訪問[url]http://localhost:8080/acegi-security-samples-tutorial-1.0.6/[/url] 點擊頁面上任何一個鏈接,都需要用戶登錄后訪問, 可以在頁面上看到可用的用戶名和密碼.二. 開始集成到自己的程序中
2.1 將用戶和角色放在數據庫中
可能是為了演示方便, 簡單的展示Acegi如何控制權限, 而不依賴于任何數據庫, ACEGI給出的例子采用InMemoryDaoImpl獲取用戶信息, 用戶和角色信息放在WEB-INF/users.properties 文件中, InMemoryDaoImpl 一次性的從該配置文件中讀出用戶和角色信息, 格式是: 用戶名=密碼, 角色名, 如第一行是: marissa=koala,ROLE_SUPERVISOR 就是說marissa的密碼是koala, 并且他的角色是ROLE_SUPERVISOR 對這個文件的解析是通過applicationContext-acegi-security.xml中如下的設置進行的: ?1?<!--?UserDetailsService?is?the?most?commonly?frequently???? Acegi?Security?interface?implemented?by?end?users?-->
?2?<bean?id="userDetailsService"
?3?class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
?4?<property?name="userProperties">
?5?<bean
?6?class="org.springframework.beans.factory.config.PropertiesFactoryBean">
?7?<property?name="location"
?8?value="classpath:sers.properties"?/>
?9?</bean>
10?</property>
11?</bean>
12?
13?
除了InMemoryDaoImpl之外, ACEGI還提供了Jdbc和 ldap的支持, 由于使用數據庫進行驗證比較常見, 下面僅就jdbc實現做出介紹. 不管是InMemoryDaoImpl還是JdbcDaoImpl都是實現了UserDetailsService接口, 而這個接口里只定義了一個方法: UserDetails loadUserByUsername(String username) 就是根據用戶名加載UserDetails對象, UserDetails也是一個接口, 定義了一個用戶所需要的基本信息, 包括: username, password, authorities等信息
2.1.1 直接使用JdbcDaoImpl 訪問數據庫中的用戶信息
如果ACEGI提供的信息滿足你的需要, 也就是說你只需要用戶的username, password等信息, 你可以直接使用ACEGI提供的Schema, 這樣, 不需要任何變動, JdbcDaoImpl就可以使用了. 如果你的數據庫已經定義好了, 或者不想使用ACEGI提供的Schema,那么你也可以自定義JdbcDaoImpl的查詢語句 ?1?????????<property?name="usersByUsernameQuery">?2?<value>
?3?SELECT?email,?password,?enabled?from?user?u?where?email?=??
?4?</value>
?5?</property>
?6?<property?name="authoritiesByUsernameQuery">
?7?<value>
?8?SELECT?u.email,?r.role_name?FROM?user_role?ur,?user?u,?role?r?WHERE
?9?ur.user_id?=?u.user_id?and?ur.role_id?=?r.role_id?and?u.email?=??
10?</value>
11?</property>
2.1.2 擴展JdbcDaoImpl獲取更多用戶信息
如果上面提到的定制查詢SQL語句不能提供足夠的靈活性, 那么你可能就需要定義一個JdbcDaoImpl的子類, 如果變動不大, 通過覆蓋initMappingSqlQueries方法重新定義MappingSqlQuery的實例. 而如果你需要獲取更多信息, 比如userId, companyId等, 那就需要做更多的改動, 第一種改動不大, 所以不具體介紹, 下面以第二種改動為例,介紹如何實現這種需求. 我們需要三張表User, Role, User_Role, 具體的SQL如下: ?1?1?#?2??2?#?Structure?for?the?`role`?table?:
?3??3?#
?4??4?DROP?TABLE?IF?EXISTS?`role`;
?5??5?CREATE?TABLE?`role`?(
?6??6?`role_id`?int(11)?NOT?NULL?auto_increment,
?7??7?`role_name`?varchar(50)?default?NULL,
?8??8?`description`?varchar(20)?default?NULL,
?9??9?`enabled`?tinyint(1)?NOT?NULL?default?'1',
10?10?PRIMARY?KEY??(`role_id`)
11?11?);
12?12?#
13?13?#?Structure?for?the?`user`?table?:
14?14?#
15?15?DROP?TABLE?IF?EXISTS?`user`;
16?16?CREATE?TABLE?`user`?(
17?17?`user_id`?int(11)?NOT?NULL?auto_increment,
18?18?`company_id`?int(11)?default?NULL,
19?19?`email`?varchar(200)?default?NULL,
20?20?`password`?varchar(10)?default?NULL,
21?21?`enabled`?tinyint(1)?default?NULL,
22?22?PRIMARY?KEY??(`user_id`)
23?23?);
24?24?#
25?25?#?Structure?for?the?`user_role`?table?:
26?26?#
27?27?DROP?TABLE?IF?EXISTS?`user_role`;
28?28?CREATE?TABLE?`user_role`?(
29?29?`user_role_id`?int(11)?NOT?NULL?auto_increment,
30?30?`user_id`?varchar(50)?NOT?NULL,
31?31?`role_id`?int(11)?NOT?NULL,
32?32?PRIMARY?KEY??(`user_role_id`)
33?33?); 前面講過, UserDetailsService接口中只定義了一個方法: UserDetails loadUserByUsername(String username), UserDetails中不存在我們需要的userId 和companyId等信息, 所以我們首先需要擴展UserDetails接口, 并擴展org.acegisecurity.userdetails.User: IUserDetails.java
UserDetailsImpl.java ?1?package?org.security;
?2?import?org.acegisecurity.GrantedAuthority;
?3?import?org.acegisecurity.userdetails.User;
?4?/**
?5??*?The?class?<code>UserDetailsImpl</code>?extends?the
? ? * org.acegisecurity.userdetails.User?class,?and?provides
??? * additional?userId,?companyId?information
?6??*?@author?wade
?7??*?
?8??*?@see?IUserDetails,?User
?9??*/
10?public?class?UserDetailsImpl?extends?User?implements?IUserDetails{
11?private?int?user_id;
12?private?int?company_id;
13?private?String?username;
14?private?GrantedAuthority[]?authorities;
15?public?UserDetailsImpl(String?username,?String?password,?boolean?enabled,
16?boolean?accountNonExpired,?boolean?credentialsNonExpired,
17?boolean?accountNonLocked,?GrantedAuthority[]?authorities)
18?throws?IllegalArgumentException?{
19?super(username,?password,?enabled,?accountNonExpired,?credentialsNonExpired,
20?accountNonLocked,?authorities);
21?setUsername(username);
22?setAuthorities(authorities);
23?}
24?public?UserDetailsImpl(int?userid,?int?companyid,?String?username,
??? ??? ??? ??? ??? ??? ??? ??? ??? ??? String?password,?boolean?enabled,
25?boolean?accountNonExpired,?boolean?credentialsNonExpired,
26?boolean?accountNonLocked,?GrantedAuthority[]?authorities)
27?throws?IllegalArgumentException?{
28?super(username,?password,?enabled,?accountNonExpired,?credentialsNonExpired,
29?accountNonLocked,?authorities);
30?this.user_id?=?userid;
31?this.company_id?=?companyid;
32?setUsername(username);
33?setAuthorities(authorities);
34?}
35?public?int?getUserId()?{
36?return?user_id;
37?}
38?public?void?setUserId(int?user_id)?{
39?this.user_id?=?user_id;
40?}
41?public?int?getCompanyId()?{
42?return?company_id;
43?}
44?public?void?setCompanyId(int?company_id)?{
45?this.company_id?=?company_id;
46?}
47?public?String?getUsername()?{
48?return?username;
49?}
50?public?void?setUsername(String?username)?{
51?this.username?=?username;
52?}
53?public?GrantedAuthority[]?getAuthorities()?{
54?return?authorities;
55?}
56?public?void?setAuthorities(GrantedAuthority[]?authorities)?{
57?this.authorities?=?authorities;
58?}
59?}
到此為止, 我們已經準備好了存放用戶信息的類, 下面就開始動手修改取用戶數據的代碼. 假設我們用下面的SQL取用戶信息: SELECT u.user_id, u.company_id, email, password, enabled
FROM role r, user_role ur, user u
WHERE r.role_id = ur.role_id
and ur.user_id = u.user_id
and email = ?
limit 1 用下面的SQL取用戶具有的Role列表 SELECT u.email, r.role_name
FROM user_role ur, user u, role r
WHERE ur.user_id = u.user_id
and ur.role_id = r.role_id
and u.email = ?
我們需要修改的主要是兩部分: 1. 取用戶和用戶角色的MappingSqlQuery, 增加了查詢的userId和companyId. 2. loadUserByUsername方法, 修改了返回的對象類型,和很少的內部代碼.
轉載于:https://blog.51cto.com/77857/150344
總結
以上是生活随笔為你收集整理的集成ACEGI 进行权限控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IE工具条不能自动显示
- 下一篇: 站长站收集