我比上次更深入地检查了该主题,发现您必须确定用户是否在控制器中由您自己进行身份验证。行绞盘(Spring Security 开发)在这里说 http://forum.springsource.org/showthread.php?119015-Login-page-is-not-redirecting-for-logged-user:
Spring Security 不知道应用程序的内部结构
(即,如果您想让您的登录页面根据用户是否
是否已登录)。登录页面时显示您的主页
请求并且用户已登录使用SecurityContextHolder
在
登录页面(或其控制器)并将用户重定向或转发到
主页。
所以解决方案是确定用户是否请求/auth/login
是否匿名,如下所示。
applicationContext-security.xml:
<http auto-config="true" use-expressions="true"
access-decision-manager-ref="accessDecisionManager">
<intercept-url pattern="/auth/login" access="permitAll" />
<intercept-url pattern="/auth/logout" access="permitAll" />
<intercept-url pattern="/admin/**" access="ADMINISTRATIVE_ACCESS" />
<intercept-url pattern="/**" access="XYZ_ACCESS" />
<form-login login-page="/auth/login"
authentication-failure-url="/auth/loginFailed"
authentication-success-handler-ref="authenticationSuccessHandler" />
<logout logout-url="/auth/logout" logout-success-url="/auth/login" />
</http>
<beans:bean id="defaultTargetUrl" class="java.lang.String">
<beans:constructor-arg value="/content" />
</beans:bean>
<beans:bean id="authenticationTrustResolver"
class="org.springframework.security.authentication.AuthenticationTrustResolverImpl" />
<beans:bean id="authenticationSuccessHandler"
class="com.example.spring.security.MyAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" ref="defaultTargetUrl" />
</beans:bean>
Add to 应用程序上下文.xml豆定义:
<bean id="securityContextAccessor"
class="com.example.spring.security.SecurityContextAccessorImpl" />
这是类
public final class SecurityContextAccessorImpl
implements SecurityContextAccessor {
@Autowired
private AuthenticationTrustResolver authenticationTrustResolver;
@Override
public boolean isCurrentAuthenticationAnonymous() {
final Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
return authenticationTrustResolver.isAnonymous(authentication);
}
}
实现简单的接口
public interface SecurityContextAccessor {
boolean isCurrentAuthenticationAnonymous();
}
(SecurityContextHolder访问代码与控制器分离,我遵循了这个答案的建议 https://stackoverflow.com/a/8765597/708434, hence SecurityContextAccessor
界面。)
最后但并非最不重要的一点是控制器中的重定向逻辑:
@Controller
@RequestMapping("/auth")
public class AuthController {
@Autowired
SecurityContextAccessor securityContextAccessor;
@Autowired
@Qualifier("defaultTargetUrl")
private String defaultTargetUrl;
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {
if (securityContextAccessor.isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:" + defaultTargetUrl;
}
}
}
定义defaultTargetUrl
String bean 看起来像是一个 hack,但我没有更好的方法不硬编码 url...(实际上在我们的项目中我们使用<util:constant> http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#xsd-config-body-schemas-util-constant包含静态最终字符串字段的类。)但它毕竟有效。