解决方案 »

  1.   

    继承UsernamePasswordAuthenticationFilter类的代码package filter;import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import org.springframework.security.authentication.AuthenticationServiceException;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
      /** 
     * 重载SECURITY3的UsernamePasswordAuthenticationFilter的attemptAuthentication, 
     * obtainUsername,obtainPassword方法(完善逻辑) 增加验证码校验模块 添加验证码属性 添加验证码功能开关属性 
     *  
     * @author shadow 
     * @email [email protected] 
     * @create 2012.04.28 
     */
    public class UsernamePasswordAuthenticationExtendFilter extends UsernamePasswordAuthenticationFilter  {

    private SessionAuthenticationStrategy  sessionAuthenticationStrategy = null;


    public SessionAuthenticationStrategy getSessionAuthenticationStrategy() {
    return sessionAuthenticationStrategy;
    }

    public void setSessionAuthenticationStrategy(
    SessionAuthenticationStrategy sessionAuthenticationStrategy) {
    this.sessionAuthenticationStrategy = sessionAuthenticationStrategy;
    } // 验证码字段
    private String validateCodeParameter = "validateCode";
    // 是否开启验证码功能
    private boolean openValidateCode = false; @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
    HttpServletResponse response) throws AuthenticationException {
    request.getSession().removeAttribute("msg");
    // 只接受POST方式传递的数据
    if (!"POST".equals(request.getMethod())){
    throw new AuthenticationServiceException("不支持非POST方式的请求!");
    } // 开启验证码功能的情况
    if (isOpenValidateCode()){
    checkValidateCode(request);
    } // 获取Username和Password
    String username = obtainUsername(request);
    String password = obtainPassword(request); // UsernamePasswordAuthenticationToken实现Authentication校验
    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
    username, password); // 允许子类设置详细属性
    setDetails(request, authRequest); // 运行UserDetailsService的loadUserByUsername 再次封装Authentication
    return this.getAuthenticationManager().authenticate(authRequest);
    } // 匹对验证码的正确性
    public void checkValidateCode(HttpServletRequest request) {
    String jcaptchaCode = obtainValidateCodeParameter(request);
    if (null == jcaptchaCode || "".equals(jcaptchaCode)){
    throw new AuthenticationServiceException("请输入验证码");    
    }
    if(null == request.getSession().getAttribute("rand")){
    throw new AuthenticationServiceException("验证码失效");    
    }
    //对比普通验证码
    if(!request.getSession().getAttribute("rand").equals(jcaptchaCode)){
    throw new AuthenticationServiceException("验证码错误!");    
    }
    return;
    } public String obtainValidateCodeParameter(HttpServletRequest request) {
    Object obj = request.getParameter(getValidateCodeParameter());
    return null == obj ? "" : obj.toString().trim();
    } @Override
    protected String obtainUsername(HttpServletRequest request) {
    Object obj = request.getParameter(getUsernameParameter());
    return null == obj ? "" : obj.toString().trim();
    } @Override
    protected String obtainPassword(HttpServletRequest request) {
    Object obj = request.getParameter(getPasswordParameter());
    return null == obj ? "" : obj.toString().trim();
    } public String getValidateCodeParameter() {
    return validateCodeParameter;
    } public void setValidateCodeParameter(String validateCodeParameter) {
    this.validateCodeParameter = validateCodeParameter;
    } public boolean isOpenValidateCode() {
    return openValidateCode;
    } public void setOpenValidateCode(boolean openValidateCode) {
    this.openValidateCode = openValidateCode;
    }
    }
    UserDetailsService页面代码package filter;import java.util.ArrayList;
    import java.util.Collection;import model.UserDetail;import org.springframework.dao.DataAccessException;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.GrantedAuthorityImpl;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;/**
     * 登录类
     * 
     * @author Administrator
     * @comment 在这个类中,你就可以从数据库中读入用户的密码、角色信息、是否锁定、 账号是否过期等. new User()方法参数说明, String
     *          username(用户名), String password(密码), boolean enabled(账户是否可用), boolean
     *          accountNonExpired(账户是否未过期), boolean accountNonLocked(账户是否未锁定),
     *          Collection<GrantedAuthority> authorities(账户所受权限).
     */
    public class MyUserDetailService implements UserDetailsService {


    @Override
    public UserDetails loadUserByUsername(String username)
    throws UsernameNotFoundException, DataAccessException {
    Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
    GrantedAuthorityImpl auth2 = new GrantedAuthorityImpl("ROLE_USER");// 进行授权
    auths.add(auth2);// 添加所授的权限 
    UserDetail user = new UserDetail("123", "123", true, true, true, true, auths);
    return  user;
    }
    }UserDetail类方法package model;import java.util.Collection;import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;@SuppressWarnings("serial")
    public class UserDetail implements UserDetails {
    private Collection<GrantedAuthority> authorities;
    private String password;
    private String username;
    private boolean isAccountNonExpired;
    private boolean isAccountNonLocked;
    private boolean isCredentialsNonExpired;
    private boolean isEnabled; /** default constructor */
    public UserDetail() {
    } public UserDetail(String username, String password,
    boolean isAccountNonExpired, boolean isAccountNonLocked,
    boolean isCredentialsNonExpired, boolean isEnabled, Collection<GrantedAuthority> authorities) {
    this.username = username;
    this.password = password;
    this.isAccountNonExpired = isAccountNonExpired;
    this.isAccountNonLocked = isAccountNonLocked;
    this.isCredentialsNonExpired = isCredentialsNonExpired;
    this.isEnabled = isEnabled;
    this.authorities = authorities;
    } // Constructors public Collection<GrantedAuthority> getAuthorities() {
    return authorities;
    } public void setAuthorities(Collection<GrantedAuthority> authorities) {
    this.authorities = authorities;
    } public String getPassword() {
    return password;
    } public void setPassword(String password) {
    this.password = password;
    } public String getUsername() {
    return username;
    } public void setUsername(String username) {
    this.username = username;
    } public boolean isAccountNonExpired() {
    return isAccountNonExpired;
    } public void setAccountNonExpired(boolean isAccountNonExpired) {
    this.isAccountNonExpired = isAccountNonExpired;
    } public boolean isAccountNonLocked() {
    return isAccountNonLocked;
    } public void setAccountNonLocked(boolean isAccountNonLocked) {
    this.isAccountNonLocked = isAccountNonLocked;
    } public boolean isCredentialsNonExpired() {
    return isCredentialsNonExpired;
    } public void setCredentialsNonExpired(boolean isCredentialsNonExpired) {
    this.isCredentialsNonExpired = isCredentialsNonExpired;
    } public boolean isEnabled() {
    return isEnabled;
    } public void setEnabled(boolean isEnabled) {
    this.isEnabled = isEnabled;
    }

    @Override
    public boolean equals(Object obj) {
    System.out.println("进入equals方法");
    if (obj instanceof UserDetail) {
    UserDetail another = (UserDetail)obj;
    return this.getUsername().equals(another.getUsername());
    }
    return super.equals(obj);
    } @Override
    public int hashCode() {
    System.out.println("进入hashCode方法");
    return this.getUsername().hashCode();
    }

    }