我已經實現了具有用於登錄/註銷的REST通道的單面應用程序。我已經開始使用JWT,但我想轉向基於會話的通信。我目前是春天的XML配置:由REST服務創建的彈簧安全令牌未保存在會話中
<http pattern="/spring/login" security="none" create-session="always" />
<http pattern="/spring/logout" security="none" create-session="never" />
<http pattern="/spring/**" entry-point-ref="restAuthenticationEntryPoint"
create-session="always">
<csrf disabled="true" />
<custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter" />
</http>
現在,jwtAuthenticationFilter
被修改,使得它不記錄如果驗證是否存在,如果不是,它是從頭部解析:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// skip if authorization already exists
Authentication sessionAuth = SecurityContextHolder.getContext().getAuthentication();
if (sessionAuth != null) {
LOGGER.info("Already authenticated as {}", sessionAuth.getPrincipal());
chain.doFilter(request, response);
return;
}
LOGGER.info("Try to authorize");
的/春天/ login方法創建令牌,並試圖把它變成安全上下文:
SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS512), claimsSet);
try {
signedJWT.sign(signer);
String token = "Bearer " + signedJWT.serialize();
response.setToken(token);
Authentication auth = authenticationManager.authenticate(new JWTToken(signedJWT));
SecurityContextHolder.getContext().setAuthentication(auth);
} catch(JOSEException | ParseException e) {
我期待什麼,是該令牌將出現在接下來的安全上下文REST呼叫。但是,日誌表明,通過下一個請求,令牌不在安全上下文中,它被創建並通過servlet過濾器放到那裏,然後它就會出現在後續請求中。
我在這裏做錯了什麼?我期望,如果我要求在/ spring/login調用上創建會話,Authentication
放入SecurityContext
也會在會話中保留。這顯然不是這種情況。爲了讓Spring Security保留REST調用中存儲的令牌,我需要做些什麼?