我有一個 Web 應用程式并使用 Spring Security 進行身份驗證。
所有頁面都需要身份驗證,但登錄頁面不需要身份驗證。
在我的情況下,我在本地環境登錄后成功訪問了其他需要身份驗證的頁面。但是我在服務器環境上失敗了。因為 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]
我的源代碼
我只有 Config 和 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);
}
});
}
}
登錄實作 UserDetailsS??ervice
@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;
}
}
loginUser 用于會話資訊
public class LoginUser extends User {
@SuppressWarnings("unchecked")
public LoginUser(LoginInfoEntity loginInfo) {
super(loginInfo.getUserId(), loginInfo.getPassword(),
loginInfo.isAvailable(), true, true, true, Collections.EMPTY_SET);
}
}
感謝您閱讀。
uj5u.com熱心網友回復:
[2021-11-11 06:17:15:126766][foo] DEBUG org.springframework.security.web.authentication.AnonymousAuthenticationFilter - 將 SecurityContextHolder 設定為匿名 SecurityContext
這是理解問題的關鍵。當您進行重定向時,您正在重定向用戶,是的。然而,他的會話資訊 (cookie) 或其他一些東西不是這個重定向請求的一部分。
因此,從/foo端點的角度來看,它不會獲得任何憑證資訊并將請求視為匿名。
如果你能擺脫這段代碼......
successHandler(.. do redirect ...)
并且不要像這樣執行重定向,而是像這樣執行重定向,它可能會解決問題。
重定向通過 defaultSuccessUrl
http.formLogin().defaultSuccessUrl("/success.html", true);
這能解決您的問題嗎?在評論中告訴我。
您還可以啟用 HTTP 請求跟蹤并準確查看哪些請求以及哪些標頭和有效負載到達/foo端點,這將使診斷問題變得更加容易。
您是使用 cookie 還是 JWT 進行身份驗證?在評論中告訴我。
uj5u.com熱心網友回復:
我解決了這個問題。謝謝亞瑟·克萊佐維奇。原因是背景關系路徑未重定向。我認為本地環境等于服務器環境。但是服務器環境有背景關系路徑,因為我沒有設定背景關系路徑。它導致 url 涉及背景關系路徑。
例如)
在本地登錄后成功獲取會話 - http://99.99.99/foo
登錄服務器后無法獲取會話 - http://99.99.99/foo(問題的網址)
登錄服務器后成功獲取會話 -http://99.99.99/contextpath/foo
有幾種方法可以洗掉背景關系路徑的 url。我選擇了最簡單的方式更改戰爭名稱檔案
foo.war -> root.war
Spring-security 運行良好后,無需修改代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/357713.html
