我已经运行了Java EE 7(JSF,JPA)和基于CDI的应用程序,使用Shiro进行身份验证和授权。
我已经满足要求,用户必须在一定时间后更改密码(可由应用程序的管理员自定义,即30天)。在我们的用户表中,我们存储了上次设置密码时的信息,因此可以在登录时计算,如果有时间的话。
计划是重新显示登录页面并表示不同的表单(更改密码而不是登录)。到现在为止还挺好。然而: 如何强制更改密码而不让用户导航到其他页面?
是否有推荐(甚至是内置)解决方案?
我的想法是实现一个过滤器,它检查会话范围的登录对象是否需要重置PW。 希望是,这就像创建一个新的过滤器一样简单,在那里注入登录并检查标志的状态 - 并且只要flag为真/他没有更新他的pw,就将用户重定向到登录页面。 / p>
(我们已经有一个自定义的cdi识别EnvironmentLoaderListener来支持我们的JPA领域。)
新过滤器会落后于最后一行吗?
[urls]
/javax.faces.resource/** = anon
/layout.xhtml = anon
/css/** = anon
/login.xhtml = user
/logout.xhtml = logout
/** = user
所以我们有:
/** = user,pwresetfilter
欢迎提供有关详细信息和整体解决方案的建议。
答案 0 :(得分:0)
您可以使用您的解决方案,但最好是这样:
你让自己的境界
MyRealm extends AuthorizingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
}
}
在doGetAuthenticationInfo中,如果需要更改密码,您将检查凭据并抛出异常。随意扩展目前正在使用的领域。
在您的EnvironmentLoaderListener中注册您的领域
最后你可能需要使用过滤器来重定向到正确的页面,或者如果你使用REST(比如Jersey),你可以有一个异常映射器,它将响应你的浏览器客户端
答案 1 :(得分:0)
我在验证后对OTP有类似的要求,我使用普通过滤器来过滤掉所有请求。 在use bean中使用lastPasswordChangedDate制作一个属性,或者根据需要使用isPasswordChangerequired。并在过滤器中进行比较。
我的简单otpFliter代码如下,但您可以根据需要制作自己的jsf等:
/**
* Servlet Filter implementation class OTPFilter
*/
@WebFilter(urlPatterns = {"/*"},initParams={@WebInitParam(name="enabled",value="0")})
public class OTPFilter implements Filter {
/**
* Default constructor.
*/
boolean enabled=true;
public OTPFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
//System.out.println(enabled);
if(enabled){
if(SecurityUtils.getSubject().getPrincipal()!=null){
if(request instanceof HttpServletRequest ){
HttpSession session = ((HttpServletRequest) request).getSession();
LoggedInUser user = (LoggedInUser) session.getAttribute("userinfo");
String url = ((HttpServletRequest) request).getRequestURL().toString();
//System.out.println("url is "+ url);
if( !url.contains("public") && !user.isOTPverified()){
if(user.getOTP() == null)
{
user.setOTP(OTPUtils.generateOTP());
}
//user.setOTPverified(true);
((HttpServletRequest) request).getRequestDispatcher("OTP.jsp").forward(request, response);
return;
}
}
}
}
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
//System.out.println("fConfig.getInitParameter :" + fConfig.getInitParameter("enabled"));
enabled = fConfig.getInitParameter("enabled").equals("1");
}
}