我正在使用Spring安全性版本3.1.4.RELEASE。当我尝试登录该应用程序时,出现错误。我已经交叉检查了数据库中的凭据。即使凭据正确,系统也无法让我登录。以下是错误的详细信息和我的配置设置。
尝试登录系统时出现以下错误:
web.security.auth.CustomUsernamePasswordAuthenticationFilter username is support
web.security.auth.CustomUsernamePasswordAuthenticationFilter password is [PROTECTED]
web.security.auth.CustomUsernamePasswordAuthenticationFilter authRequest is org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4a159a52: Principal: support; Credentials: [PROTECTED]; Authenticated: false; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 204.238.52.177; SessionId: 9B49838B0DF4224E169EAF425C0AABE9; Not granted any authorities
web.security.auth.CustomUsernamePasswordAuthenticationFilter Authentication manager was com.sun.proxy.$Proxy476
System.out loadUserByUsername support enter
org.springframework.security.authentication.event.LoggerListener Authentication event AuthenticationFailureServiceExceptionEvent: support; details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 204.238.52.177; SessionId: 9B49838B0DF4224E169EAF425C0AABE9; exception: null
在这里,我得到的异常为null!
配置:
<authentication-manager alias="authenticationManager">
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager>
<beans:bean id="plaintextPasswordEncoder" class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder" />
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="daoUserDetailsService" />
<beans:property name="passwordEncoder" ref="plaintextPasswordEncoder" />
</beans:bean>
<beans:bean id="daoUserDetailsService" class="web.security.auth.DAOUserDetailsService">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<beans:bean id="dataSource" class="web.security.auth.DAODataSource" />
<beans:bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<filter-chain-map request-matcher="ant">
<filter-chain pattern="/**" filters="channelProcessingFilter, SecurityContextPersistenceFilter, logoutFilter, authenticationFilter, anonymousAuthFilter, exceptionTranslationFilter, filterSecurityInterceptor" />
</filter-chain-map>
</beans:bean>
<beans:bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
<beans:property name="channelDecisionManager" ref="channelDecisionManager"/>
<beans:property name="securityMetadataSource">
<filter-security-metadata-source request-matcher="ant">
<intercept-url pattern="/**" access="REQUIRES_SECURE_CHANNEL"/>
</filter-security-metadata-source>
</beans:property>
</beans:bean>
<beans:bean id="channelDecisionManager" class="org.springframework.security.web.access.channel.ChannelDecisionManagerImpl">
<beans:property name="channelProcessors">
<beans:list>
<beans:ref bean="secureChannelProcessor"/>
<beans:ref bean="insecureChannelProcessor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="secureChannelProcessor" class="org.springframework.security.web.access.channel.SecureChannelProcessor" />
<beans:bean id="insecureChannelProcessor" class="org.springframework.security.web.access.channel.InsecureChannelProcessor" />
<beans:bean id="SecurityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
<beans:bean id="authenticationFilter" class="web.security.auth.CustomUsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"/>
<beans:property name="usernameParameter" value="username"/>
<beans:property name="passwordParameter" value="password"/>
</beans:bean>
<beans:bean id="anonymousAuthFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<beans:property name="key" value="foobar"/>
<beans:property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</beans:bean>
<beans:bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<beans:property name="key" value="foobar"/>
</beans:bean>
<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="securityMetadataSource">
<filter-security-metadata-source>
<intercept-url pattern="/LoginPage" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/LoginExpiredPage" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/wicket/bookmarkable/web.sec.pages.LoginExpiredPage" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/images/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/*.png" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/*.ico" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/wicket/resource/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED"/>
</filter-security-metadata-source>
</beans:property>
</beans:bean>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="ROLE_"/>
</beans:bean>
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="/" />
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</beans:list>
</beans:constructor-arg>
<beans:property name="filterProcessesUrl" value="/logout"/>
</beans:bean>
<beans:bean id="forceCookieUseFilter" class="web.security.ForceCookieUseFilter">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<beans:property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</beans:bean>
<beans:bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/LoginPage"/>
</beans:bean>
<beans:bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/accessDenied.htm"/>
</beans:bean>
<beans:bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener"/>
AuthenticationFilter类如下:
public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private boolean postOnly = true;
public CustomUsernamePasswordAuthenticationFilter() {
super("/j_spring_security_check");
}
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);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
if(this.getAuthenticationManager()==null){
logger.info("Authentication manager is null.");
} else {
logger.info("Authentication manager was "+this.getAuthenticationManager().getClass().getName());
}
return this.getAuthenticationManager().authenticate(authRequest);
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setUsernameParameter(String usernameParameter) {
this.usernameParameter = usernameParameter;
}
public void setPasswordParameter(String passwordParameter) {
this.passwordParameter = passwordParameter;
}
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getUsernameParameter() {
return usernameParameter;
}
public final String getPasswordParameter() {
return passwordParameter;
}
}
UserDetails类如下:
public class DAOUserDetailsService implements UserDetailsService {
private DataSource dataSource;
public void setDataSource(DAODataSource dataSource) {
this.dataSource = dataSource;
}
public DAOUserDetailsService () { }
public DAOUserDetailsService (DAODataSource dataSource) {
this.dataSource = dataSource;
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
DataSource ds = dataSource;
PreparedStatement userStatement = null;
try {
Connection con = ds.getConnection();
String userQuery = "SELECT USER_ID, USER_PASSWORD, USER_ENABLED FROM USER WHERE USER_ID = ?";
userStatement = con.prepareStatement(userQuery);
userStatement.setString(0, username);
ResultSet userResults = userStatement.executeQuery();
if (userResults.next()) {
final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority(
"supervisor");
final SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority(
"user");
Collection<GrantedAuthority> authorityList = new ArrayList<GrantedAuthority>();
authorityList.add(supervisorAuthority);
authorityList.add(userAuthority);
return new User(userResults.getString(0), userResults.getString(1), authorityList);
}
throw new UsernameNotFoundException(username);
} catch (SQLException e) {
throw new UsernameNotFoundException(e.toString());
}
finally {
if (userStatement != null) {
try {
userStatement.close();
} catch (SQLException e) {
throw new UsernameNotFoundException(e.toString());
}
}
}
}
}
请就这个问题提供一些想法。
提前致谢。
最佳答案
您可以创建LoggerListener的实现以调查更多原因。
public class LoggerListener implements ApplicationListener<AbstractAuthorizationEvent> {
private static final Log logger = LogFactory.getLog(LoggerListener.class);
public void onApplicationEvent(AbstractAuthorizationEvent event) {
//investigation code
}
}
我有一个非常类似的问题,原因是代码另一部分的一个ClassCastException,一个 Controller 。