gpt4 book ai didi

java - 使用 JAAS 登录模块注销

转载 作者:行者123 更新时间:2023-12-01 18:01:06 25 4
gpt4 key购买 nike

问题比预期的要长一些。下面是一个类似的链接(第 3 篇文章),我没有找到令人满意的答案。

<强> TL;DR

我正在尝试使用 JAAS 登录模块注销。以下是该项目的简要结构:LoginService 负责在用户想要登录时实例化 LoginContext:

@Service
public class LoginService {

public UserDTO getUserDTOFrom(Credentials credentials) {
try {
LoginContext loginContext = new LoginContext("Login", new JAASCallbackHandler(credentials));
loginContext.login();
// construct UserDTO object.
} catch (LoginException e) {
LOGGER.error("Login Exception: {}", e.getMessage());
// construct UserDTO object.
}
// return UserDTO object.
}

LoginController 调用方法:

@RestController
@RequestMapping("/login")
public class LoginController {

private final LoginService loginService;

@Autowired
public LoginController(LoginService loginService) {
this.loginService = loginService;
}

@PostMapping
public ResponseEntity<UserDTO> getUserDTOFrom(@Valid @RequestBody Credentials credentials) {
UserDTO userDTO = loginService.getUserDTOFrom(userForm);
// return response that depends on outcome in the login service
}
}

当我想注销以前登录的用户时,就会出现此问题。 LoginContext 负责调用 JAAS 登录模块中的注销方法。例如:

loginContext.logout();

JAAS登录模块中的方法:

public class JAASLoginModule implements LoginModule {

@Override
public boolean logout() {
subject.getPrincipals().remove(usernamePrincipal);
subject.getPrincipals().remove(passwordPrincipal);
return true;
}
}

我在 LogoutService 中没有 LoginContext,无法完全清除之前经过身份验证的主题。

我尝试创建一个单例 bean 来获取 LoginContext 的相同实例:

@Configuration
public class LoginContextBean {

@Lazy
@Bean
public LoginContext getLoginContext(Credentials credentials) throws LoginException {
System.setProperty("java.security.auth.login.config", "resources/configuration/jaas.config");
return new LoginContext("Login", new JAASCallbackHandler(credentials));
}
}

@Service
public class LoginService {

private final ObjectProvider<LoginContext> loginContextProvider;

@Autowired
public LoginService(ObjectProvider<LoginContext> loginContextProvider) {
this.loginContextProvider = loginContextProvider;
}

public UserDTO getUserDTOFrom(Credentials credentials) {
try {
LoginContext loginContext = loginContextProvider.getObject(credentials);
loginContext.login();
// construct UserDTO object.
} catch (LoginException e) {
LOGGER.error("Login Exception: {}", e.getMessage());
// construct UserDTO object.
}
// return UserDTO object.
}
}

@Service
public class LogoutService {

private final ObjectProvider<LoginContext> loginContextProvider;

@Autowired
public LogoutService(ObjectProvider<LoginContext> loginContextProvider) {
this.loginContextProvider = loginContextProvider;
}

public void performLogout() {
LoginContext loginContext = loginContextProvider.getObject();
try {
loginContext.logout();
} catch (LoginException e) {
LOGGER.error("Failed to logout: {}.", e.getMessage());
}
}
}

该解决方案并不是特别有用,因为下一个/同一用户登录将在 LoginContext 上获得 NPE。我读到 HttpServletRequestgetSession().invalidate(); 假设调用 JAAS 的 logout()HttpServletRequest logout() 可以完成这项工作。但这两种方法都没有效果。例如:

@RestController
@RequestMapping("/logout")
public class LogoutController {

private final LogoutService logoutService;

@Autowired
public LogoutController(LogoutService logoutService) {
this.logoutService = logoutService;
}

@DeleteMapping
public ResponseEntity<Void> deleteJwt(@CookieValue("jwt_cookie") String jwtToken, HttpServletRequest request) throws ServletException {
request.getSession().invalidate(); // logout() is not called.
request.logout(); // logout() is not called.
return getResponse();
}
}

当用户想要注销时,我想控制之前创建的 LoginContext,但当其他用户尝试登录时创建一个新的。请注意,我没有使用 Spring Security。

编辑:

其中一个想法是使用一个单例来保存与特定用户关联的一组登录上下文。然后在用户注销时调用并销毁它们。此类 Set 的 key 可以是 JWT token 或用户 ID。经过进一步思考,我发现一个用户可能有多个 session ,在这种情况下,用户 id 作为 key 将无法达到其目的。第二个选项是 JWT token ,但有一种情况是 future 的中间件会在过期时发出新的 JWT token ,那么我的 Set 将无法返回有效的登录上下文。

最佳答案

经过一番研究,我的团队认为 JAAS 不适合我们的需求。我们没有使用它所提供的完整功能,它束缚了我们的双手,而不是让开发过程变得顺利。

如果您遇到类似问题,这里有一个解释:我们使用的是WebSphere 8.5.5,它支持JAAS。可以注销,但代价是将其与应用程序服务器绑定(bind)。考虑到我们的计划是从 WebSphere 迁移,因此这种实现不是一个选择。
此类指南之一的链接位于 here .

future 有两种选择:

  1. 将其包装在 Spring Security 中,因为它提供 support for JAAS ;
  2. 替换完全依赖 Spring Security 的自定义模块功能。

关于java - 使用 JAAS 登录模块注销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60626440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com