0

Springを使用してアプリケーションを開発しています。ログイン、ログアウトについて困っています。ログイン資格情報 (例: userName:john、pass: doe) を使用してアプリケーションにログインし、管理ページに移動して、アプリケーションからログアウトしました。ただし、今回は別のログイン資格情報 (例: userName: jack、pass: white) を使用してログインしました。@ModelAttribute(value = "myUser") User loggedInUser管理ページに移動してアプリケーションをデバッグすると、AdminController古いユーザー値が表示されます。なぜこれが起こるのか理解できませんでした。誰でも助けることができますか?

私のソースコードは以下の通りです:

@Controller
@RequestMapping("/LoginController")
@SessionAttributes({"myUser"})
public class LoginController 
{
    private static String LOGIN_URL         = "login/login_";
    private static String INDEX_URL         = "main/index";

    @Autowired
    private IUserService userService    = null;

    @RequestMapping("/login")
    public ModelAndView login(@RequestParam(value="userName", required=false) String argUserName, @RequestParam(value="password", required=false) String argPassword, HttpServletRequest req)
    {

        ModelAndView modelAndView = new ModelAndView();

        // Assume argUserName and argPassword not null
        User loginUser = this.userService.getUser(argUserName, argPassword);

        HttpSession ses = req.getSession();

        // Assume loginUser not null
        ses.setAttribute("myUser", loginUser);

        modelAndView.setViewName(LoginController.INDEX_URL);

        return modelAndView;
    }

    @RequestMapping("/logout")
    public String logout(HttpServletRequest argReq, HttpServletResponse argResp) throws ServletException, IOException
    {
        HttpSession session = argReq.getSession(false);

        Enumeration<?> attributeNames = session.getAttributeNames();
        while(attributeNames.hasMoreElements())
        {
            String attrName = (String)attributeNames.nextElement();

            if(session.getAttribute(attrName) != null)
            {
                session.setAttribute(attrName,null);
                //session.removeAttribute(attrName);
                attributeNames = session.getAttributeNames();
            }
        }
        // close session
        session.invalidate();

        return LoginController.LOGIN_URL;
    }
}

管理者コントローラ

@Controller
@RequestMapping("/AdminController")
@SessionAttributes({"myUser"})
public class AdminController 
{
    private static String SETTINGS_PAGE = "settings/index";

    @RequestMapping("/index")
    public ModelAndView index(@ModelAttribute(value = "myUser") User loggedInUser, HttpSession ses)
    {
        ModelAndView modelAndView = new ModelAndView();
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("loggedInUserId", loggedInUser.getUserID());
        map.put("userName", loggedInUser.getUserName());

        modelAndView.addAllObjects(map);

        modelAndView.setViewName(AdminController.SETTINGS_PAGE);
        return modelAndView;
    }

}
4

2 に答える 2

2

まず@SessionAttributes、異なるコントローラー間のセッションにデータを保存するようには設計されていません。その使用目的は、リクエスト間で同じコントローラのデータを保存することだけです。リクエスト間のセッションにアイテムを保存する場合は、@SessionAttributes に依存せずに、自分でセッションに保存します。これは、アノテーションの javadocにも記載されています (少しわかりにくいかもしれませんが)。

によってキャッシュされたオブジェクトを削除する場合@SessionAttributesは、単純にセッションをクリアすることはできませんが、SessionStatusオブジェクト (引数として追加できる) を使用して、これらのオブジェクトの使用が完了したことをマークする必要があります。

あなたのログアウト方法は冗長です。単に呼び出すだけsession.invalidate()で十分ですが、これは問題を修正するための試みの1つであったと思います. また、サーブレット 3.0 コンテナーを使用している場合は、単純に呼び出すrequest.logout()だけで十分です (または と組み合わせて呼び出しますsession.invalidate()) 。

私の最後のアドバイスは、独自のセキュリティ ソリューションを開発しようとする代わりに、Spring Securityを使用することです。

于 2013-09-02T09:23:47.853 に答える
2

この注釈を削除

@SessionAttributes({"myUser"})
于 2013-09-02T11:06:50.617 に答える