你們知道在spring中有一個基於acegi開發的spring-security的權限管理模塊,它是一個輕量級框架。 SpringSecurity能以聲明的方式來保護Web應用程序的URL訪問,只需簡單的配置便可實現。SpringSecurity經過一系列Servlet過濾器爲Web應用程序提供了多種安全服務。
配置spring-security
在web.xml中添加過濾器:html
<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
而後在<classpath>路徑下建立配置文件PROJECT-security.xml:web
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd"> <http auto-config="true" access-denied-page="/access_denied.jsp"> <intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> <intercept-url pattern="/user/**" access="ROLE_USER" /> <form-login login-page="/login.htm" authentication-failure-url="/login.htm?error=1" default-target-url="/" /> <remember-me data-source-ref="dataSource" /> <logout invalidate-session="true" logout-success-url="/" /> <!-- Uncomment to enable X509 client authentication support <x509 /> --> </http> <authentication-provider> <!-- <password-encoder hash="md5" /> --> <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select account as username, password, status as enabled from user where account=?" authorities-by-username-query="select account as username, authority from user where account=?" /> </authentication-provider> </beans:beans>
同時將該配置文件加到web.xml的 <context-param> 裏。spring
spring-security中使用角色來分類管理用戶權限,如上面的配置中就包含了ROLE_ADMIN和ROLE_USER兩個角色,並分別有/admin/和/user/的URL路徑下的權限。數據庫
用戶的賬號密碼有幾種不一樣的方式保存,包括xml中、LDAP和數據庫中等。上面使用的是保存到數據庫中的方式,使用了以前在applicationContext.xml中配置的dataSource bean。使用數據庫保存賬號時,須要按照spring-security規定的字段來建表,有兩個相關的表,分別用於保存賬號密碼和登陸狀態。使用MySQL能夠這樣建立:安全
CREATE TABLE `user` ( `account` varchar(50) NOT NULL, `password` varchar(50) NOT NULL, `authority` varchar(50) NOT NULL, `status` tinyint(1) NOT NULL, UNIQUE KEY `account` (`account`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `persistent_logins` ( `username` varchar(64) NOT NULL, `series` varchar(64) NOT NULL, `token` varchar(64) NOT NULL, `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`series`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
默認spring-security中採用明文方式存儲密碼,能夠經過設置 <password-encoder> 來對密碼加密。這時對應的用戶註冊模塊也要將密碼以加密後的數據保存到數據庫中才行。session
import org.springframework.security.providers.encoding.Md5PasswordEncoder; import org.springframework.security.providers.encoding.PasswordEncoder; PasswordEncoder encoder = new Md5PasswordEncoder(); String password = encoder.encodePassword(form.getPassword(), null);
能夠經過會話控制來防止用戶重複登陸,這能夠經過配置來實現。首先在web.xml中添加監聽:app
<listener> <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class> </listener>
而後在PROJECT-security.xml配置文件中的 <http></http> 內添加:框架
<concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true" />
max-sessions="1" 表示該用戶同時登陸的最大會話數爲1, exception-if-maximum-exceeded="true" 表示阻止超出的用戶登陸。jsp
spring-security給出了在jsp中使用的接口。用戶登陸能夠使用下面的表單:ide
<form name='f' action='/PROJECT/j_spring_security_check' method='POST'> <table> <tr><td>用戶名:</td><td><input type='text' name='j_username' value=''></td></tr> <tr><td>密碼:</td><td><input type='password' name='j_password'/></td></tr> <tr><td></td><td><input type='checkbox' name='_spring_security_remember_me'/> 自動登陸</td></tr> <tr><td colspan='2' align="right"><input name="reset" id="reset" type="reset" value="重置" /> <input name="submit" id="submit" type="submit" value="登陸" /></td></tr> </table> </form>
根據登陸用戶進行條件判斷能夠使用下面的方式:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <sec:authorize ifAllGranted="ROLE_ANONYMOUS"> <!-- ... --> </sec:authorize> <sec:authorize ifAllGranted="ROLE_USER"> <!-- ... --> </sec:authorize>
在特定jsp頁面獲取登陸用戶的賬號的方法是:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <input name="customer" type="hidden" value="<sec:authentication property='principal.username' />" />
另外, Spring Security 還提供了以下一些功能:
1. remember me ,記住我;
2. form-login 登陸控制;
3. 多種身份認證功能;
4. 用戶密碼加密和「 salt 」功能;
5. http 協議控制;
6. 訪問端口控制;
7. Pre-Invocation & After-Invocation 。
spring-security還有不少相關的用法,能夠查看 官方的文檔 。 http://www.yeolar.com/note/2011/10/19/spring-security/