2015-08-21 4 views
2

Я использую Spring security version 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.springframew[email protected]4a159a52: Principal: support; Credentials: [PROTECTED]; Authenticated: false; Details: org.sprin[email protected]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.sprin[email protected]0: RemoteIpAddress: 204.238.52.177; SessionId: 9B49838B0DF4224E169EAF425C0AABE9; exception: null 

Здесь я получаю исключение в нуль!

Config: класс

<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()); 
       } 
      } 
     } 
    } 
} 

Просьба представить некоторые идеи по этому вопросу. Спасибо заранее.

ответ

3

В вашем классе DAOUserDetailsService:

... 
return new User(userResults.getString(0), userResults.getString(1), new ArrayList<GrantedAuthority>()); 
... 

вы вернетесь UserDeatils с пустыми органами. Таким образом, ваш пользователь зарегистрирован, но у него нет ролей (не авторизован).

+0

Я попытался добавить роли, все еще не работая. – Leejoy

+0

Это была проблема с SQL Statement. – Leejoy

4

Вы можете создать свою реализацию LoggerListener, чтобы исследовать больше причин.

public class LoggerListener implements ApplicationListener<AbstractAuthorizationEvent> { 

    private static final Log logger = LogFactory.getLog(LoggerListener.class); 


    public void onApplicationEvent(AbstractAuthorizationEvent event) { 

     //investigation code 
    } 
} 

У меня была очень похожая проблема, и причиной было одно исключение ClassCastException в другой части кода, один контроллер.

2

При создании GrantedAuthority вы должны добавить префикс ROLE_. Таким образом, вы код должен выглядеть следующим образом:

// For xxx 
final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority(
        "ROLE_xxx"); 

Альтернатива: Вы можете удалить префикс по умолчанию в RoleVoter но ИМО это не является хорошим выбором, потому что ROLE_ Приставка на самом деле помогает RoleVoter понять, что remaning струны.

<bean id="roleVoter" class="org.springframework.security.vote.RoleVoter"> 
     <property name="rolePrefix" value=""></property> 
</bean> 
Смежные вопросы