gpt4 book ai didi

java - 使用 Apache Shiro 实现 reCaptcha

转载 作者:太空宇宙 更新时间:2023-11-04 06:06:58 25 4
gpt4 key购买 nike

我有一个使用 Apache Shiro 保护的 Web 应用程序,并且一切正常。现在我想将 Goolge 的 reCaptcha 添加到我的登录页面,但不知道如何做到这一点。

验证码本身已添加并且工作正常,我现在需要帮助的部分是如何将其与 Shiro 集成以在继续对用户进行身份验证之前进行验证。

根据我从 docs 收集到的信息这可以通过过滤器链来完成。

所以我将其放入我的 shiro.ini 中:

[main]
authc.failureKeyAttribute = shiroLoginFailure
authc.loginUrl = /login.jsp
authc.successUrl = /LogIn
logout.redirectUrl = /login.jsp
captcha = path.to.my.class.VerifyUserFilter

...

[urls]
/login.jsp = captcha,authc
/* = authc

我知道如何实现验证验证码的逻辑。我不知道除了实际的验证逻辑之外,VerifyUserFilter 类需要是什么样子才能完成这项工作。本质上,它需要做的就是发布到 Google API,获取响应,解析它,并根据结果将请求传递到下一个过滤器,或者在验证失败时停止。

在我发布这篇文章之前,我决定最后一次尝试,并花了几个小时尝试不同的事情,最终让它发挥作用!无论如何,我仍然决定发布这个问题,并在下面附上我自己的答案,因为我在研究这个问题时找不到太多帮助,也看看我所做的是否正确。如果有更好或更合适的方法来做到这一点,我想知道。

最佳答案

这是我解决这个问题的方法。

首先,我按如下方式设置我的 shiro.ini(相关部分):

[main]
authc.failureKeyAttribute = shiroLoginFailure
authc.loginUrl = /login.jsp
authc.successUrl = /LogIn
logout.redirectUrl = /login.jsp
captcha = path.to.my.class.VerifyUserFilter

...

[urls]
/login.jsp = captcha,authc
/* = authc

然后,我通过扩展 FormAuthenticationFilter 类并重写读取参数的 doFilterInternal 方法创建了我的 VerifyUserFilter 类,调用 Google API验证响应,然后根据结果,如果验证失败,则重定向到登录页面,或者转到过滤器链中的下一项 - 在本例中为 authc

这是我的 VerifyUserFilter 类的完整实现:​​

import org.apache.shiro.web.util.WebUtils;

public class VerifyUserFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {

@Override
public void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(VerifyUserFilter.class);
if (isLoginSubmission(request, response)){
String user = WebUtils.getCleanParam(request, "username");
String verifId = WebUtils.getCleanParam(request, "g-recaptcha-response");
log.debug("Verif ID: " + verifId);
if (verifId == null || "".equals(verifId)) {
log.warn("User " + user + " missed the captcha challenge and is returned to login page.");
saveRequestAndRedirectToLogin(request, response);
} else {
// Now do the verification of the captcha
final String url = "https://www.google.com/recaptcha/api/siteverify";
final String secret = "6Lxxxxxxxxxxxxxx";
// Send the POST request to the Google API
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection)obj.openConnection();
con.setRequestMethod("POST");
String params = "secret=" + secret + "&response=" + verifId;
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
log.debug("Sending POST to " + url);
wr.writeBytes(params);
wr.flush();
wr.close();
// Get the response code
int respCode = con.getResponseCode();
log.debug("Response code: " + respCode);
// Read in the response data
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
StringBuilder input = new StringBuilder();
log.debug("Reading response data...");
while ((line = in.readLine()) != null){
input.append(line);
}
in.close();
log.debug("Reponse data: " + input);
// Parse the json received to determine if the verif was successful
JsonReader jr = Json.createReader(new StringReader(input.toString()));
JsonObject jo = jr.readObject();
jr.close();
if (jo.getBoolean("success")){
log.debug("User " + user + " is good to go, not a robot!");
// Move on to the next filter
chain.doFilter(request, response);
} else {
// User did not solve the captcha, return to login page
log.warn("User " + user + " failed the captcha challenge and is returned to login page.");
saveRequestAndRedirectToLogin(request, response);
}
}
} else {
log.debug("Not a login attempt, carry on.");
chain.doFilter(request, response);
}
}
}

关于java - 使用 Apache Shiro 实现 reCaptcha,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30301277/

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