Spring Security: kodowanie haseł w DB i w applicationkontekst

Mieć config (applicationContext-security.xml):

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

From other side have sqls from my dataSource (it ' s JdbcDaoImpl):

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

Jest teraz słowo o sha w tym kodzie, więc hasło wybrane ze standardowej tabeli Spring Security users nie jest zakodowane.

Być może powinienem podać jakiś atrybut sha dla kolumny password w moim Config mapowania hibernate tutaj:

<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>

Na razie hasło zapisane w DB tak jak jest, ale powinno być zakodowane.

Jak friend applicationContext config i DB queries to be the same password encoding?

Author: falsarella, 2011-12-15

7 answers

Jeśli sam wybierasz system haszujący, zamiast budować aplikację za pomocą istniejącej bazy danych, która już zawiera haszowane hasła, powinieneś upewnić się, że Twój algorytm haszujący również używa soli. Nie używaj zwykłego trawienia.

Dobrym wyborem jest bcrypt, który Teraz wspieramy bezpośrednio w Spring Security 3.1 poprzez BCryptPasswordEncoder (zaimplementowany przy użyciu jBCrypt ). To automatycznie generuje sól i łączy ją z wartością hash w jednym Sznurek.

Niektóre bazy danych mają wbudowaną obsługę hashowania (np. Postgres ). W przeciwnym razie musisz samodzielnie hashować hasło przed przekazaniem go do JDBC:

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

To wszystko, co musisz zrobić, aby zakodować hasła podczas tworzenia użytkownika.

Do uwierzytelniania można użyć czegoś w rodzaju:

<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>
 75
Author: Shaun the Sheep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-21 15:20:26

Trochę więcej wyjaśnień na temat zaakceptowanej odpowiedzi. Mam nadzieję, że to komuś pomoże.

Hashuj hasło samodzielnie przed umieszczeniem go w bazie danych:

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

Dodaj bcryptpasswordencoder bean do swojego security-config.xml

Dodaj passwordEncoder jako właściwość do klasy dostawcy uwierzytelniania. Autowire it or provide setter and getter methods.

@AutoWired
private BCryptPasswordEncoder passwordEncoder;

Get the property while you authendicate user for login

<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>

I w klasie authenticating pasują zarówno hasła

 new BCryptPasswordEncoder().matches(plainTextPasswdFromUserInput, hashedPasswdFromDb)
 8
Author: false9striker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-10 18:48:06

W prosty sposób można zrobić coś takiego jak w 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"/>

W Javie

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

Następnie przetestuj to

System.out.println(encodePasswordWithBCrypt("fsdfd"));
 5
Author: user2368100,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-06 17:13:47

Używając Spring Security 3.1, spróbuj tego:

<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>

Co nowego: authentication-provider wskazuje na service i service wskazuje na datasource.

Edit: w Javie będziesz musiał zakodować hasło czymś takim:

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

Warn: bądź ostrożny! Nie mieszaj SHA Z MD5 !

Jeśli ustawisz password-encoder z authentication-provider jako SHA, musisz kodować w Javie w ten sam sposób, aby zachować spójność. Ale jeśli kodujesz w Javie jako MD5, jako próbka, którą znalazłeś, nie zapomnij ustawić hash na "md5". DigestUtils zapewnia również koder md5:

DigestUtils.md5(request.getParameter("password"));
 5
Author: falsarella,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-15 23:06:08

Just a tip for doing it with adnotations

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

}
 4
Author: Alireza Fattahi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-26 06:33:09

Przyjęta odpowiedź jest prawidłowa. Przetestowałem go za pomocą spring 3.1 i BCrypt algorytm kodowania.

Podczas tworzenia użytkownika.

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

Gdy użytkownik loguje się, pamiętaj, użyj zwykłego hasła (nie hashowanego ). tak jak:

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

Oto security-config:

    <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>
Mam nadzieję, że to komuś pomoże!
 2
Author: maoyang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-31 10:27:03

Z 3.1.x to mapowanie nie działa dla auth. Sposób pracy to:

<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>
 1
Author: z0mb1ek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-11 15:17:33