2011-12-15 13 views
31

Have config (ApplicationContext-security.xml):Wiosna bezpieczeństwa: kodowanie haseł w DB w ApplicationContext

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

z drugiej strony mają zapytania SQL z moim dataSource (to JdbcDaoImpl):

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

W tym kodzie znajduje się teraz słowo o numerze sha, dlatego hasło wybrane ze standardowej tabeli Spring Security users nie jest zakodowane.

Może powinienem zapewnić pewne sha atrybut password kolumny w moim hibernacji mapowania config 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 do DB, jak jest, ale powinny być kodowane.

Jak zaprzyjaźnić się z applicationContext zapytaniami config i DB, które mają być tym samym kodowaniem hasła?

Odpowiedz

73

Jeśli wyborze systemu mieszaja siebie, zamiast budowania aplikacji z wykorzystaniem istniejącej bazy danych, która zawiera już zakodowane hasła, to należy upewnić się, że algorytm mieszania wykorzystuje również sól. Nie używaj zwykłego skrótu.

Dobrym wyborem jest bcrypt, który teraz obsługujemy bezpośrednio w Spring Security 3.1 poprzez BCryptPasswordEncoder (zaimplementowano przy użyciu jBCrypt). To automatycznie generuje sól i łączy ją z wartością mieszania w pojedynczym łańcuchu.

Niektóre bazy danych mają wbudowaną obsługę mieszania (na przykład Postgres). W przeciwnym razie trzeba hash hasła przy sobie przed przekazaniem go do JDBC:

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

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

przypadku uwierzytelniania, należy użyć coś takiego:

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

Luke Taylor, dziękuję, że chciałem wiedzieć - że powinienem podać hasło hasłem, zanim wstawię je do DB. – sergionni

+0

o soli, wiem, to jest kolejna faza mojego wyzwania bezpieczeństwa)) – sergionni

+4

Jeśli używasz czegoś podobnego do bcrypt, to jest ono automatycznie obsługiwane, więc nie ma żadnego wyzwania :-). Nie musisz sam sobie radzić z solą. –

5

Korzystanie Wiosna Zabezpieczenia 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 punkty service i service punktów datasource.

Edit: W Javie trzeba będzie zakodować hasło z czymś takim:

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

Warn: Bądź ostrożny! Nie mieszaj SHA z MD5!

Jeśli ustawisz password-encoder z następujących authentication-provider jak SHA, trzeba kodować w Javie w ten sam sposób, aby utrzymać spójne. Jeśli jednak znajdziesz się w Javie jako MD5, jako próbkę, którą znalazłeś, nie zapomnij ustawić wartości mieszania hash na "md5". DigestUtils zapewnia również md5 koder:

DigestUtils.md5(request.getParameter("password")); 
+0

Tak, wiem, ale nie zapytać o moje pytanie, jak zapewnić, że hasło użytkownika zaoszczędzone zakodowany do DB – sergionni

+1

dobrze, ja nie Wiesz, co masz na myśli mówiąc "dostarczaj", ale aby przetrwać, użyłem [DigestUtils] (http://commons.apache.org/codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html). – falsarella

+1

@sergionni: Przepraszam, ale nie znam konfiguracji applicationContext do automatycznego zapisania zakodowanego hasła, jak już wspomniałem, użyłem DigestUtils z Apache commons. – falsarella

8

Trochę więcej wyjaśnień na przyjętym odpowiedź. Mam nadzieję, że to komuś pomaga.

Hash hasło samemu przed wprowadzeniem go do bazy danych:

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

Dodaj BCryptPasswordEncoder fasolkę do zabezpieczenia-config.xml

Dodaj passwordEncoder jako obiekt do klasy dostawcy uwierzytelniania. Autowiruj go lub zapewnij metody setera i gettera.

@AutoWired 
private BCryptPasswordEncoder passwordEncoder; 

Get właściwość podczas authendicate użytkownika do logowania

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

A w klasie uwierzytelniający meczu obu haseł

new BCryptPasswordEncoder().matches(plainTextPasswdFromUserInput, hashedPasswdFromDb) 
1

z 3.1.x to odwzorowanie robi praca dla uwierzytelniania. sposób robocza:

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

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

System.out.println(encodePasswordWithBCrypt("fsdfd")); 
2

Przyjęta odpowiedź jest właściwa. Testowałem go z wiosną 3.1 i algorytm kodowania BCrypt.

Po utworzeniu użytkownika.

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

Gdy login użytkownika, Pamiętaj, użyj zwykłego hasła (nie hashed). po prostu lubię:

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> 

nadzieję, że komuś pomóc!

2

Just a wskazówka dla robią to z adnotacjami

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

} 
Powiązane problemy