java spring security詳解


spring security文檔介紹 
http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/index-all.html#_D_ 

自己寫的一個demo,用來介紹security

1,UserDetails 

//返回驗證用戶密碼,無法返回則NULL
String getPassword();
String getUsername();
//賬戶是否過期,過期無法驗證
boolean isAccountNonExpired();
//指定用戶是否被鎖定或者解鎖,鎖定的用戶無法進行身份驗證
boolean isAccountNonLocked();
//指示是否已過期的用戶的憑據(密碼),過期的憑據防止認證
boolean isCredentialsNonExpired();
//是否被禁用,禁用的用戶不能身份驗證
boolean isEnabled();

UserDetails讓User對象去實現,屬性字段設計階段就把字段跟接口字段對應!! 

2.UserDetailsService 

 

UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException, DataAccessException;

這里這個方法是當用戶登錄ok,通過之后會緩存起來,可以通過用戶名從緩存中讀取. 

UserDaoImpl可以去實現. 

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List users = getHibernateTemplate().find("from User where username=?", username);
        if (users == null || users.isEmpty()) {
            throw new UsernameNotFoundException("user '" + username + "' not found...");
        } else {
            return (UserDetails) users.get(0);
        }
    }

下邊這個跟常用的session一樣,也是從緩存中讀取! 
這里要特別注意,應用是這樣!但是框架的流程則復雜很多. 


3.SessionUtils 

public class SessionUtil {
    public static User getCurrentUser() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User currentUser;
        if (auth.getPrincipal() instanceof UserDetails) {
            currentUser = (User) auth.getPrincipal();
        } else if (auth.getDetails() instanceof UserDetails) {
            currentUser = (User) auth.getDetails();
        } else {
            throw new AccessDeniedException("User not properly authenticated.");
        }
        return currentUser;
    }
}

4.web.xml中配置 
個人喜歡把security的東西新建一個xml,在web中啟動自己的security.xml(當然放在web-inf下比較好) 

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
       /WEB-INF/security.xml
    </param-value>
</context-param>

 

dfp代理過濾Filter,在初始化的時候springSecurityFilterChain這個有注意到了嗎? 

<!-- 所有的Filter委托給Spring -->
<!-- 第一種,可以自定義過濾器 -->
<filter>
  <filter-name>securityFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
     <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>springSecurityFilterChain</param-value>
     </init-param>
</filter>
<filter-mapping>
     <filter-name>securityFilter</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 第二種配置 -->
<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>

在這里要特別注意:springSecurityFilterChain這個名稱是命名空間默認創建的,用於處理Web安全的一個內部Bean的Id 
★在自定義Bean時不可以在用這個Id名稱,不然會沖突異常! 
5.security.xml 

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             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.1.xsd">
    <!-- 還記得前面的代理嗎,這里注明后!代理會自動生成 -->
    <http auto-config="true" lowercase-comparisons="false">
        <!--intercept-url pattern="/images/*" filters="none"/>
        <intercept-url pattern="/styles/*" filters="none"/>
        <intercept-url pattern="/scripts/*" filters="none"/--> 
        <intercept-url pattern="/admin/*" access="ROLE_ADMIN"/>
        <intercept-url pattern="/cpManagerPages/*" access="ROLE_ADMIN,ROLE_CONTENT_PROVIDER"/>
        <intercept-url pattern="/**/*.ca*" access="ROLE_CONTENT_PROVIDER,ROLE_ADMIN,ROLE_USER"/>
        <!-- 這里/j_security_check是表單提交位置 -->
        <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" login-processing-url="/j_security_check"/>
        <remember-me user-service-ref="userDao" key="e37f4b31-0c45-11dd-bd0b-0800200c9a66"/>
    </http>
    <!--① 驗證過程是由userDao,也就是連接數據庫驗證 -->
    <authentication-provider user-service-ref="userDao">
        <password-encoder ref="passwordEncoder"/>
    </authentication-provider>
    <!--② 這個跟1不同,這里是根據自定義的用戶來驗證 -->
    <authentication-provider>
        <user-service>
          <user name="sp" password="123" authorities="ROLE_SP" />
          <user name="admin" password="123" authorities="ROLE_CARRIER" />
          <user name="cp" password="123" authorities="ROLE_CP" />
        </user-service>
    </authentication-provider>
    <!-- Override the default password-encoder (SHA) by uncommenting the following and changing the class -->
    <!-- <bean id="passwordEncoder" class="org.springframework.security.providers.encoding.ShaPasswordEncoder"/> -->
    <!-- 限制對方法的訪問 @Secured JSR-250注解 -->
    <global-method-security>
        <protect-pointcut expression="execution(* *..service.UserManager.getUsers(..))" access="ROLE_ADMIN"/>
        <protect-pointcut expression="execution(* *..service.UserManager.removeUser(..))" access="ROLE_ADMIN"/>
    </global-method-security>
</beans:beans>

在配置intercept-url,最先驗證的是第一個intercept-url,隊列形式! 


下邊這些是標簽屬性說明: 
配置說明: 
  lowercase-comparisons:表示URL比較前先轉為小寫。 
  path-type:表示使用Apache Ant的匹配模式。 
  access-denied-page:訪問拒絕時轉向的頁面。 
  access-decision-manager-ref:指定了自定義的訪問策略管理器。當系統角色名的前綴不是默認的ROLE_時,需要自定義訪問策略管理器。 
  login-page:指定登錄頁面。 
  login-processing-url:指定了客戶在登錄頁面中按下 Sign In 按鈕時要訪問的 URL。與登錄頁面form的action一致。其默認值為:/j_spring_security_check。 
  authentication-failure-url:指定了身份驗證失敗時跳轉到的頁面。 
  default-target-url:指定了成功進行身份驗證和授權后默認呈現給用戶的頁面。 
  always-use-default-target:指定了是否在身份驗證通過后總是跳轉到default-target-url屬性指定的URL。 
  logout-url:指定了用於響應退出系統請求的URL。其默認值為:/j_spring_security_logout。 
  logout-success-url:退出系統后轉向的URL。 
  invalidate-session:指定在退出系統時是否要銷毀Session。 
  max-sessions:允許用戶帳號登錄的次數。范例限制用戶只能登錄一次。 
  exception-if-maximum-exceeded: 默認為false,此值表示:用戶第二次登錄時,前一次的登錄信息都被清空。 
  當exception-if-maximum-exceeded="true"時系統會拒絕第二次登錄。


免責聲明!

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



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