Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JAAS登录模块注销_Java_Spring Boot_Rest_Jaas - Fatal编程技术网

Java 使用JAAS登录模块注销

Java 使用JAAS登录模块注销,java,spring-boot,rest,jaas,Java,Spring Boot,Rest,Jaas,这个问题比预期的要长一点。下面是一个类似的链接(第三篇文章),我没有找到令人满意的答案 我正在尝试使用JAAS登录模块注销。以下是该项目的简要结构: LoginService负责在用户想要登录时实例化LoginContext: @Service public class LoginService { public UserDTO getUserDTOFrom(Credentials credentials) { try { Lo

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

我正在尝试使用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
    }
}
我没有
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
,但当另一个用户尝试登录时,我想创建一个新的。 请注意,我没有使用Spring Security

编辑


其中一个想法是使用一个单例来保存与特定用户关联的登录上下文集。然后在用户注销时调用并销毁它们。此类
集合的密钥可以是JWT令牌或用户id。经过进一步思考,我认为用户可能有多个会话,在这种情况下,作为密钥的用户id将无法发挥作用。第二个选项是JWT令牌,但有一种情况是,未来的中间件将在到期时发布一个新的JWT令牌,那么我的
将无法返回有效的登录上下文。

经过一些研究,我的团队认为JAAS不适合我们的需要。我们没有使用它所提供的完整功能,它束缚了我们的手脚,而不是平滑开发过程

如果您会遇到类似问题,以下是一个解释: 我们正在使用支持JAAS的WebSphere8.5.5。可以注销,但价格将限制在应用服务器上。考虑到我们的计划是从WebSphere迁移,此实现不是一个选项。
指向其中一个指南的链接存在

未来有两种选择:

  • 用Spring Security包装它,因为它提供了
  • 完全依靠Spring Security的 功能
  • @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());
            }
        }
    }
    
    @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();
        }
    }