簡體   English   中英

Zkoss Spring Security始終返回AnonymousAuthenticationToken

[英]Zkoss Spring Security always returns AnonymousAuthenticationToken

由於Spring-Security和Zkoss,我有一個問題。 我當前的問題是,在我以admin正確登錄(別名:admin,pw:admin)的情況下,Spring始終以匿名用戶身份驗證當前用戶。 我創建了自己的AuthenticationProvider,用於驗證正確的登錄數據。 這是我的安全上下文xml文件:

    <http auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
    <custom-filter position="FORM_LOGIN_FILTER" ref="usernamePasswordAuthenticationFilter" />
    <intercept-url pattern="/login.zul" access="permitAll" />
    <intercept-url pattern="/index.html" access="permitAll" />
    <intercept-url pattern="/**" access="permitAll" />
    <logout logout-url="/j_spring_security_logout" logout-success-url="/logout.zul" />
    <access-denied-handler ref="accessDeniedHandler" />

    <!-- <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" /> -->
    <!-- <session-management session-authentication-strategy-ref="sas" /> -->
</http>

<beans:bean id="httpSessionSecurityContextRepository" class="com.tembit.terminator.security.HttpSessionSecurityContextRepository" />

<beans:bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <beans:property name="loginFormUrl" value="/login.zul" />
</beans:bean>

<beans:bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
    <beans:property name="errorPage" value="/error.zul" />
</beans:bean>

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

<beans:bean id="usernamePasswordAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <beans:property name="filterProcessesUrl" value="/j_security_check" />
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="sessionAuthenticationStrategy" ref="sas" />
    <beans:property name="authenticationSuccessHandler">
        <beans:bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
            <beans:property name="defaultTargetUrl" value="/index.html" />
        </beans:bean>
    </beans:property>
    <beans:property name="authenticationFailureHandler">
        <beans:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
            <beans:property name="defaultFailureUrl" value="/error.zul" />
        </beans:bean>
    </beans:property>
</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:property name="exceptionIfMaximumExceeded" value="true" />
</beans:bean>

<beans:bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
    <beans:property name="sessionRegistry" ref="sessionRegistry" />
    <beans:property name="expiredUrl" value="/index.html" />
</beans:bean>

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

<beans:bean id="authenticationProvider" class="com.tembit.terminator.auth.AuthentificationProvider" />

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="authenticationProvider" />
</security:authentication-manager>

這是我的AuthenticationProvider

@Service

公共類AuthentificationProvider實現AuthenticationProvider {

@Autowired
private UserManager userManager;

@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
    final User user = userManager.findByAlias(authentication.getPrincipal().toString());

    if (user.getId() == null) {
        throw new UsernameNotFoundException("Invalid credentials");
    }

    final HashUtil util = new HashUtil();
    final String suppliedPassword = util.hash(authentication.getCredentials().toString());
    if (!user.getPassword().equals(suppliedPassword)) {
        throw new BadCredentialsException("Invalid credentials");
    }

    return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
}

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

}

這是我的用戶類別

public class User implements BaseEntity, UserDetails {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(length = 50, nullable = false, unique = true)
private String alias;

@Column(columnDefinition = "text")
private String password;

@Version
private Long versionCount;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "UserRole", joinColumns = { @JoinColumn(name = "userId") }, inverseJoinColumns = { @JoinColumn(name = "roleId") })
private Set<Role> roles;

public Long getId() {
    return id;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    final Set<Authority> authorities = new HashSet<Authority>();
    for (final Role role : roles) {
        for (final Permission permission : role.getPermissions()) {
            final Authority authority = new Authority(permission.getName());
            authorities.add(authority);
        }
    }
    return authorities;
}

public void setPassword(final String password) {
    final HashUtil util = new HashUtil();
    this.password = util.hash(password);
}

@Override
public String getPassword() {
    return password;
}

public void setUsername(final String username) {
    alias = username;
}

@Override
public String getUsername() {
    return alias;
}

public Set<Role> getRoles() {
    return roles;
}

public void setRoles(final Set<Role> roles) {
    this.roles = roles;
}

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

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

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

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

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (prime * result) + ((alias == null) ? 0 : alias.hashCode());
    result = (prime * result) + ((id == null) ? 0 : id.hashCode());
    result = (prime * result) + ((password == null) ? 0 : password.hashCode());
    result = (prime * result) + ((roles == null) ? 0 : roles.hashCode());
    result = (prime * result) + ((versionCount == null) ? 0 : versionCount.hashCode());
    return result;
}

@Override
public boolean equals(final Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final User other = (User) obj;
    if (alias == null) {
        if (other.alias != null) {
            return false;
        }
    } else if (!alias.equals(other.alias)) {
        return false;
    }
    if (id == null) {
        if (other.id != null) {
            return false;
        }
    } else if (!id.equals(other.id)) {
        return false;
    }
    if (password == null) {
        if (other.password != null) {
            return false;
        }
    } else if (!password.equals(other.password)) {
        return false;
    }
    if (roles == null) {
        if (other.roles != null) {
            return false;
        }
    } else if (!roles.equals(other.roles)) {
        return false;
    }
    if (versionCount == null) {
        if (other.versionCount != null) {
            return false;
        }
    } else if (!versionCount.equals(other.versionCount)) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "User [id=" + id + ", alias=" + alias + ", password=" + password + ", versionCount=" + versionCount + ", roles=" + roles + "]";
}

@Override
public Map<String, Object> getPatternMap() {
    final Map<String, Object> patternMap = new HashMap<String, Object>();
    if (alias != null) {
        patternMap.put("alias", alias);
    }
    return patternMap;
}

}

這是角色

public class Role implements BaseEntity, Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(length = 50, nullable = false, unique = true)
private String name;

