为什么Spring Security getAuthentication()在服务器上返回null



我有一个web应用程序,并使用spring安全性进行身份验证
所有页面都需要身份验证,但登录页面不需要身份验证
在我的情况下,我在本地环境中登录后成功访问了其他需要身份验证的页面。但我在服务器环境中失败了。因为getAuthentication((返回null

我不知道为什么getAuthentication((在服务器环境中返回null

登录后移动到/foo时(本地日志(

[2021-11-11 15:20:05:32506][http-nio-8080-exec-7] DEBUG org.springframework.security.authentication.dao.DaoAuthenticationProvider.createSuccessAuthentication - Authenticated user
[2021-11-11 15:20:05:32507][http-nio-8080-exec-7] DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.successfulAuthentication - Set SecurityContextHolder to UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@12234790), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[]]
[2021-11-11 15:20:06:33756][http-nio-8080-exec-7] WARN  org.apache.catalina.util.SessionIdGeneratorBase.log - Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [1,246] milliseconds.
[2021-11-11 15:20:06:33760][http-nio-8080-exec-7] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext - Stored SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@12234790), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade@16178716]
[2021-11-11 15:20:06:33760][http-nio-8080-exec-7] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext - Stored SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@12234790), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade@16178716]
[2021-11-11 15:20:06:33760][http-nio-8080-exec-7] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter - Cleared SecurityContextHolder to complete request
--move to foo
[2021-11-11 15:20:06:33769][http-nio-8080-exec-8] DEBUG org.springframework.security.web.FilterChainProxy.doFilterInternal - Securing GET /foo
[2021-11-11 15:20:06:33769][http-nio-8080-exec-8] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository.readSecurityContextFromSession - Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@12234790), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[]]]
[2021-11-11 15:20:06:33769][http-nio-8080-exec-8] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter - Set SecurityContextHolder to SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@12234790), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[]]]
[2021-11-11 15:20:06:33769][http-nio-8080-exec-8] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandler - Mapped to com.bar.view.controller.FooController#initalize()
--success
[2021-11-11 15:20:06:33770][http-nio-8080-exec-8] DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor.beforeInvocation - Authorized filter invocation [GET /foo] with attributes [authenticated]

登录后移动到/foo时(服务器日志(。抱歉,日志上没有方法名称

[2021-11-11 06:17:15:126723][foo] DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Set SecurityContextHolder to UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@708afefc), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=39.110.214.222, SessionId=null], Granted Authorities=[]]
[2021-11-11 06:17:15:126740][foo] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - Stored SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@708afefc), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=39.110.214.222, SessionId=null], Granted Authorities=[]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade@4d6cfed4]
[2021-11-11 06:17:15:126740][foo] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - Stored SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=LoginUser(loginInfo=com.bar.entity.LoginInfoEntity@708afefc), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=39.110.214.222, SessionId=null], Granted Authorities=[]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade@4d6cfed4]
[2021-11-11 06:17:15:126741][foo] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - Cleared SecurityContextHolder to complete request
-- move to foo
[2021-11-11 06:17:15:126766][foo] DEBUG org.springframework.security.web.FilterChainProxy - Securing GET /foo
[2021-11-11 06:17:15:126766][foo] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - Set SecurityContextHolder to empty SecurityContext
[2021-11-11 06:17:15:126766][foo] DEBUG org.springframework.security.web.authentication.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
[2021-11-11 06:17:15:126767][foo] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.bar.view.controller.RobotSelectController#initalize()
-- fail
[2021-11-11 06:17:15:126780][foo] DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Failed to authorize filter invocation [GET /foo] with attributes [authenticated]

我的源代码

我只有Spring Security 的配置和

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/images/**", "/js/**", "/css/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers(loginPage).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage(loginPage)
.loginProcessingUrl(loginSuccessUrl)
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
//add Session
request.getSession().setMaxInactiveInterval(180000);
//move page
response.sendRedirect(fooPage);
}
});
}
}

登录实现UserDetailsService

@Service
public class Login implements UserDetailsService{


private final LoginInfoRepository loginRepo;

@Autowired
public Login(LoginInfoRepository loginRepo) {
this.loginRepo = loginRepo;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LoginInfoEntity entity = loginRepo.findById(username)
.orElseThrow(() -> new UsernameNotFoundException("not exist user"));

UserDetails userDetails = new LoginUser(entity);

return userDetails; 
}

}

login用户使用会话信息

public class LoginUser extends User {
@SuppressWarnings("unchecked")
public LoginUser(LoginInfoEntity loginInfo) {
super(loginInfo.getUserId(), loginInfo.getPassword(), 
loginInfo.isAvailable(), true, true, true, Collections.EMPTY_SET);
}
}

感谢您阅读。

[2021-11-11 06:17:15:126766][foo]调试org.springframework.security.web.authentication.AnonymousAuthenticationFilter-将SecurityContextHolder设置为匿名SecurityContext

这是理解问题的关键一行。当你进行重定向时,你正在重定向用户,是的。但是,他的会话信息(cookie(或其他东西不属于此重定向请求的一部分。

因此,从/foo端点的角度来看,它不会获得任何凭据信息,并且将该请求视为匿名请求。

如果你能去掉这段代码。。。

successHandler(.. do redirect ...)

不要这样重定向,而是这样做,它很可能会解决问题。

通过defaultSuccessUrl重定向

http.formLogin().defaultSuccessUrl("/success.html", true);

这能解决你的问题吗?请在评论中告诉我。

您还可以启用HTTP请求跟踪,并准确地查看哪个请求的标头和有效负载将到达/foo端点,这将使诊断问题变得更容易。

您是否使用Cookie或JWT进行身份验证?请在评论中告诉我。

我解决了这个问题。谢谢Arthur Klezovich原因是contextpath未重定向。我认为本地环境等于服务器环境。但服务器环境有contextpath Bease,因为我没有为contextpath设置。它导致url被卷入contextpath。

例如(

  • 在本地登录后成功获取会话-http://99.99.99/foo

  • 登录服务器后获取会话失败-http://99.99.99/foo(问题网址(

  • 登录服务器后成功获取会话-http://99.99.99/contextpath/foo

有几种方法可以删除contextpath的url。我选择了最简单的方式更改战争名称的文件

foo.war -> root.war

Spring安全性运行良好后,没有修改代码

最新更新