web-dev-qa-db-ja.com

Spring Securityのカスタム認証とパスワードエンコーディング

そこにチュートリアルがありますか、Spring-Securityで次のことを行う方法についてのポインタがありますか?

タスク:

データベースから認証ユーザー名のソルトを取得し、それを使用して提供されたパスワードを(ログインページから)暗号化し、保存されている暗号化パスワードと比較する必要があります(別名ユーザー認証)。

追加情報:

カスタムデータベース構造を使用します。 UserDetailsオブジェクトは、カスタムUserDetailsServiceを介して作成され、カスタムDAOProviderを使用してデータベースから情報を取得します。

これまでのsecurity.xmlファイル:

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
    </authentication-provider>
</authentication-manager>

今、私は必要になると思います

        <password-encoder hash="sha" />

しかし、他に何ですか?パスワードをエンコードするためにデータベース提供のソルトを使用するようにスプリングセキュリティに指示するにはどうすればよいですか?


編集

私は このSO の投稿は有益であるが、十分ではないことを見つけました:XMLでソルトソースを定義して、パスワードエンコーダーで使用する場合:

        <password-encoder ref="passwordEncoder">                
            <salt-source ref="saltSource"/>
        </password-encoder>

カスタムソルトを使用するには、カスタムSaltSourceを作成する必要があります。しかし、それはUserDetailsオブジェクト内にはありません。そう...

代替1:

UserDetailsのカスタム実装を使用して、saltプロパティを使用できますか?

<beans:bean id="saltSource" class="path.to.MySaltSource"
    p:userPropertyToUse="salt"/>

そして

@Service("userDetailsService") 
public class UserDetailsServiceImpl implements UserDetailsService {
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {

        // ...
        return buildUserFromAccount(account);
    }

    @Transactional(readOnly = true)

    UserDetailsImpl buildUserFromAccount(Account account){

        // ... build User object that contains salt property
}

カスタムユーザークラス:

public class UserDetailsImpl extends User{

    // ...

    private String salt;

    public String getSalt() { return salt; }

    public void setSalt(String salt) { this.salt = salt; }
}

security.xml:

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="sha">                
        <salt-source ref="saltSource"/>
    </password-encoder>
    </authentication-provider>
</authentication-manager>

<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource" p:userPropertyToUse="salt"/>


代替案2:

そうでない場合、特定のSaltSourceのソルトをデータベースから抽出するために、userNameにaccountDAOを挿入する必要があります。

しかし:Spring SecurityはSaltSourceをどのように呼び出しますか?常にsaltSource.getSalt(userDetails)で?

次に、SaltSourceaccountDAOuserDetails.accountNameを使用してソルトを取得することを確認する必要があります。


Edit2:

ちょうど私のアプローチがレガシーであることを学んだ.. :(だから私はStandardPasswordEncoderを使用するだけだと思う​​(正確に使用する方法をまだ理解する必要がある)。

ところで:Userクラスを拡張し、saltプロパティを追加するだけのカスタムUserDetailsクラスを使用して最初のオプションを実装し、SO =編集1で言及された投稿...


編集3:

StandardPasswordEncoderが機能するようになったので、ここにいくつかのポインタを残します。

認証にStandardPasswordEncoderを使用します。

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


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

これには、バージョン3.1.0.RCのspring-security-cryptoモジュールが必要ですか?私の知る限りでは。 3.0を含むリポジトリが見つかりませんでした。バージョン(3.0.6などを含むバージョンがリストされていた場合でも)。また、ドキュメントでは、春のセキュリティ3.1について説明しているので、考えてみます。

ユーザーを作成するとき(私にとっては管理者だけがそれを行うことができます)、私は

        StandardPasswordEncoder encoder = new StandardPasswordEncoder();
        String result = encoder.encode(password);

できました。

Springセキュリティはランダムにソルトを作成し、データベースに保存する前にパスワード文字列に追加するため、ソルト列はもう必要ありません

ただし、コンストラクター引数(new StandardPasswordEncoder("12345");)としてグローバルソルトを提供することもできますが、<constructor-arg name="secret" value "12345" />で静的文字列を提供する代わりに、Beanからその値を取得するためのセキュリティ構成を設定する方法を知りませんでした。しかし、とにかくそれがどれだけ必要かはわかりません。

52
Pete

私は自分の問題を解決し、他のコメントや回答が与えられなかったため、これを回答済みとしてマークします。

編集1-代替1元の質問に答えます

[〜#〜] but [〜#〜]カスタマイズされたパスワードソルティングはレガシーセキュリティアプローチであり、Spring Security 3.1ではもう必要ないことを学ばなければならなかった。

編集パスワードで保存された自動化されたソルトにStandardPasswordEncoderを使用する方法についてのポインタを残しました。

34
Pete

それが価値があることについて、私はあなたが説明したことを詳述したこのブログ投稿を書きました: http://rtimothy.tumblr.com/post/26527448708/spring-3-1-security-and-salting-passwords =

4
rooftop

Beanからグローバルソルトを取得するには、Spring Expression LanguageまたはSpELを使用します。

<beans:bean id="encoder" 
        class="org.springframework.security.crypto.password.StandardPasswordEncoder">
    <constructor-arg value="#{someotherBean.somePropertyWithAGetterMethod"/>
</beans:bean>
0
paulchapman