Spring并发控制不起作用,用户可以多次登录

时间:2012-09-26 02:46:24

标签: hibernate jsf java-ee spring-security richfaces

我使用Spring和Spring-security 3.0.RELEASE以及jsf 1.2,richface 3.3和hibernate3。

我想避免同一个用户在差异浏览器中多次登录。我创建了一个自定义身份验证提供程序,如下所示:

public class AuthenthicationServiceProvider extends AbstractUserDetailsAuthenticationProvider {


private StaffDao staffDao ;


@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
    // TODO Auto-generated method stub

}

@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
    UserDetails ad = null;
    try {
        ad= getUserDetailInfo(authentication.getPrincipal().toString(), authentication.getCredentials().toString());
    } catch (Exception e) {
        throw new CustomAuthenticationException(e.getMessage()) ;
    }
    return ad;

}

private AuthUserDetail getUserDetailInfo(final String login, final String password ) throws CustomAuthenticationException{
    Staff user = staffDao.getStaffByLogin(login, password);

    String role =  "ROLE_ADMIN";

    if (null == user ) {
        throw new CustomAuthenticationException("Invalid Username or password");
    }

    return new AuthUserDetail(user, role);
}

public StaffDao getStaffDao() {
    return staffDao;
}

public void setStaffDao(StaffDao staffDao) {
    this.staffDao = staffDao;
}

UserDetail如下:

public class AuthUserDetail  implements UserDetails,Serializable  {

private static final long serialVersionUID = -3727430377858939077L;

private Staff staff;
private String role;
private Set<GrantedAuthority> authorities;

public AuthUserDetail(Staff pstaff, String pRole){
    setStaff(pstaff);
    setRole(pRole);
}

@Override
public Collection<GrantedAuthority> getAuthorities() {
     Collection<GrantedAuthority> a = new ArrayList<GrantedAuthority>(Arrays.asList(new GrantedAuthority(){
         public String getAuthority() {
             return role;
         }
   }));
   return a;
}

@Override
public String getPassword() {
    return this.staff.getPassword();
}

@Override
public String getUsername() {
    return this.staff.getLoginId();
}

@Override
public boolean isAccountNonExpired() {
    return true;
}

@Override
public boolean isAccountNonLocked() {
    return true;
}

@Override
public boolean isCredentialsNonExpired() {
    return true;
}

@Override
public boolean isEnabled() {

    return true;
}

public Staff getStaff() {
    return staff;
}

public void setStaff(Staff staff) {
    this.staff = staff;
}

public String getRole() {
    return role;
}

public void setRole(String role) {
    this.role = role;
}

@Override
public boolean equals(Object rhs) {
    if (!(rhs instanceof AuthUserDetail) || (rhs == null)) {
        return false;
    }

    AuthUserDetail user = (AuthUserDetail) rhs;

    // We rely on constructor to guarantee any User has non-null
    // authorities
    if (!getAuthorities().equals(user.getAuthorities())) {
        return false;
    }

    // We rely on constructor to guarantee non-null username and password
    return (this.getPassword().equals(user.getPassword()) && this.getUsername().equals(user.getUsername())
            && (this.isAccountNonExpired() == user.isAccountNonExpired())
            && (this.isAccountNonLocked() == user.isAccountNonLocked())
            && (this.isCredentialsNonExpired() == user.isCredentialsNonExpired())
            && (this.isEnabled() == user.isEnabled()));
}

@Override
public int hashCode() {
    int code = 9792;

    for (GrantedAuthority authority : getAuthorities()) {
        code = code * (authority.hashCode() % 7);
    }

    if (this.getPassword() != null) {
        code = code * (this.getPassword().hashCode() % 7);
    }

    if (this.getUsername() != null) {
        code = code * (this.getUsername().hashCode() % 7);
    }

    if (this.isAccountNonExpired()) {
        code = code * -2;
    }

    if (this.isAccountNonLocked()) {
        code = code * -3;
    }

    if (this.isCredentialsNonExpired()) {
        code = code * -5;
    }

    if (this.isEnabled()) {
        code = code * -7;
    }

    return code;
}

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append(super.toString()).append(": ");
    sb.append("Username: ").append(this.getUsername()).append("; ");
    sb.append("Password: [PROTECTED]; ");
    sb.append("Enabled: ").append(this.isEnabled()).append("; ");
    sb.append("AccountNonExpired: ").append(this.isAccountNonExpired()).append("; ");
    sb.append("credentialsNonExpired: ").append(this.isCredentialsNonExpired()).append("; ");
    sb.append("AccountNonLocked: ").append(this.isAccountNonLocked()).append("; ");

    if (!authorities.isEmpty()) {
        sb.append("Granted Authorities: ");

        boolean first = true;
        for (GrantedAuthority auth : authorities) {
            if (!first) {
                sb.append(",");
            }
            first = false;

            sb.append(auth);
        }
    } else {
        sb.append("Not granted any authorities");
    }

    return sb.toString();
}

}

和安全配置:

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                    http://www.springframework.org/schema/security
                     http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<global-method-security pre-post-annotations="enabled" secured-annotations="enabled" jsr250-annotations="enabled"  />

<http auto-config="true"    access-denied-page="/login.xhtml">

    <intercept-url pattern="/logout*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/error/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/css/**" filters="none"  />
    <intercept-url pattern="/images/**" filters="none" />
    <intercept-url pattern="/js/**" filters="none" />
    <intercept-url pattern="/a4j/**" filters="none" />

    <intercept-url pattern="/common/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/customers/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/journal/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/masterCustomer/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/report/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/setting/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/staffs/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/templates/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/transactions/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/winloses/**" access="ROLE_ADMIN,ROLE_USER" />
    <intercept-url pattern="/**" access="ROLE_ADMIN,ROLE_USER" />

    <form-login 
        login-processing-url="/j_spring_security_check" 
        login-page="/login.xhtml" 
        default-target-url="/transactions/index.xhtml"
        authentication-failure-url="/login.xhtml?error=true" always-use-default-target="true"  />


    <session-management   session-authentication-error-url="/login.xhtml?expired=2" invalid-session-url="/login.xhtml?expired=1" session-fixation-protection="newSession">
           <concurrency-control session-registry-ref="sessionRegistry"  max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.xhtml?errorMessage=The session is expired due to another user logging in with your user name and password."/> 
    </session-management> 

</http> 

<authentication-manager >
    <authentication-provider  ref="authenthicationServiceProvider" />
</authentication-manager>

<beans:bean id="authenthicationServiceProvider" class="com.cboclub.csmweb.service.AuthenthicationServiceProvider">
    <beans:property name="staffDao" ref="staffDao" />
</beans:bean>

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


</beans:beans>

你有什么想法吗?

0 个答案:

没有答案