spring security 3.0 的 用戶詳細信息的 session 擴展 (基於rapid framework)

applicationContext-security.xml:

 

複製代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:s="http://www.springframework.org/schema/security"
    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.5.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"

    default-autowire
="byType" default-lazy-init="true">

    
<description>使用SpringSecurity的安全配置文件</description>

    
<!-- http安全配置 -->
    
<s:http auto-config="true" access-decision-manager-ref="accessDecisionManager">
        
<s:form-login login-page="/pages/Login/login.do" />
        
<s:logout logout-success-url="/" />
        
<s:remember-me key="ssss" />
    
</s:http>
    <!-- 自定義成功和失敗處理器,AppSessionSuccessHandler中設置了session -->
    
<bean id="appSessionProcessingFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter"> 
        
<s:custom-filter before="AUTHENTICATION_PROCESSING_FILTER" />
        
<property name="authenticationFailureHandler"> 
            
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> 
                
<property name="defaultFailureUrl" value="/pages/Login/login.do?error=true"/> 
            
</bean> 
        
</property> 
        
<property name="authenticationSuccessHandler"> 
            
<bean class="javacommon.base.AppSessionSuccessHandler"> 
                
<property name="defaultTargetUrl" value="/"/> 
            
</bean> 
        
</property>
    
</bean>   

    
<!-- 認證配置 -->
    
<s:authentication-provider user-service-ref="userDetailsService">
        
<!-- 可設置hash使用sha1或md5散列密碼後再存入數據庫 -->
        
<s:password-encoder hash="plaintext" />
    
</s:authentication-provider>

    
<!-- 項目實現的用戶查詢服務 -->
    
<bean id="userDetailsService" class="com.awd.service.UserDetailServiceImpl" />

    
<!-- 重新定義的FilterSecurityInterceptor,使用databaseDefinitionSource提供的url-授權關係定義 -->
    
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        
<s:custom-filter before="FILTER_SECURITY_INTERCEPTOR" />
        
<property name="accessDecisionManager" ref="accessDecisionManager" />
        
<property name="objectDefinitionSource" ref="databaseDefinitionSource" />
    
</bean>

    
<!-- DefinitionSource工廠,使用resourceDetailService提供的URL-授權關係. -->
    
<bean id="databaseDefinitionSource" class="javacommon.base.DefinitionSourceFactoryBean">
        
<property name="resourceDetailService" ref="resourceDetailService" />
    
</bean>
    
    
<!-- 項目實現的URL-授權查詢服務 -->
    
<bean id="resourceDetailService" class="com.awd.service.ResourceDetailServiceImpl" />

    
<!-- 授權判斷配置, 將授權名稱的默認前綴由ROLE_改爲A_. -->
    
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        
<property name="decisionVoters">
            
<list>
                
<bean class="org.springframework.security.access.vote.RoleVoter">
                    
<property name="rolePrefix" value="A_" />
                
</bean>
                
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
            
</list>
        
</property>
    
</bean>
</beans>
複製代碼

 

 

AppSessionSuccessHandler:

 

複製代碼

package javacommon.base;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.util.RedirectUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.awd.dao.UsersDao;
import com.awd.model.Users;

@Transactional(readOnly 
= true)
public class AppSessionSuccessHandler extends
        SavedRequestAwareAuthenticationSuccessHandler {

    @Autowired
    
private UsersDao usersDao;

    
public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            
throws ServletException, IOException {

        SavedRequest savedRequest 
= getSavedRequest(request);

        
if (savedRequest == null) {
            
super.onAuthenticationSuccess(request, response, authentication);

            
return;
        }

        
if (isAlwaysUseDefaultTargetUrl()
                
|| StringUtils.hasText(request
                        .getParameter(getTargetUrlParameter()))) {
            removeSavedRequest(request);
            
super.onAuthenticationSuccess(request, response, authentication);

            
return;
        }

        // 參考Lingo 的Spring security 3.0文檔 附錄 C. Spring Security-3.0.0.M1

        HttpSession session = request.getSession();
        UserDetails userDetails 
= (UserDetails) authentication.getPrincipal();
        Users currentUser 
= usersDao.findByUnique("loginname", userDetails.getUsername().toString());
        session.setAttribute(
"currentUser", currentUser);

        
// Use the SavedRequest URL
        String targetUrl = savedRequest.getFullRequestUrl();
        logger.debug(
"Redirecting to SavedRequest Url: " + targetUrl);
        RedirectUtils.sendRedirect(request, response, targetUrl,
                isUseRelativeContext());

    }

    
private SavedRequest getSavedRequest(HttpServletRequest request) {
        HttpSession session 
= request.getSession(false);

        
if (session != null) {
            
return (SavedRequest) session
                    .getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
        }

        
return null;
    }

    
private void removeSavedRequest(HttpServletRequest request) {
        HttpSession session 
= request.getSession(false);

        
if (session != null) {
            logger.debug(
"Removing SavedRequest from session if present");
            session
                    .removeAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
        }
    }
}

複製代碼

 

 

 

UserDetailServiceImpl.java

 

複製代碼
package com.awd.service;

import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import com.awd.dao.UsersDao;
import com.awd.model.Authorities;
import com.awd.model.Roles;
import com.awd.model.Users;


/**
 * 實現SpringSecurity的UserDetailsService接口,實現獲取用戶Detail信息的回調函�數.
 * 
 * 
@author calvin  edit by meetrice
 
*/
@Transactional(readOnly 
= true)
public class UserDetailServiceImpl implements UserDetailsService {
    
    
    @Autowired
    
private UsersDao usersDao;

    
/**
     * 獲取用戶Detail信息的回調函�數.
     
*/
    
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {

        Users users 
= usersDao.findByUnique("loginname", userName);
        
if (users == null)
            
throw new UsernameNotFoundException("用戶" + userName + " 不存在");

        GrantedAuthority[] grantedAuths 
= obtainGrantedAuthorities(users);
        
// 無以下屬性,暫時全部設爲true.
        boolean enabled = true;
        
boolean accountNonExpired = true;
        
boolean credentialsNonExpired = true;
        
boolean accountNonLocked = true;

        org.springframework.security.core.userdetails.User userdetail 
= new org.springframework.security.core.userdetails.User(
                users.getLoginname(), users.getPassword(), enabled, accountNonExpired, credentialsNonExpired,
                accountNonLocked, grantedAuths);

        
return userdetail;
    }

    
/**
     * 獲得用戶所有角色的權限.
     
*/
    
private GrantedAuthority[] obtainGrantedAuthorities(Users user) {
        Set
<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
        
for (Roles role : user.getRoles()) {
            
for (Authorities authority : role.getAuthorities()) {
                authSet.add(
new GrantedAuthorityImpl(authority.getName()));
            }
        }
        
return authSet.toArray(new GrantedAuthority[authSet.size()]);
    }
}
發佈了3 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章