gpt4 book ai didi

spring - 如何在 Spring Security 中集成 JCaptcha

转载 作者:行者123 更新时间:2023-12-01 01:14:32 27 4
gpt4 key购买 nike

在开始回答之前,我知道有 ReCaptcha,它更简单更容易,但我不能使用它。生产服务器不在线。所以我们开始了。

我在 maven 项目和 weblogic 上使用带有 spring security 的 Spring mvc 3 作为 web 服务器(开发时的码头)。我将非常具体地说明这一点。

在查看我的配置和文件之前,我想向您展示我的问题列表:

  • 我在 JCaptcha 之前尝试过使用相同编码结构的 ReCaptcha,它工作正常。
  • logger.debug 根本没有出现在 CaptchaCaptureFilter 类和/或 CaptchaVerifierFilter 类中(而它出现在 ArtajasaAuthenticationProvider 类中)。
  • 我可以看到验证码图像,但无论答案是什么,它总是无效的。
  • 在当前状态下,它在 jetty 和 weblogic 中都不起作用,但是如果我将自定义过滤器位置更改为下面的位置,则它仅在 jetty 中起作用。
    <custom-filter ref="captchaCaptureFilter" position="FIRST"/>
    <custom-filter ref="captchaVerifierFilter" after="FIRST"/>

  • 感谢您的观看,非常感谢您回答我的问题。
    以下是详细信息。

    JCaptcha 的存储库是这样的:
    <repository>
    <id>sourceforge-releases</id>
    <name>Sourceforge Releases</name>
    <url>https://oss.sonatype.org/content/repositories/sourceforge-releases</url>
    </repository>

    <dependency>
    <groupId>com.octo.captcha</groupId>
    <artifactId>jcaptcha-integration-simple-servlet</artifactId>
    <version>2.0-alpha-1</version>
    </dependency>

    以下是我在 .xml 文件中所做的一些配置:

    网页.xml
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/applicationContext.xml
    /WEB-INF/spring/spring-security.xml
    </param-value>
    </context-param>
    <listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>

    <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <servlet>
    <servlet-name>jcaptcha</servlet-name>
    <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>jcaptcha</servlet-name>
    <url-pattern>/jcaptcha.jpg</url-pattern>
    </servlet-mapping>

    spring-security.xml
    <http auto-config="true" use-expressions="true">
    <intercept-url pattern="/resources/**" access="permitAll()" />
    <intercept-url pattern="/jcaptcha.jpg" access="permitAll()" />
    <intercept-url pattern="/**" access="isAuthenticated()" />

    <form-login login-page="/session/login/" default-target-url="/"
    authentication-failure-url="/session/loginfailed/" />
    <logout logout-success-url="/session/logout/" />
    <access-denied-handler error-page="/session/403/" />

    <!--JCaptcha Filtering-->
    <custom-filter ref="captchaCaptureFilter" before="FORM_LOGIN_FILTER"/>
    <custom-filter ref="captchaVerifierFilter" after="FORM_LOGIN_FILTER"/>
    <anonymous />
    </http>

    <!-- For capturing CAPTCHA fields -->
    <beans:bean id="captchaCaptureFilter" class="com.util.CaptchaCaptureFilter" />

    <!-- For verifying CAPTCHA fields -->
    <!-- Private key is assigned by the JCaptcha service -->
    <beans:bean id="captchaVerifierFilter" class="com.util.CaptchaVerifierFilter"
    p:failureUrl="/session/loginfailed/"
    p:captchaCaptureFilter-ref="captchaCaptureFilter"/>

    <beans:bean id="customAuthFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <beans:property name="sessionAuthenticationStrategy" ref="sas"/>
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="allowSessionCreation" value="true" />
    </beans:bean>

    <beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
    <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry"/>
    <beans:property name="maximumSessions" value="1" />
    </beans:bean>

    <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />

    <beans:bean id="userService" class="com.service.mybatis.UserManager" />

    <beans:bean id="customAuthenticationProvider" class="com.util.ArtajasaAuthenticationProvider" />
    <authentication-manager alias="authenticationManager">
    <authentication-provider ref="customAuthenticationProvider" />
    </authentication-manager>

    <beans:bean id="accessDeniedHandler" class="com.util.ThouShaltNoPass">
    <beans:property name="accessDeniedURL" value="/session/403/" />
    </beans:bean>

    这些是java类:

    ArtajasaAuthenticationProvider.java
    public class ArtajasaAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService userService;
    private Logger logger = LoggerFactory.getLogger(ArtajasaAuthenticationProvider.class);

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = String.valueOf(authentication.getPrincipal());
    String password = String.valueOf(authentication.getCredentials());
    logger.debug("Checking authentication for user {}", username);
    if (StringUtils.isBlank(username)
    || StringUtils.isBlank(password)) {
    throw new BadCredentialsException("No Username and/or Password Provided.");
    } else {
    Pengguna user = userService.select(username);
    if (user == null) {
    throw new BadCredentialsException("Invalid Username and/or Password.");
    }
    if (user.getPassword().equals(new PasswordUtil().generateHash(password, user.getSalt()))) {
    List<GrantedAuthority> authorityList = (List<GrantedAuthority>) userService.getAuthorities(user);
    return new UsernamePasswordAuthenticationToken(username, password, authorityList);
    } else {
    throw new BadCredentialsException("Invalid Username and/or Password.");
    }
    }
    }

    @Override
    public boolean supports(Class<?> authentication) {
    return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
    }

    CaptchaCaptureFilter.java
    public class CaptchaCaptureFilter extends OncePerRequestFilter {

    protected Logger logger = Logger.getLogger(CaptchaCaptureFilter.class);
    private String userCaptchaResponse;
    private HttpServletRequest request;

    @Override
    public void doFilterInternal(HttpServletRequest req, HttpServletResponse res,
    FilterChain chain) throws IOException, ServletException {

    logger.debug("Captcha capture filter");

    // Assign values only when user has submitted a Captcha value.
    // Without this condition the values will be reset due to redirection
    // and CaptchaVerifierFilter will enter an infinite loop
    if (req.getParameter("jcaptcha") != null) {
    request = req;
    userCaptchaResponse = req.getParameter("jcaptcha");
    }

    logger.debug("userResponse: " + userCaptchaResponse);

    // Proceed with the remaining filters
    chain.doFilter(req, res);
    }

    public String getUserCaptchaResponse() {
    return userCaptchaResponse;
    }

    public void setUserCaptchaResponse(String userCaptchaResponse) {
    this.userCaptchaResponse = userCaptchaResponse;
    }

    public HttpServletRequest getRequest() {
    return request;
    }

    public void setRequest(HttpServletRequest request) {
    this.request = request;
    }
    }

    CaptchaVerifierFilter.java
    public class CaptchaVerifierFilter extends OncePerRequestFilter {

    protected Logger logger = Logger.getLogger(CaptchaVerifierFilter.class);
    private String failureUrl;
    private CaptchaCaptureFilter captchaCaptureFilter;

    // Inspired by log output: AbstractAuthenticationProcessingFilter.java:unsuccessfulAuthentication:320)
    // Delegating to authentication failure handlerorg.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@15d4273
    private SimpleUrlAuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();

    @Override
    public void doFilterInternal(HttpServletRequest req, HttpServletResponse res,
    FilterChain chain) throws IOException, ServletException {

    logger.debug("Captcha verifier filter");
    logger.debug("userResponse: " + captchaCaptureFilter.getUserCaptchaResponse());

    // Assign values only when user has submitted a Captcha value
    if (captchaCaptureFilter.getUserCaptchaResponse() != null) {

    // Send HTTP request to validate user's Captcha
    boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse(captchaCaptureFilter.getRequest(), captchaCaptureFilter.getUserCaptchaResponse());

    // Check if valid
    if (!captchaPassed) {
    logger.debug("Captcha is invalid!");

    // Redirect user to login page
    failureHandler.setDefaultFailureUrl(failureUrl);
    failureHandler.onAuthenticationFailure(req, res, new BadCredentialsException("Captcha invalid! " + captchaCaptureFilter.getRequest() + " " + captchaCaptureFilter.getUserCaptchaResponse()));

    } else {
    logger.debug("Captcha is valid!");
    }

    // Reset Captcha fields after processing
    // If this method is skipped, everytime we access a page
    // CaptchaVerifierFilter will infinitely send a request to the Google Captcha service!
    resetCaptchaFields();
    }

    // Proceed with the remaining filters
    chain.doFilter(req, res);
    }

    /**
    * Reset Captcha fields
    */
    public void resetCaptchaFields() {
    captchaCaptureFilter.setUserCaptchaResponse(null);
    }

    public String getFailureUrl() {
    return failureUrl;
    }

    public void setFailureUrl(String failureUrl) {
    this.failureUrl = failureUrl;
    }

    public CaptchaCaptureFilter getCaptchaCaptureFilter() {
    return captchaCaptureFilter;
    }

    public void setCaptchaCaptureFilter(CaptchaCaptureFilter captchaCaptureFilter) {
    this.captchaCaptureFilter = captchaCaptureFilter;
    }
    }

    最后但并非最不重要的,login.jsp
    <%@ taglib prefix='c' uri='http://java.sun.com/jstl/core_rt' %>

    <form id="login" name="f" action="<c:url value='/j_spring_security_check'/>" method="POST">
    <div class="container">

    <div class="content">
    <div class="row">
    <div class="login-form">
    <h3>Login</h3>
    <br />
    <fieldset>
    <div class="clearfix">
    username: ecr
    <input type="text" name='j_username' value='<c:if test="${not empty param.login_error}"><c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>' placeholder="username@artajasa.co.id">
    </div>
    <div class="clearfix">
    password: ecr123
    <input type="password" name='j_password' placeholder="password">
    </div>
    <div class="clearfix">
    <img src="../../jcaptcha.jpg" />
    <br />
    <input type="text" name="jcaptcha" placeholder="masukkan captcha" />
    </div>
    <br />
    <button class="btn btn-primary" type="submit"><i class="icon-lock"></i> Sign in</button>
    </fieldset>
    </div>
    </div>
    </div>
    <br />
    <c:if test="${not empty error}">
    <div class="alert alert-error">
    <button type="button" class="close" data-dismiss="alert"><i class="icon-remove"></i></button>
    Login Failed, try again.<br />
    <c:out value="${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message}"/>
    </div>
    </c:if>
    </div>

    最佳答案

    问题解决了!我找到了答案。所以我们毕竟不需要 CaptchaVerifierFilter。我在 AuthenticationProvider 中验证了验证码。

    这些是更改列表:

    在 spring-security.xml 中,这个

    <!--JCaptcha Filtering-->
    <custom-filter ref="captchaCaptureFilter" before="FORM_LOGIN_FILTER"/>
    <custom-filter ref="captchaVerifierFilter" after="FORM_LOGIN_FILTER"/>

    成为这个
    <!--JCaptcha Filtering-->
    <custom-filter ref="captchaCaptureFilter" before="FORM_LOGIN_FILTER"/>

    消除
    <!-- For verifying CAPTCHA fields -->
    <!-- Private key is assigned by the JCaptcha service -->
    <beans:bean id="captchaVerifierFilter" class="com.util.CaptchaVerifierFilter"
    p:failureUrl="/session/loginfailed/"
    p:captchaCaptureFilter-ref="captchaCaptureFilter"/>

    并在此处验证验证码
    <beans:bean id="customAuthenticationProvider" class="com.pusilkom.artajasa.ecr.backend.util.MyAuthenticationProvider"
    p:captchaCaptureFilter-ref="captchaCaptureFilter"/>

    关于spring - 如何在 Spring Security 中集成 JCaptcha,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12851637/

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