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

轉載自 http://www.cnblogs.com/meetrice/archive/2009/08/04/1538441.html
發佈了34 篇原創文章 · 獲贊 2 · 訪問量 1601
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章