Pie*_*rre 5 java authentication guice session-scope
嗨,
我目前正在玩Guice和@SessionScoped.为了更有意义,我决定构建一个(非常简单的)身份验证过程.
下面,我将解释我所做的每一步.然后我会问你一些问题.
[1] 我创建了一个代表一个人(访客或用户)的Identity类:
@SessionScoped
public class Identity implements Serializable
{
private String uid;
private String name;
public boolean isAuthenticate()
{
return uid != null;
}
public void logout()
{
this.uid = null;
}
/*Setters-Getters*/
}
Run Code Online (Sandbox Code Playgroud)
[2] 接下来,我创建了一个登录用户的Authentication类:
public class Authentication
{
@Override
public Identity authenticate(String login, String password)
{
/*some code*/
Identity identity = new Identity();
identity.setUid(user.getId());
return identity;
}
}
Run Code Online (Sandbox Code Playgroud)
[3] 然后,在我的Servlet中,我登录用户:
@RequestScoped
public class LoginAction
{
@Inject
Injector injector;
protected void login(HttpServletRequest req, HttpServletResponse resp)
{
Identity identity = injector.getInstance(Identity.class);
Authentication auth = new Authentication();
identity = auth.authenticate("login","password");
}
}
Run Code Online (Sandbox Code Playgroud)
[4] 最后,我创建了一个过滤器,显示用户是否经过身份验证:
@Singleton
public class SecurityFilter implements Filter
{
@Inject
private Injector injector;
@Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
{
Identity identity = injector.getInstance(Identity.class);
if(identity.isAuthenticate())
{
System.err.println("USER");
}
else
{
System.err.println("GUEST");
}
chain.doFilter(request, response);
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,这段代码不起作用.我的身份的uid总是"空".
我们来回答问题:
a - 首先,为什么我的代码不起作用?
b - @SessionScoped是否相当于在HttpSession中设置对象?
c - 如何在(http)会话中使Identity对象(仅限于它)无效?
d - 通常,在哪种情况下我们必须使用@SessionScoped?
谢谢你的阅读,
等待你的答案.
[a]您正在Identity
为一个局部变量分配一个新实例LoginAction
,而不是替换Guice管理的实例.您可以通过填充Guice管理的现有实例上的uid
和name
字段来解决问题Identity
.
例如,而不是
identity = auth.authenticate("login","password");
Run Code Online (Sandbox Code Playgroud)
你可以说:
Identity identity = injector.getInstance(Identity.class);
Authentication auth = new Authentication();
Identity authenticated = auth.authenticate("login","password");
identity.setUid(authenticated.getUid());
identity.setName(authenticated.getName());
Run Code Online (Sandbox Code Playgroud)
有更简洁的方法可以做到这一点,但你明白了.
[b]/[d]这是正确的:@SessionScoped
相当于在中设置一个变量HttpSession
,这就是你要使用它的情况.对于需要在会话中唯一的对象,您需要它,但需要为每个请求提供.
[c]我不太清楚你的意思,但是如果你想根据用户是否登录而重定向到应用程序的不同位置,你的过滤器设计是一种常见的方法.
您可以做出一些改进:
SessionScoped
管理会话用户的服务Identity
,并确保它在Identity
实例上同步.这样,如果用户快速连续发出两个请求,您就不会遇到并发问题.Provider
s而不是注入Injector
(这里的例子)来将你的类与Guice分离.