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()]);
    }
}

 

posted @ 2009-08-04 14:20  meetrice  阅读(8930)  评论(3编辑  收藏  举报