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