Springで、ログイン画面に入力されたID・パスワードをDBに確認し、ユーザーの権限で特定のURLへのアクセスを禁止する機能を簡単に作成しましょう〜♪
これまでに、直リンク禁止やログイン機能の実装、エラーメッセージの日本語化、パスワードの暗号化、ログアウト機能を実装したので、
これから認可の機能も実装していきます^^
URLの認可
- URLの認可=権限がないユーザーは指定のURLにはアクセス自体できないようにします
antMatchers("<パス>")
- アクセス制限するパスを設定します。正規表現もOK
hasAuthority("<ロール>")
- ロールには、データベースから取得してきたロール名を指定
Springでのロール名
- Springでは、ロール名の先頭に"ROLE_"を付けるというルールがあります
- 中には、"ROLE_"を省略して引数にセットするようなメソッドもあります。。。🙄
- データベースにロール名を登録する際は、"ROLE_"を付けるようにしましょう
SecurityConfig.java
package com.example.demo;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// データソース
@Autowired
private DataSource dataSource;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// ユーザーIDとパスワードを取得するSQL文
private static final String USER_SQL = "SELECT"
+ " user_id,"
+ " password,"
+ " true"
+ " FROM"
+ " m_user"
+ " WHERE"
+ " user_id = ?";
// ユーザーのロールを取得するSQL文
private static final String ROLE_SQL = "SELECT"
+ " user_id,"
+ " role"
+ " FROM"
+ " m_user"
+ " WHERE"
+ " user_id = ?";
@Override
public void configure(WebSecurity web) throws Exception {
//静的リソースへのアクセスには、セキュリティを適用しない
web.ignoring().antMatchers("/webjars/∗∗", "/css/∗∗");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// ログイン不要ページの設定
http
.authorizeRequests()
.antMatchers("/webjars/**").permitAll() //webjarsへアクセス許可
.antMatchers("/css/**").permitAll() //cssへアクセス許可
.antMatchers("/login").permitAll() //ログインページは直リンクOK
.antMatchers("/signup").permitAll() //ユーザー登録画面は直リンクOK
.antMatchers("/admin").hasAuthority("ROLE_ADMIN") //アドミンユーザーに許可
.anyRequest().authenticated(); //それ以外は直リンク禁止
//ログイン処理
http
.formLogin()
.loginProcessingUrl("/login") //ログイン処理のパス
.loginPage("/login") //ログインページの指定
.failureUrl("/login") //ログイン失敗時の遷移先
.usernameParameter("userId") //ログインページのユーザーID
.passwordParameter("password") //ログインページのパスワード
.defaultSuccessUrl("/home", true); //ログイン成功後の遷移先
//ログアウト処理
http
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")) //
.logoutUrl("/logout") //ログアウトのURL
.logoutSuccessUrl("/login"); //ログアウト成功後のURL
//CSRFを無効にするURLを設定
RequestMatcher csrfMatcher = new RestMatcher("/rest/**");
//RESTのみCSRF対策を無効に設定
http.csrf().requireCsrfProtectionMatcher(csrfMatcher);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// ログイン処理時のユーザー情報を、DBから取得する
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery(USER_SQL)
.authoritiesByUsernameQuery(ROLE_SQL)
.passwordEncoder(passwordEncoder());
}
}
アプリ起動して、ログインしてアドミン画面を確認!
- 一般ユーザーでログインした後、アドミン権限専用画面を開く
- ユーザーID:satou@xxx.co.jp
- パスワード:password
- http://localhost:8080/admin
- 403エラーになって、一般ユーザではアクセスできません🙆♀️💮