这是我在Spring日志中的消息:
[DEBUG] 2016-04-22 10:39:19,469 [] [-254028363] org.springframework.security.web.access.intercept.FilterSecurityInterceptor authenticateIfRequired - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@6faa3d44: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff4c9c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: F5BF9CC6CFE7D2C98A0CB043F4D5C10F; Granted Authorities: ROLE_ANONYMOUS
org.springframework.security.web.access.intercept.FilterSecurityInterceptor
authenticateIfRequired - Previously Authenticated
org.springframework.security.authentication.AnonymousAuthenticationToken@6faa3d44:
Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true;
Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff4c9c:
RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: F5BF9CC6CFE7D2C98A0CB043F4D5C10F;
Granted Authorities: ROLE_ANONYMOUS
考虑到org.springframework.security.access.intercept.AbstractSecurityInterceptor.class的" authenticateIfRequired()" 方法的实现:
/**
* Checks the current authentication token and passes it to the AuthenticationManager
* if {@link org.springframework.security.core.Authentication#isAuthenticated()}
* returns false or the property <tt>alwaysReauthenticate</tt> has been set to true.
*
* @return an authenticated <tt>Authentication</tt> object.
*/
private Authentication authenticateIfRequired() {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (authentication.isAuthenticated() && !alwaysReauthenticate) {
if (logger.isDebugEnabled()) {
logger.debug("Previously Authenticated: " + authentication);
}
return authentication;
}
authentication = authenticationManager.authenticate(authentication);
// We don't authenticated.setAuthentication(true), because each provider should do
// that
if (logger.isDebugEnabled()) {
logger.debug("Successfully Authenticated: " + authentication);
}
SecurityContextHolder.getContext().setAuthentication(authentication);
return authentication;
}
这种情况的结果是&#39; anonymousUser&#39;从未经过身份验证。
我从来没有在Spring日志中看到&#34;成功通过身份验证:&#34; 以及<#39; anonymousUser&#39; 。
此外, SecurityContextHolder 将不包含任何身份验证对象,因为从不执行此行代码:
SecurityContextHolder.getContext().setAuthentication(authentication);
实际上,如果我执行SecurityContextHolder.getContext()。getAuthentication(),我有一个null对象作为返回。
此行为与文档中的内容不匹配:
http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#anonymous-overview
这就是匿名身份验证的含义。请注意有 匿名的用户之间没有真正的概念差异 认证&#34;和一个未经身份验证的用户。 Spring Security的 匿名身份验证只是为您提供了一种更方便的方法 配置访问控制属性。调用servlet API调用 例如,getCallerPrincipal仍然会返回null 虽然实际上有一个匿名身份验证对象 SecurityContextHolder中。
还有其他匿名情况 身份验证很有用,例如审计拦截器查询时 SecurityContextHolder用于标识哪个主体 负责给定的操作。可以更多地编写类 如果他们知道 SecurityContextHolder总是包含一个 身份验证对象,永不为空。
为什么会这样? 就我而言,身份验证对象永远不会为空。
这是我的Java配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
public class SecurityContextConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/index.html","/myApp/pages/**").permitAll().and()
.authorizeRequests().anyRequest().authenticated().and()
.httpBasic().and()
.csrf().csrfTokenRepository(csrfTokenRepository()).and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll().logoutSuccessUrl("/index.html");
}
// ...
}
有什么想法吗? 谢谢!
修改
这是方法调用的完整堆栈&#34; authenticateIfRequired()&#34;:
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.authenticateIfRequired(AbstractSecurityInterceptor.java:345)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:228)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at myApp.security.config.SecurityContextConfig$1.doFilterInternal(SecurityContextConfig.java:150)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at myApp.filter.RequestFilter.doFilter(RequestFilter.java:21)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
这是我目前的实施:
public class MyDaoAuthenticationProvider extends DaoAuthenticationProvider {
@Autowired
AuthenticationHandler authenticationHandler;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Authentication authenticated = null;
try {
authenticated = super.authenticate(authentication);
} catch (Exception e) {
e.printStackTrace();
authenticationHandler.handleFailedAuthentication(authentication.getName());
throw e;
}
// this works
SecurityContextHolder.getContext().setAuthentication(authentication);
authenticationHandler.handleSuccessAuthentication(authentication.getName());
return authenticated;
}
}
当我需要当前用户的通知时,在@MappedSuperclass中调用SecurityContextHolder.getContext()。getAuthentication()。
public abstract class TableObject implements Serializable {
@PreUpdate
protected void onUpdate() {
userModifier = SecurityContextHolder.getContext().getAuthentication().getName();
// this don't work
}
}