Spring Security: кодировка пароля в БД и в текстовом приложении - PullRequest
33 голосов
/ 15 декабря 2011

Конфигурация (applicationContext-security.xml):

<authentication-manager alias="authenticationManager">
    <authentication-provider>
    <password-encoder hash="sha"/>
        <jdbc-user-service data-source-ref="dataSource"/>
    </authentication-provider>
</authentication-manager>

с другой стороны, есть SQL от моего dataSource (это JdbcDaoImpl ):

...
    public static final String DEF_USERS_BY_USERNAME_QUERY =
            "select username,password,enabled " +
            "from users " +
            "where username = ?";
...

Теперь в этом коде есть слово о sha, поэтому пароль, выбранный из стандартной таблицы Spring Security users, не закодирован.

Возможно, я должен предоставить некоторый атрибут sha для столбца password вмоя конфигурация отображения hibernate здесь:

<class name="model.UserDetails" table="users">
    <id name="id">
        <generator class="increment"/>
    </id>
    <property name="username" column="username"/>
    <property name="password" column="password"/>
    <property name="enabled" column="enabled"/>
    <property name="mail" column="mail"/>
    <property name="city" column="city"/>
    <property name="confirmed" column="confirmed"/>
    <property name="confirmationCode" column="confirmation_code"/>

    <set name="authorities" cascade="all" inverse="true">
        <key column="id" not-null="true"/>
        <one-to-many class="model.Authority"/>
    </set>

</class>

На данный момент пароль сохранен в БД как есть, но должен быть закодирован.

Как дружить applicationContext config и запросы БД, чтобы быть тем же паролемкодирование

Ответы [ 7 ]

77 голосов
/ 16 декабря 2011

Если вы выбираете систему хеширования самостоятельно, а не создаете приложение с использованием существующей базы данных, которая уже содержит хешированные пароли, то вам следует убедиться, что в вашем алгоритме хеширования также используется соль.Не просто используйте простой дайджест.

Хорошим выбором является bcrypt, который мы теперь напрямую поддерживаем в Spring Security 3.1 через BCryptPasswordEncoder (реализовано с использованием jBCrypt ).Это автоматически генерирует соль и объединяет ее со значением хеш-функции в одной строке.

Некоторые базы данных имеют встроенную поддержку хеширования (например, Postgres ).В противном случае вам необходимо самостоятельно хешировать пароль перед его передачей в JDBC:

String password = "plaintextPassword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);

Это все, что вам нужно сделать для кодирования паролей при создании пользователя.

Для аутентификации выбудет использовать что-то вроде:

<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

<bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <property name="userDetailsService" ref="yourJdbcUserService" />
  <property name="passwordEncoder" ref="encoder" />
</bean>
8 голосов
/ 05 февраля 2013

Еще немного пояснений по поводу принятого ответа. Надеюсь, это кому-нибудь поможет.

Хешируйте пароль самостоятельно перед тем, как поместить его в базу данных:

String password = "plaintextPassword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);

Добавьте bean-компонент BCryptPasswordEncoder в ваш security-config.xml

Добавить passwordEncoder как свойство в класс провайдера аутентификации. Autowire это или предоставить методы установки и получения.

@AutoWired
private BCryptPasswordEncoder passwordEncoder;

Получить собственность, пока вы аутентифицируете пользователя для входа в систему

<bean id="dbAuthenticationProvider" class="mypackage.auth.spring.DBAuthenticationProvider" >
    <property name="dataSource" ref="routingDataSource"></property>
    <property name="passwordEncoder" ref="encoder" />
    <property name="passwordQuery"
        value="select password as password from tbl where username=:username">
    </property> 
</bean>

А в классе аутентификации совпадают оба пароля

 new BCryptPasswordEncoder().matches(plainTextPasswdFromUserInput, hashedPasswdFromDb)
5 голосов
/ 10 мая 2013

Простым способом вы можете сделать что-то вроде в applicationContext-security.xml

<authentication-manager alias="authenticationManager">
   <authentication-provider>
    <password-encoder ref="encoder"/>
    <jdbc-user-service data-source-ref="dataSource"
       users-by-username-query="
          select username,password, enabled 
          from principal where username=?" 
       authorities-by-username-query="
          select p.username, a.authority from principal p, authority a
          where p.id = a.principal_id and p.username=?" 
    />
   </authentication-provider>
</authentication-manager> 

  <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

В Java

public static String encodePasswordWithBCrypt(String plainPassword){
    return new BCryptPasswordEncoder().encode(plainPassword);
}

Тогда проверь это

System.out.println(encodePasswordWithBCrypt("fsdfd"));
5 голосов
/ 15 декабря 2011

Используя Spring Security 3.1, попробуйте это:

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="service">
        <password-encoder hash="sha"/>
        <jdbc-user-service data-source-ref="dataSource"/>
    </authentication-provider>
</authentication-manager>

<beans:bean id="dataSource" ...>
    ...
</beans:bean>

<beans:bean id="service" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <beans:property name="dataSource" ref="dataSource"/>
        ...
</beans:bean>

Что нового: authentication-provider указывает на service и service указывает на datasource.

Редактировать: В Java вам придется кодировать пароль примерно так:

DigestUtils.sha(request.getParameter("password"));

Предупредить: Будьте осторожны! Не смешивайте SHA с MD5 !

Если вы установите password-encoder из authentication-provider как SHA , вам нужно будет кодировать в Java таким же образом, чтобы сохранить согласованность. Но если вы включили в Java как MD5 , как образец, который вы нашли, не забудьте установить для hash значение "md5". DigestUtils также предоставляет кодировщик md5:

DigestUtils.md5(request.getParameter("password"));
4 голосов
/ 26 декабря 2016

Просто совет, как делать это с аннотациями

@Configuration
@EnableWebSecurity
@PropertySource("classpath://configs.properties")
public class SecurityContextConfig extends WebSecurityConfigurerAdapter {


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

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


@Bean(name = "passwordEncoder")
public PasswordEncoder getPasswordEncoder(){
    return new BCryptPasswordEncoder();     
 }

}
2 голосов
/ 31 августа 2014

Принятый ответ правильный. Я протестировал его с алгоритмом spring 3.1 и BCrypt .

При создании пользователя.

PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword()));
userDao.save(userEntity);

Когда пользователь входит в систему, помните, используйте простой пароль ( не хэшируется ). просто как:

Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
Authentication result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);

Вот настройки безопасности:

    <bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userService" />
        <property name="hideUserNotFoundExceptions" value="false" />
        <property name="passwordEncoder" ref="encoder" />
    </bean>

Надеюсь, это кому-нибудь поможет!

1 голос
/ 11 апреля 2013

с 3.1.x это отображение не работает для аутентификации.Рабочий путь:

<beans:bean id='bCryptPasswordEncoder' class='org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder'></beans:bean>

<authentication-manager>
  <authentication-provider user-service-ref="userDetailsService">
          <password-encoder ref="bCryptPasswordEncoder"/>
  </authentication-provider>
</authentication-manager>
...