1. 程式人生 > >訪問專案域彈出瀏覽器原生登入框----Spring Security登陸認證 LDAP認證

訪問專案域彈出瀏覽器原生登入框----Spring Security登陸認證 LDAP認證

springSecurity的登入驗證是由org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter這個過濾器來完成的,在該類的父類AbstractAuthenticationProcessingFilter中有一個AuthenticationManager介面屬性,驗證工作主要是通過這個AuthenticationManager介面的例項來完成的。在預設情況下,springSecurity框架會把org.springframework.security.authentication.ProviderManager

類的例項注入到該屬性,

AuthenticationManager介面的相關類圖如下:

UsernamePasswordAuthenticationFilter的驗證過程如下:

1. 首先過濾器會呼叫自身的attemptAuthentication方法,從request中取出authentication, authentication是在org.springframework.security.web.context.SecurityContextPersistenceFilter過濾器中通過捕獲使用者提交的登入表單中的內容生成的一個org.springframework.security.core.Authentication

介面例項.

2. 拿到authentication物件後,過濾器會呼叫ProviderManager類的authenticate方法,並傳入該物件

3.ProviderManager類的authenticate方法再呼叫自身的doAuthentication方法,在doAuthentication方法中會呼叫類中的List<AuthenticationProvider> providers集合中的各個AuthenticationProvider介面實現類中的authenticate(Authentication authentication)方法進行驗證,由此可見,真正的驗證邏輯是由各個各個AuthenticationProvider介面實現類來完成的,DaoAuthenticationProvider類是預設情況下注入的一個AuthenticationProvider介面實現類

4.AuthenticationProvider介面通過UserDetailsService來獲取使用者資訊

以下為時序圖:

spring-security使用者許可權認證框架

 2011-10-19 13:15  

spring中沒有提供預設的許可權管理模組,而是基於Acegi開發了一個spring-security,它是基於spring的使用者許可權認證框架。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" 表示阻止超出的使用者登入。

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還有很多相關的用法,可以檢視 官方的文件


相關推薦

no