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) | ユーザのリクエスト情報をもとに認証を開始するクラス |
具体的な処理の流れについてはココが参考になる。