SIer だけど技術やりたいブログ

SpringSecurityでFORM認証

Java Spring SpringBoot SpringSecurity

SpringSecurityとは

springプロダクトのひとつ。
認証認可の機能を提供してくれる。

認証(アクセスしてきたのは誰か?)

  • BASIC認証、DIGEST認証、LDAP、FORM認証、openID認証など、色々サポート

認可(そのユーザが何をできるか?)

  • デフォルトはROLEベースの制御 ※1
  • URLや画面の部品出力単位で認可の制御が可能

※1 権限ベースの制御方法についても調べた。 SpringSecurity 権限に基づいた認可をする - SIerだけど技術やりたいブログ

サンプルコード

簡単なものを書いた。

https://github.com/kimullaa/springsecurity-with-boot

  • OracleJDK1.8
  • Spring Boot1.3.2.RELEASE
  • Maven 3.3.3

サンプルコードのポイント

SpringBootがデフォルトで設定しているBASIC認証よりも前に、アプリで定義した認証が有効になるように以下の設定をする。 詳細はここ
また、Form認証を有効にするためにformLogin()を設定する。

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) //重要
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.authorizeRequests()
      .antMatchers("/admin/**").hasRole("ADMIN")
    .anyRequest().authenticated().and()
    .formLogin() //重要
      .loginPage("/login")
      .defaultSuccessUrl("/home")
      .failureUrl("/login?error")
      .permitAll().and()
    .logout()
      .logoutUrl("/logout")
      .logoutSuccessUrl("/login?logout")
      .permitAll();
    }

DBはインメモリを利用する。

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication() 
    .withUser("user").password("password").roles("USER").and()
    .withUser("admin").password("password").roles("USER","ADMIN");
    }

ログイン時のユーザ名はusername, パスワードはpassword のパラメータ名にする必要がある。(下記に記載しているUsernamePasswordAuthenticationFilterのBean生成時にパラメータ名を設定すればカスタマイズ可能。)

~~~省略~~~
    <input type="text" id="name" placeholder="Name" required="required"
        autofocus="autofocus" name="username"/> 
    <label for="password" >Password</label>
    <input type="password" id="password" 
        placeholder="Password" required="required" name="password"/>
~~~省略~~~

ログイン後のページ。
sec:authentication=“principal.username” で認証情報を取得するために、 xmlns:sec=”http://www.thymeleaf.org/thymeleaf-extras-springsecurity4を追加する。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org"
    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">  //重要
<head>
<title>USER PAGE</title>
</head>
<body>
    <h1>USER PAGE</h1>
    <dl>
        <dt>username</dt>
    <dd sec:authentication="principal.username"></dd>
    <dt>authorities</dt>
    <dd sec:authentication="principal.authorities"></dd>
    </dl>
        <div sec:authorize="hasRole('ADMIN')">
        <a th:href="@{/admin}">to admin page</a>
    </div>
    <form th:action="@{/logout}" method="post">
        <input type="submit" value="Sign Out" />
    </form>
</body>
</html>

pom.xmlにも追加する。

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>

主要なクラス

以下のクラスがSpringSecurity内で利用される様子。

インタフェース (デフォルトの実装クラス)役割
UserDetails (User)ユーザ情報(ユーザ名、パスワード、権限)を表すクラス
UserDetailsService (InMemoryUserDetailsManager)データソース(DBやLDAP)からUserDetailsを取得するクラス。DBを利用する場合はJdbcDaoImplクラス。
Authentication (UsernamePasswordAuthenticationToken)認証情報を表すクラス (認証前はユーザリクエストを格納する。認証後はUserDetailsをprincipalに格納する)
AuthenticationProvider (DaoAuthenticationProvider)UserDetailsServiceから取得したUserDetailsとAuthenticationTokenを比較することで認証処理を実装するクラス
AuthenticationManager (ProviderManager)AuthenticationProviderに実際の認証処理を指示するクラス
AuthenticationFilter (UsernamePasswordAuthenticationFilter)ユーザのリクエスト情報をもとに認証を開始するクラス

具体的な処理の流れについてはココが参考になる。

参考にしたサイト