spring-security用戶權限認證框架


      大家知道在spring中有一個基於acegi開發的spring-security的權限管理模塊,它是一個輕量級框架。 SpringSecurity能以聲明的方式來保護Web應用程序的URL訪問,只需簡單的配置即可實現。SpringSecurity通過一系列Servlet過濾器為Web應用程序提供了多種安全服務。
      配置spring-security
     在web.xml中添加過濾器:

<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:

<?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-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> 來對密碼加密。這時對應的用戶注冊模塊也要將密碼以加密后的數據保存到數據庫中才行。

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中添加監聽:

<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

spring-security給出了在jsp中使用的接口。用戶登錄可以使用下面的表單:

<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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM