本人在修改一个项目,加入验证码,但是整个项目由Spring Security安全机制,我将验证码存放在session中,但是现在不知道如何在Security工程下获取这个session中得值。因为需要比较前台传过来的和session中存得,感谢大家,应该在Security工程下面类中可以调用方法。

解决方案 »

  1.   

    给你看看我刚实现的代码
    1.applicationContext-security.xml
    自己重写ValidateCodeUsernamePasswordAuthenticationFilter继承UsernamePasswordAuthenticationFilter<bean id="authenticationProcessingFilter" class="com.apabi.leopard.service.security.ValidateCodeUsernamePasswordAuthenticationFilter">2.ValidateCodeUsernamePasswordAuthenticationFilter.java/**
     * <li>带验证码校验功能的用户名、密码认证过滤器</li>
     * <p>
     * 支持不输入验证码;支持验证码忽略大小写。
     * 
     * @author cb
     * 
     */
    public class ValidateCodeUsernamePasswordAuthenticationFilter extends
    UsernamePasswordAuthenticationFilter { private boolean postOnly = true;
    private boolean allowEmptyValidateCode = false;
    private String sessionvalidateCodeField = DEFAULT_SESSION_VALIDATE_CODE_FIELD;
    private String validateCodeParameter = DEFAULT_VALIDATE_CODE_PARAMETER;
    public static final String DEFAULT_SESSION_VALIDATE_CODE_FIELD = "_validate_code";//session中的验证码
    public static final String DEFAULT_VALIDATE_CODE_PARAMETER = "j_code";//表单输入验证码 @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
    HttpServletResponse response) throws AuthenticationException {
    if (postOnly && !request.getMethod().equals("POST")) {
    throw new AuthenticationServiceException(
    "Authentication method not supported: "
    + request.getMethod());
    } String username = obtainUsername(request);
    String password = obtainPassword(request); if (username == null) {
    username = "";
    } if (password == null) {
    password = "";
    } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
    username, password); // Place the last username attempted into HttpSession for views
    HttpSession session = request.getSession(false); if (session != null || getAllowSessionCreation()) {
    request.getSession().setAttribute(
    SPRING_SECURITY_LAST_USERNAME_KEY,
    TextEscapeUtils.escapeEntities(username));
    } // Allow subclasses to set the "details" property
    setDetails(request, authRequest);
    // check validate code
    if (!isAllowEmptyValidateCode())
    checkValidateCode(request);
    return this.getAuthenticationManager().authenticate(authRequest);
    } /**
     * 
     * <li>比较session中的验证码和用户输入的验证码是否相等</li>
     * 
     */
    protected void checkValidateCode(HttpServletRequest request) {
    String sessionValidateCode = obtainSessionValidateCode(request);
    String validateCodeParameter = obtainValidateCodeParameter(request);
    if (StringUtils.isEmpty(validateCodeParameter)
    || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {
    throw new AuthenticationServiceException("ValidateCode error");
    }
    } private String obtainValidateCodeParameter(HttpServletRequest request) {
    return request.getParameter(validateCodeParameter);
    } protected String obtainSessionValidateCode(HttpServletRequest request) {
    Object obj = request.getSession()
    .getAttribute(sessionvalidateCodeField);
    return null == obj ? "" : obj.toString();
    } public boolean isPostOnly() {
    return postOnly;
    } @Override
    public void setPostOnly(boolean postOnly) {
    this.postOnly = postOnly;
    } public String getValidateCodeName() {
    return sessionvalidateCodeField;
    } public void setValidateCodeName(String validateCodeName) {
    this.sessionvalidateCodeField = validateCodeName;
    } public boolean isAllowEmptyValidateCode() {
    return allowEmptyValidateCode;
    } public void setAllowEmptyValidateCode(boolean allowEmptyValidateCode) {
    this.allowEmptyValidateCode = allowEmptyValidateCode;
    }}
      

  2.   

    问下你包的引用 还有问下_validate_code 这个是验证码放在session里面的key吗? StringUtils.isEmpty是哪个包导入的
      

  3.   

    _validate_code 就是session中验证码的名字 上面有注释的 换成你自己的
    StringUtils类在
    commons-lang-2.4.jar这个包应该很常见吧 一般的项目里面都有
      

  4.   

    貌似在spring的配置上有问题,install通不过 不知道为什么
       <b:bean id="loginFilter"    
                class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
               <b:property name="authenticationManager" ref="authenticationManager"/>
               <b:property name="authenticationFailureHandler" ref="failureHandler"/>
               <b:property name="authenticationSuccessHandler" ref="successHandler"/>
               <b:property name="filterProcessesUrl" value="/login"/>
          </b:bean>
    这个是原来只有用户名和密码验证的,是不是我把后面的class改成现在的类就可以了呢
      

  5.   

    基本搞定了spring security真心是个复杂的东西,我这边配置的被注释掉了 所以出现了问题 被人用了另外一种拦截机制 AbstractSecurityInterceptor这个玩意 竟然配置了这个 现在我把它注销掉了 谢谢你 分都给你了 思路有了就好了 发现你很给力啊