由于Spring-Security和Zkoss,我有一个问题。我目前的问题是Spring总是以匿名用户身份验证我当前的用户,而我正确地以admin身份登录(别名:admin,pw:admin)。我创建了自己的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
public class 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");
}
}
每当我使用admin用户正确进行身份验证(并且在AuthentificationProvider中返回UsernamePasswordAuthenticationToken)时,在处理AnonymousAuthenticationFilter之后,它将被AnonymousAuthenticationToken替换。如何防止Filter创建AnoynmousToken?
你能帮帮我吗?如果您需要更多信息,我会交给他们。祝福,任何人
答案 0 :(得分:0)
对于那些有同样问题的人:问题是zkoss彗星服务器推送修改了身份验证过程。会话以某种方式添加到zkoss彗星服务器的线程而不是身份验证请求线程。很奇怪。
解决方案:禁用zkoss彗星服务器!
祝福,任何人