2016-04-05 3 views
0

У меня довольно простая система auth на основе SpringSecurity и очень похожа на найденную here (немного сложнее).SpringWebSecurity: Bad Credentials по отсутствующей причине

Тем не менее, когда я выполняю процедуру входа в систему, SpringSecurity выдает ошибку Bad Credentials в соответствии с ее конфигурацией.

Просматривая код, я не мог найти причину, потому что во время выполнения имя пользователя, пароль, включен и роли в соответствии с тем, что хранится в БД. Таким образом, я думаю, что это может быть связано с плохой конфигурацией или логикой.

Единственное, что может быть ошибкой, согласно журналу: WARNING: Encoded password does not look like BCrypt, но я прочитал, что это может быть нормально для каждой аутентификации.

Может ли кто-нибудь помочь мне проверить конфигурацию? Благодаря!!

package com.company.config; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.crypto.password.PasswordEncoder; 

@Configuration 
@EnableWebSecurity 
public class AppSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    @Qualifier("userDetailsService") 
    UserDetailsService userDetailsService; 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ 
     auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); 
} 

@Bean 
public PasswordEncoder passwordEncoder() { 
    PasswordEncoder encoder = new BCryptPasswordEncoder(); 
    return encoder; 
} 


@Override 
protected void configure(HttpSecurity http) throws Exception { 

    http.authorizeRequests() 
      .antMatchers("**/admin/**").access("hasAnyRole('ROLE_ADMIN','ROLE_SUPERADMIN')") 
      .antMatchers("/superadmin/**").access("hasRole('ROLE_SUPERADMIN')") 
      .antMatchers("**/user/**").access("hasAnyRole('ROLE_USER','ROLE_ADMIN','ROLE_SUPERADMIN')") 
      .antMatchers("/resources/**").permitAll() 
      .antMatchers("/messages/**").permitAll() 
      .and() 
      .formLogin() 
       .loginPage("/login") 
       .usernameParameter("username") 
       .passwordParameter("password") 
       .defaultSuccessUrl("/user/home") 
       .failureUrl("/403") 
       .permitAll() 
      .and() 
       .exceptionHandling().accessDeniedPage("/403") 
      .and() 
       .logout().logoutUrl("/logout") 
      .and() 
       .csrf().disable(); 
    } 
} 

package com.company.service.impl; 

import java.util.ArrayList; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.security.core.userdetails.User; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 

import com.company.dao.UsuarioDao; 
import com.company.model.UserRole; 
import com.company.model.Usuario; 

@Service("userDetailsService") 
public class MyUserDetailsService implements UserDetailsService{ 

    @Autowired 
    private UsuarioDao usuarioDao; 


    @Transactional(readOnly=true) 
    public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException { 

     Usuario usuario = usuarioDao.findByChave(username); 
     List<GrantedAuthority> authorities = buildUserAuthority(usuario.getUserRole()); 

     return buildUserForAuthentication(usuario, authorities); 

    } 

    private User buildUserForAuthentication(Usuario user, 
     List<GrantedAuthority> authorities) { 

     User usr= new User(user.getUsername(), user.getPassword(), 
      user.isEnabled(), true, true, true, authorities); 

     System.out.println(usr.toString()); 
/* 
* Prints: [email protected]: 
* Username: SMITH; Password: [PROTECTED]; Enabled: true; 
* AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: 
* true; Not granted any authorities 
*/ 

     return usr; 

    } 

    private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles){ 

     Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>(); 

     // Build user's authorities 
     for (UserRole userRole : userRoles) { 
      setAuths.add(new SimpleGrantedAuthority(userRole.getRole())); 
     } 

     List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths); 

     return Result; 
    } 

} 
+2

Если вы получаете это сообщение, его означает, что то, что вы получаете из базы данных, поскольку пароль не является тем, что является e xpected. Проверьте кодировку, длину поля ... Проверьте фактическое значение ... По-видимому, вы не храните правильный хеш, это то, что вам сообщает это сообщение. –

+0

@ M.Deinum, проблема обнаружена. Если вы хотите просмотреть ответ, я думаю, что это ценно. Спасибо за интерес. – Alex

ответ

0

После некоторых исследований я обнаружил проблему. Я имею дело с уже указанным паролем, предоставленным третьей стороной. Таким образом, я хранили его непосредственно в БД, а SpringSecurity работал со своим собственным шифрованием (BCrypt). Таким образом, SpringSecurity объединила две разные строки, обозначенные буквой, породив проблему (хороший отзыв был указан в сообщении WARNING, упомянутом в вопросе).

Таким образом, я отключил @Bean PasswordEncoder в AppSecurityConfig, потому что нет необходимости его хранить (помните, что я уже имею дело с предварительно введенными паролями). После этого все работало нормально.

Для получения дополнительной информации, это ценно взглянуть на эти вопросы и ответы:

Смежные вопросы