SecurityContextHolderAwareRequestFilter 將 HttpServletRequest 包裝,使 Servlet 標準 API (getRemoteUser、getUserPrincipal、isUserInRole) 直接反映 Acegi SecurityContext 中的認證資訊。
<bean id="securityContextHolderAwareRequestFilter"
class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />
無需額外屬性,直接加入 Filter 鏈即可。
request.getRemoteUser() 取得登入帳號,無需引入 Acegi API,降低耦合。public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequestWrapper {
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
public String getRemoteUser() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return (auth != null) ? auth.getName() : null;
}
public Principal getUserPrincipal() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return (auth != null && authenticationTrustResolver.isAuthenticated(auth)) ? auth : null;
}
public boolean isUserInRole(String role) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) return false;
for (GrantedAuthority ga : auth.getAuthorities()) {
if (ga.getAuthority().equals(role)) return true;
}
return false;
}
}
區分「匿名認證」與「真實認證」:isAuthenticated() 排除 AnonymousAuthenticationToken 與 RememberMeAuthenticationToken(視策略而定),確保 getUserPrincipal() 僅在真實登入時返回非 null。
SecurityContextHolderAwareRequestFilter → 讓 Request 感知 (Aware) SecurityContextHolder 中的內容,透過覆寫三大方法實現。
子類新增 SavedRequest 支援,實現「登入前保存目標 URL,登入後自動導向」,詳見後續文章。