開発者ドキュメント

Spring SecurityでのX.509認証


1概要

この記事では、

HTTPS(

HTTP over SSL

)プロトコルを使用する場合の

X.509証明書認証__ –

通信ピアの身元の確認

の主な使用例に焦点を当てます。

簡単に言うと、安全な接続が確立されている間、クライアントはその証明書(信頼できる認証局によって発行されたもの)に従ってサーバーを検証します。

しかしそれ以外にも、

Spring Security



X.509

を使用して、接続中にサーバーを通じて

クライアントの身元を確認する

ことができます。これは


“相互認証”と呼ばれます。


ここでもその方法について説明します。

最後に、この種の認証を使用することが意味がある場合には、ここで触れます。

サーバーの検証を実証するために、簡単なWebアプリケーションを作成し、ブラウザにカスタム認証局をインストールします。

そして、[相互認証]では、クライアント証明書を作成し、検証済みのクライアントのみを許可するようにサーバーを変更します。


2キーストア

  • オプション要件** :暗号強度の高い鍵を暗号化および復号化機能と一緒に使用するには、

    JVM.

    にインストールされた

    Java Cryptography Extension(JCE)無制限強度管轄ポリシーファイル

    が必要です。

これらは、例えばhttp://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html[Oracle]からダウンロードできます(ダウンロードに含まれるインストール手順に従ってください)。 Linuxディストリビューションの中には、パッケージマネージャを介してインストール可能なパッケージを提供するものもあります。

Springアプリケーションで

X.509認証

を実装するには、まず

Java Key-Store



JKS

)形式の

keystore

を作成します。

この

keystore



有効な証明書

authority

または一連の証明書

authorities


と私たちのサーバー用の自身の証明書を含まなければなりません。後者は含まれている

authorities

の一つによって署名されなければならず、そしてサーバが実行されている

hostname

にちなんで命名されなければなりません。ここでは

Java



keytool


アプリケーションを使用します。


  • keytool

    を使って

    keys



    certificates

    を作成するプロセス(コードhttps://github.com/eugenp/tutorials[on

    Github

    ])は、このセクションを完成するのに必要なすべてのステップを含む、コメント付きの

    Makefile

    をGNU

    make

    に提供します。いくつかの環境変数を使って簡単にカスタマイズすることもできます。

  • ヒント:**

    オールインワンステップ

    として、引数なしで

    make

    を実行できます。

ブラウザにインポートするための

keystore



truststore

、および2つの証明書(1つは

localhost

用、もう1つは

“ cid”

と呼ばれる)を作成します。

認証局を使用して新しい

keystore

を作成するには、次のように

make

を実行します。

$> make create-keystore PASSWORD=changeit

それでは、作成した

keystore

に開発用ホストの証明書を追加し、

certificate authority

で署名します。

$> make add-host HOSTNAME=localhost


クライアント認証

を許可するには、

“truststore”

と呼ばれる

keystore

も必要です。この

信頼ストア

は私たちの

認証局

と許可されたクライアントすべての有効な証明書を含まなければなりません。

keytool

の使い方については、次のセクションの

Makefile

を参照してください____:

$> make create-truststore PASSWORD=changeit
$> make add-client CLIENTNAME=cid


3アプリケーション例

SSLで保護されたサーバープロジェクトは、次のリンクで構成されます。/spring-boot-application-configuration[

@ SpringBootApplication

]アノテーション付きアプリケーションクラス-java-based-configuration[@Configuration])



application.properties__設定ファイル、そしてとてもシンプルなMVCスタイルのフロントエンド。

アプリケーションがしなければならないのは、

HTML

ページに

“Hello \ {User}!”

メッセージを表示することだけです。これにより、ブラウザでサーバー証明書を調べて、接続が検証されて保護されていることを確認できます。

まず、3つの

Spring Boot Starter

バンドルを含む新しい

Maven

プロジェクトを作成します。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>
  • 参考のために:**

    Maven Central

    にバンドルがあります(https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a%3A %22spring-boot-starter-security%22[セキュリティ]、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a%3A %22spring-boot-starter-web%22[web]、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a%3A %22spring-boot-starter-thymeleaf%22[thymeleaf])。

次のステップとして、メインアプリケーションクラスとユーザーコントローラを作成します。

@SpringBootApplication
public class X509AuthenticationServer {
    public static void main(String[]args) {
        SpringApplication.run(X509AuthenticationServer.class, args);
    }
}

@Controller
public class UserController {
    @RequestMapping(value = "/user")
    public String user(Model model, Principal principal) {

        UserDetails currentUser
          = (UserDetails) ((Authentication) principal).getPrincipal();
        model.addAttribute("username", currentUser.getUsername());
        return "user";
    }
}

それでは、アプリケーションに

keystore

の場所とアクセス方法を教えます。

SSL

を「有効」ステータスに設定し、標準のリスニングポートを

セキュアな接続を示す

に変更します。

さらに、基本認証を介してサーバーにアクセスするための

user-details

を構成します。

server.ssl.key-store=../keystore/keystore.jks
server.ssl.key-store-password=${PASSWORD}
server.ssl.key-alias=localhost
server.ssl.key-password=${PASSWORD}
server.ssl.enabled=true
server.port=8443
security.user.name=Admin
security.user.password=admin

これは、

resources/templates

フォルダーにあるHTMLテンプレートになります。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>X.509 Authentication Demo</title>
</head>
<body>
    <h2>Hello <span th:text="${username}"/>!</h2>
</body>
</html>

このセクションを終えてサイトを見る前に、私たちが生成した認証局を私たちが選んだブラウザに


信頼できる証明書


としてインストールする必要があります。


Mozilla Firefox

用の

認証局

のインストール例は次のようになります。

  1. アドレスバーに「

    about:preferences

    」と入力します.


  2. 詳細 – >証明書 – >証明書の表示 – >認証機関

    を開きます.



  3. Import


    をクリック


  4. Baeldung tutorials

    フォルダーとそのサブフォルダーを見つけます.


spring-security-x509/keystore




ca.crt


ファイルを選択して、


OK


をクリックします。



  1. このCAを信頼してWebサイトを識別させる」を選択し、



    OK__

    • 注:**

      認証機関

      を信頼できる機関の一覧に追加したくない場合は、安全でないと記載されていても、除外__してWebサイトを厳重に表示することができます。ただし、アドレスバーに「黄色い感嘆符」の記号が表示され、安全でない接続を示しています。

その後、spring-security-x509-basic-authモジュールに移動して実行します。

mvn spring-boot:run

最後に、


https://localhost:8443/user


にアクセスし、

application.properties

からユーザーの認証情報を入力すると、「Hello Admin!」というメッセージが表示されます。これで、アドレスバーの「緑色の錠前」の記号をクリックして接続の状態を確認できるようになりました。これは安全な接続であるはずです。

リンク:/uploads/Screenshot

20160822

205015.png%20465w[]


4相互認証

このセクションでは、

Spring Security

を使用してユーザーにデモWebサイトへのアクセスを許可します。この手続きはログインフォームを時代遅れにします。

しかし、サーバーの変更を続ける前に、この種の認証を提供することが理にかなっているときに簡単に説明します。

  • 長所:**

  • __ X.509クライアント証明書の秘密鍵は

    他よりも強い

ユーザー定義パスワード** しかし、それは秘密にされなければなりません!

  • 証明書を使うと、クライアントの

    アイデンティティ

    はよく知られています**

簡単に確認できます。

  • これ以上パスワードを忘れたことはありません!

  • 短所:**

  • あなたは各ユーザーに対して、によって検証されるべきであることを覚えておく必要があります

サーバーの場合は、その証明書を構成済みの

truststore

にインストールする必要があります。少数のクライアントしかない小規模なアプリケーションでは、これはおそらく実用的かもしれません。

証明書の秘密鍵はクライアントにインストールする必要があります。

応用。実際のところ、

X.509クライアント認証


はデバイスに依存

しているため、インターネットカフェなどの公共の場でこの種の認証を使用することは不可能です。

侵害されたクライアント証明書を無効にするメカニズムが必要です。

続けるには、


WebSecurityConfigurerAdapter


から拡張するように

X509AuthenticationServer

を変更し、提供されているいずれかのconfigureメソッドをオーバーライドします。ここでは、ユーザ名を抽出するために証明書の

Common Name(CN)

フィールドを解析するように

x.509

メカニズムを設定します。

この抽出されたユーザー名を使用して、

Spring Security

は提供された

UserDetailsS​​ervice

で一致するユーザーを探します。そのため、デモユーザーを1人含むこのサービスインターフェイスも実装します。

  • ティップ:** 本番環境では、この

    UserDetailsS​​ervice

    は、例えばリンクからそのユーザーをロードできます。/spring-jdbc-jdbctemplate


    _.

    _

事前承認/事後承認を有効にして、クラスに

@ EnableWebSecurity



@ EnableGlobalMethodSecurity

のアノテーションを付けていることに注意してください。

後者では、きめ細かいアクセス制御のために、リソースに

@ PreAuthorize



@ PostAuthorize

のアノテーションを付けることができます。

@SpringBootApplication
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class X509AuthenticationServer extends WebSecurityConfigurerAdapter {
    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
          .and()
          .x509()
            .subjectPrincipalRegex("CN=(.** ?)(?:,|$)")
            .userDetailsService(userDetailsService());
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String username) {
                if (username.equals("cid")) {
                    return new User(username, "",
                      AuthorityUtils
                        .commaSeparatedStringToAuthorityList("ROLE__USER"));
                }
            }
        };
    }
}

前述のように、コントローラで

式ベースのアクセス制御

を使用できるようになりました。具体的には、

@ Configuration

:




@ EnableGlobalMethodSecurity

アノテーションのおかげで、私たちの認可アノテーションは尊重されます

@Controller
public class UserController {
    @PreAuthorize("hasAuthority('ROLE__USER')")
    @RequestMapping(value = "/user")
    public String user(Model model, Principal principal) {
        ...
    }
}

考えられるすべての認証オプションの概要は、


公式文書

にあります。

最後の修正ステップとして、

truststore

がどこにあり、

SSLクライアント認証

が必要かをアプリケーションに通知する必要があります(

server.ssl.client-auth = need

)。

それで、私たちは

application.properties

に以下を入れます:

server.ssl.trust-store=../keystore/truststore.jks
server.ssl.trust-store-password=${PASSWORD}
server.ssl.client-auth=need

それでは、アプリケーションを実行してブラウザで


https://localhost:8443/user


にアクセスすると、ピアを検証できないため、Webサイトを開くことが拒否されたことがわかります。そのため、ここで概説した

クライアント証明書

をインストールする必要があります。

  1. アドレスバーに「

    about:preferences

    」と入力します.


  2. Advanced – > View Certificates – > Your Certificates

    を開きます.



  3. Import


    をクリック


  4. Baeldung tutorials

    フォルダーとそのサブフォルダーを見つけます.


spring-security-x509/keystore




cid.p12


ファイルを選択して、


OK


をクリックします。

  1. 証明書のパスワードを入力して


    OK


    をクリックしてください.

最後のステップとして、Webサイトを含むブラウザタブを更新し、新しく開いた選択ダイアログでクライアント証明書を選択します。

リンク:/uploads/Screenshot

20160822

211057.png%201174w[]


“Hello cid!”

のようなウェルカムメッセージが表示されたら、成功しました。

** 5 XMLによる相互認証

**

リンクに

X.509クライアント認証

を追加することもできます:/spring-security-digest-authentication[

XML

のhttpセキュリティ設定]

<http>
    ...
    <x509 subject-principal-regex="CN=(.** ?)(?:,|$)"
      user-service-ref="userService"/>

    <authentication-manager>
        <authentication-provider>
            <user-service id="userService">
                <user name="cid" password="" authorities="ROLE__USER"/>
            </user-service>
        </authentication-provider>
    </authentication-manager>
    ...
</http>

基礎となる

Tomcat

を設定するには、

keystore



truststore

をその

conf

フォルダーに入れて

server.xml

を編集する必要があります。

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" scheme="https" secure="true"
    clientAuth="true" sslProtocol="TLS"
    keystoreFile="${catalina.home}/conf/keystore.jks"
    keystoreType="JKS" keystorePass="changeit"
    truststoreFile="${catalina.home}/conf/truststore.jks"
    truststoreType="JKS" truststorePass="changeit"/>
  • ヒント:**

    clientAuth



    “want”

    に設定されていると、クライアントが有効な証明書を提供していなくても

    SSL

    は有効のままです。しかしこの場合、セキュリティ保護されたリソースにアクセスするために、2番目の認証メカニズム、たとえばログインフォームを使用する必要があります。


6. 結論

  • 要約** では、開発環境用に、認証局と自己署名証明書を含むキーストアを作成する方法を学びました。

認証局とクライアント証明書を含む

信頼ストアを作成しました。そして、クライアント側でサーバーを検証する

とサーバー側でクライアントを検証する** 両方を使用しました。


Makefile

について学んだことがあれば、



証明書

の作成、

証明書要求

の作成、および署名付き証明書のインポート


をJava

keytool

で行うことができるはずです。

さらに、これで

クライアント証明書



PKCS12

形式にエクスポート** して、ブラウザのようなクライアントアプリケーション、たとえば

Mozilla Firefox

で使用できるようになりました。

そして、私たちは

Spring Security X.509クライアント認証

を使うことが理にかなっているときに議論しました、それであなたのWebアプリケーションにそれを実装するかどうか、決めるのはあなた次第です。

最後に、この記事のソースコードを見つけます。


on
Github

.

モバイルバージョンを終了