我通过审查我的安全设计并寻求更接近 Spring Security 已经提供的预身份验证机制来解决我的问题。
我扩展了 Spring Security 的 2 个组件。第一个是AbstractPreAuthenticatedProcessingFilter,通常他的作用是提供headers中提供的principal。就我而言,我检索标头值并在 2 个应用程序之间共享的上下文中搜索与该标头对应的属性并将其作为主体返回:
public class MyApplicationPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {
private static final Logger logger = Logger.getLogger(MyApplicationPreAuthenticatedProcessingFilter.class);
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
if (MyApplicationServerUtil.isProdMode()) {
String principal = request.getHeader("MY_HEADER");
String attribute = (String) request.getSession().getServletContext().getContext("/crosscontext").getAttribute(principal);
logger.info("In PROD mode - Found value in crosscontext: " + attribute);
return attribute;
} else {
logger.debug("In DEV mode - passing through ...");
return "";
}
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return null;
}
}
另一个组件是 AuthenticationProvider ,当它以 prod 模式 (GWT prod) 运行时,它将检查身份验证是否包含主体:
public class MyApplicationAuthenticationProvider implements AuthenticationProvider {
private static final Logger logger = Logger.getLogger(MyApplicationAuthenticationProvider.class);
public static final String SESSION_ID = "sessionId";
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (MyApplicationServerUtil.isProdMode()) {
if (StringUtils.isNotEmpty((String) authentication.getPrincipal())) {
logger.warn("Found credentials: " + (String) authentication.getPrincipal());
Authentication customAuth = new CustomAuthentication("ROLE_USER");
customAuth.setAuthenticated(true);
return customAuth;
} else {
throw new PreAuthenticatedCredentialsNotFoundException("Nothing returned from crosscontext for sessionId attribute ["
+ (String) authentication.getPrincipal() + "]");
}
} else {
Authentication customAuth = new CustomAuthentication("ROLE_USER");
customAuth.setAuthenticated(true);
return customAuth;
}
}
@Override
public boolean supports(Class<?> authentication) {
return PreAuthenticatedAuthenticationToken.class.isAssignableFrom(authentication);
}
}
我知道它可能不是最安全的应用程序。但是,它已经在一个安全的环境中运行。但是,如果您有改进的建议,欢迎他们!