@Column(columnDefinition = "Text")
private String description;

@Version
private Long versionCount;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "PermissionRole", joinColumns = { @JoinColumn(table = "Role", name = "roleId") }, inverseJoinColumns = { @JoinColumn(table = "Permission", name = "permissionId") })
private Set<Permission> permissions;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "UserRole", joinColumns = { @JoinColumn(name = "roleId") }, inverseJoinColumns = { @JoinColumn(name = "userId") })
private Set<User> users;

public Long getId() {
    return id;
}

public void setId(final Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(final String name) {
    this.name = name;
}

public String getDescription() {
    return description;
}

public void setDescription(final String description) {
    this.description = description;
}

public void setPermissions(final Set<Permission> permissions) {
    this.permissions = permissions;
}

public Set<Permission> getPermissions() {
    return permissions;
}

public Set<User> getUsers() {
    return users;
}

public void setUsers(final Set<User> users) {
    this.users = users;
}

public Long getVersionCount() {
    return versionCount;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (prime * result) + ((description == null) ? 0 : description.hashCode());
    result = (prime * result) + ((id == null) ? 0 : id.hashCode());
    result = (prime * result) + ((name == null) ? 0 : name.hashCode());
    result = (prime * result) + ((permissions == null) ? 0 : permissions.hashCode());
    result = (prime * result) + ((versionCount == null) ? 0 : versionCount.hashCode());
    return result;
}

@Override
public boolean equals(final Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final Role other = (Role) obj;
    if (description == null) {
        if (other.description != null) {
            return false;
        }
    } else if (!description.equals(other.description)) {
        return false;
    }
    if (id == null) {
        if (other.id != null) {
            return false;
        }
    } else if (!id.equals(other.id)) {
        return false;
    }
    if (name == null) {
        if (other.name != null) {
            return false;
        }
    } else if (!name.equals(other.name)) {
        return false;
    }
    if (permissions == null) {
        if (other.permissions != null) {
            return false;
        }
    } else if (!permissions.equals(other.permissions)) {
        return false;
    }
    if (versionCount == null) {
        if (other.versionCount != null) {
            return false;
        }
    } else if (!versionCount.equals(other.versionCount)) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "Role [id=" + id + ", name=" + name + ", description=" + description + ", versionCount=" + versionCount + ", permissions=" + permissions + "]";
}

@Override
public Map<String, Object> getPatternMap() {
    final Map<String, Object> patternMap = new HashMap<String, Object>();
    if (name != null) {
        patternMap.put("name", name);
    }
    if (description != null) {
        patternMap.put("description", description);
    }
    return patternMap;
}

}

這是登錄頁面

<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>

    <hbox id="errorMessageHbox" align="center" visible="false">
        <label id="errorMessage"/>
    </hbox>

    <h:form id="loginForm" name="loginForm" method="POST" action="j_security_check" xmlns:h="http://www.w3.org/1999/xhtml" autocomplete="off">

        <grid>
            <columns>
                <column width="100px"/>
                <column width="300px"/>
            </columns>
            <rows>
                <row align="right">
                    <label value="${c:l('login.zul.lbUserName')}"/>
                    <textbox id="tbUsername" readonly="false" width="100%" maxlength="50" value="admin" />
                </row>
                <row align="right">
                    <label value="${c:l('login.zul.lbPassword')}"/>
                    <textbox id="tbPassword" type="password" width="100%" maxlength="50" value="admin" />
                </row>
                <row align="right">
                    <cell colspan="2" align="right">
                        <button id="btnLogin" sclass="primaryButton" label="${c:l('login.zul.btnLogin')}"/>
                    </cell>
                </row>
            </rows>
        </grid>

        <!-- Unvisible fields -->
        <textbox id="j_username" name="j_username" visible="false"/>
        <textbox id="j_password" name="j_password" visible="false" type="password"/>
    </h:form>
</window>

這是loginComposer

public class LoginComposer extends BasePageComposer<Component, User> {

private static final long serialVersionUID = 1L;

// security form fields
protected Textbox j_username;
protected Textbox j_password;

protected Form loginForm;
protected Textbox tbUsername;
protected Textbox tbPassword;

public void onClick$btnLogin() {
    submitLoginForm();
}

protected void submitLoginForm() {
    if ((tbPassword.getValue() != null) && !tbPassword.getValue().isEmpty()) {
        if ((tbUsername.getValue() != null) && !tbUsername.getValue().isEmpty()) {
            j_password.setValue(tbPassword.getValue());
            j_username.setValue(tbUsername.getValue());
        } else {
            throw new WrongValueException(tbUsername, ComposerUtil.getLabel("login.zul.validation.emptyUserName"));
        }
    } else {
        throw new WrongValueException(tbPassword, ComposerUtil.getLabel("login.zul.validation.emptyPassword"));
    }

    try {
        session.setAttribute("loginPerformed", true);
        Clients.submitForm(loginForm);
    } catch (final Exception e) {
        log.error(e.getMessage(), e);
    }
}

@Override
protected String getPageTitle() {
    return ComposerUtil.getLabel("login.zul.pageTitle");
}

}

每當我向管理員用戶正確身份驗證時(並且AuthentificationProvider中返回了UsernamePasswordAuthenticationToken),在處理AnonymousAuthenticationFilter后,它將被AnonymousAuthenticationToken替換。 如何防止過濾器創建AnoynmousToken?

請你幫助我好嗎? 如果您需要更多信息,我會交給他們。

祝大家好

對於那些有相同問題的人:問題是zkoss comet服務器推送修改了身份驗證過程。 該會話以某種方式添加到zkoss comet服務器的線程中,而不是添加到身份驗證請求線程中。 很奇怪。

解決方案:禁用zkoss comet服務器!

祝大家好

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM