67465


[maven - How to add new user to Spring Security at runtime - Stack
Overflow](https://stackoverflow.com/questions/32244745/how-to-add-new-user-to-
spring-security-at-runtime)
の[回答](https://stackoverflow.com/a/32282443/1979953)で

引用:

[code]

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
    UserDetails user = new User("user@example.com", passwordEncoder.encode("s3cr3t"), authorities);
    userDetailsManager.createUser(user);
    Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, authorities);
    SecurityContextHolder.getContext().setAuthentication(authentication);
    
[/code]

というのがありました。

おそらく `userDetailsManager.createUser(user);` でユーザー登録がDBに反映されていることと思います。その後の

[code]

    SecurityContextHolder.getContext().setAuthentication(authentication);
    
[/code]

の部分はなぜ行っているのでしょうか？（どういった場面が想定されているのでしょうか？）

たとえば [Spring Securityでユーザ認証を実装してみる -
ももいろテクノロジー](http://inaz2.hatenablog.com/entry/2017/04/18/222721)
こちらのサイトにもユーザー登録の例がありましたが`setAuthentication` に該当するようなものは見かけられませんでした。


CC BY-SA 4.0
2020-06-08T13:45:13.527
67424
2020-06-12T19:39:38.197
2020-06-10T02:26:36.137
9008
9008
question
java spring spring-boot spring-security
ユーザ登録後にUsernamePasswordAuthenticationTokenを生成してsetAuthenticationしているのはなぜでしょうか？


Javadocにはこんなことが書いてありますね。

<https://docs.spring.io/spring-
security/site/docs/current/api/org/springframework/security/core/Authentication.html>

> Once the request has been authenticated, the `Authentication` will usually
> be stored in a thread-local `SecurityContext` managed by the
> `SecurityContextHolder` by the authentication mechanism which is being used.
> An explicit authentication can be achieved, without using one of Spring
> Security's authentication mechanisms, by creating an `Authentication`
> instance and using the code:
[code]

>     SecurityContextHolder.getContext().setAuthentication(anAuthentication);
>  
[/code]

つまり、認証されると、通常は使用している（Spring
Securityなどの）認証メカニズムによって`SecurityContext`に`Authentication`がセットされるけど、認証メカニズムを使用しないケースではセットされないので、明示的にセットしてねってことだと思います。

なので、Spring Securityで認証している本文リンク先のケースでは`setAuthentication()`していないのではないでしょうか。


CC BY-SA 4.0
2020-06-09T01:39:59.210
67434
2020-06-09T01:39:59.210
21092
67424
answer


`setAuthentication`はその名の通りコンテキストに認証情報を設定するメソッドです。要するにログイン認証OKであることを表します。

> どういった場面が想定されているのでしょうか？

状況の説明が不足しているので回答者が何を言いたいのかいまいちわかりませんが、仮に連続で1-5の手続きを行えば良いんだ、ということを言っているのであれば、

  * ユーザが入会フォームに情報を記入し登録ボタンを押した。システムはユーザ登録を行い、そのままセッションをログイン状態にする。

みたいな状況を想定していると思われます。  
(…なので、元々の質問に対しての回答になっていないし、どういう意図で敢えてこのコードを回答として書いたのかもよくわかりません。正直この回答コードを理解しようとする努力に益は無いと思います…)

* * *

他方、[後者リンク](http://inaz2.hatenablog.com/entry/2017/04/18/222721)先のコードは、ユーザ登録はユーザ登録、ログインはログインで独立しています。  
ユーザ登録完了したら、別途ログインボタンを押して認証を受けてくださいね、ということです。

なお、後者のコードにおいて、ログイン処理では、

[code]

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        ...
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/", "/login", "/login-error").permitAll()
                    .antMatchers("/**").hasRole("USER")
                    .and()
                .formLogin()
                    .loginPage("/login").failureUrl("/login-error");
        }
        ...
    
[/code]

上記コンフィグで`formLogin()`によって[`UsernamePasswordAuthenticationFilter`](https://docs.spring.io/spring-
security/site/docs/5.1.5.RELEASE/reference/htmlsingle/#nsa-form-
login)が有効化されますので、認証OKなら
`UsernamePasswordAuthenticationFilter#successfulAuthentication`内で[`setAuthentication`](https://github.com/spring-
projects/spring-
security/blob/5.3.3.RELEASE/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java#L316)が呼ばれます。

* * *

蛇足になりますが、この辺のアーキテクチャ概要が下のリンク先にまとまっています:

  * [Spring Security Architecture - Guides](https://spring.io/guides/topicals/spring-security-architecture/)
  * [9\. Servlet Security: The Big Picture - Spring Security Reference](https://docs.spring.io/spring-security/site/docs/5.3.3.RELEASE/reference/html5/#servlet-architecture)
  * [9.2.1.1. 認証処理のアーキテクチャ - TERASOLUNA documentation](http://terasolunaorg.github.io/guideline/5.5.1.RELEASE/ja/Security/Authentication.html#id3)

* * *

更に蛇足になりますが、[その質問](https://stackoverflow.com/q/32244745/4506703)者が聞きたいのは、  
「実行中にユーザテーブルにユーザが増えていくわけだけど、このユーザテーブルを用いて認証するにはどうすればいいの？」  
ということ(つまり、"I save users in a DB table via
Hibernate"ということなのでユーザ登録は既にやっており、聞きたいのはユーザ登録の方法ではなくて、そのデータを用いた認証方法である/"how to
add new user to Spring Security"という聞き方になっているのは、質問者がSpring
Securityにユーザ登録しないといけないと勘違いしている)と理解しましたので、回答としては[こんな感じ](https://stackoverflow.com/a/62293813/4506703)になるかと思います。


CC BY-SA 4.0
2020-06-09T13:14:38.933
67465
2020-06-12T19:39:38.197
2020-06-12T19:39:38.197
2808
2808
67424
answer