春のセキュリティフォームログイン
1. 序章
このチュートリアルでは、SpringSecurityを使用したログインに焦点を当てます。 以前のSpringMVCの例の上に構築します。これは、ログインメカニズムとともにWebアプリケーションをセットアップするために必要な部分です。
2. Mavenの依存関係
Spring Bootを使用する場合、 spring-boot-starter-security スターターには、 spring-security-core 、
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
Spring Bootを使用しない場合は、必要なすべての依存関係を追加する方法について説明しているSpringセキュリティとMavenの記事を参照してください。 標準のspring-security-webとspring-security-configの両方が必要になります。
3. SpringSecurityJava構成
WebSecurityConfigurerAdapter。を拡張するSpringセキュリティ構成クラスを作成することから始めましょう。
@EnableWebSecurity を追加することで、SpringSecurityとMVCの統合サポートを利用できます。
@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
// authentication manager (see below)
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
// http builder configurations for authorize requests and form login (see below)
}
}
この例では、メモリ内認証を使用し、3人のユーザーを定義しました。
次に、フォームのログイン構成を作成するために使用した要素について説明します。
認証マネージャーを構築することから始めましょう。
3.1. 認証マネージャー
認証プロバイダーは、単純なメモリ内実装InMemoryUserDetailsManagerによって支えられています。 これは、完全な永続化メカニズムがまだ必要でない場合のラピッドプロトタイピングに役立ちます。
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("USER")
.and()
.withUser("user2").password(passwordEncoder().encode("user2Pass")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN");
}
ここでは、ハードコードされたユーザー名、パスワード、および役割を使用して3人のユーザーを構成します。
Spring 5以降、パスワードエンコーダーも定義する必要があります。 この例では、 BCryptPasswordEncoder:を使用します
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
次に、HttpSecurity。を構成しましょう。
3.2. リクエストを承認するための設定
まず、リクエストを承認するために必要な構成を行います。
ここでは、ユーザーが認証できるように、 /loginでの匿名アクセスを許可しています。 /adminをADMINの役割に制限し、その他すべてを保護します。
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
// ...
}
antMatchers()要素の順序が重要であることに注意してください。 より具体的なルールを最初に指定し、次に一般的なルールを指定する必要があります。
3.3. フォームログインの構成
次に、フォームのログインとログアウトのために上記の構成を拡張します。
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
// ...
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage.html", true)
.failureUrl("/login.html?error=true")
.failureHandler(authenticationFailureHandler())
.and()
.logout()
.logoutUrl("/perform_logout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(logoutSuccessHandler());
}
- loginPage() –カスタムログインページ
- loginProcessingUrl() –ユーザー名とパスワードを送信するURL
- defaultSuccessUrl() –ログインに成功した後のランディングページ
- failureUrl() –ログインに失敗した後のランディングページ
- logoutUrl() –カスタムログアウト
4. SpringSecurityをWebアプリケーションに追加する
上記で定義したSpringSecurity構成を使用するには、それをWebアプリケーションにアタッチする必要があります。
WebApplicationInitializer を使用するため、 web.xml:を提供する必要はありません。
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext sc) {
AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.register(SecSecurityConfig.class);
sc.addListener(new ContextLoaderListener(root));
sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
}
}
Spring Bootアプリケーションを使用している場合、この初期化子は必要ないことに注意してください。 Spring Bootでのセキュリティ構成のロード方法の詳細については、に関する記事を参照してください。 Spring Bootセキュリティ自動構成。
5. SpringSecurityXML構成
対応するXML構成も見てみましょう。
プロジェクト全体でJava構成を使用しているため、Java @Configurationクラスを介してXML構成ファイルをインポートする必要があります。
@Configuration
@ImportResource({ "classpath:webSecurityConfig.xml" })
public class SecSecurityConfig {
public SecSecurityConfig() {
super();
}
}
そして、SpringSecurityXML構成webSecurityConfig.xml:
<http use-expressions="true">
<intercept-url pattern="/login*" access="isAnonymous()" />
<intercept-url pattern="/**" access="isAuthenticated()"/>
<form-login login-page='/login.html'
default-target-url="/homepage.html"
authentication-failure-url="/login.html?error=true" />
<logout logout-success-url="/login.html" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user1" password="user1Pass" authorities="ROLE_USER" />
</user-service>
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
</beans:bean>
6. web.xml
Spring 4 が導入される前は、web.xmlでSpringSecurityを構成していました。 標準のSpringMVC web.xmlに追加された追加のフィルターのみ:
<display-name>Spring Secured Application</display-name>
<!-- Spring MVC -->
<!-- ... -->
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
フィルタ– DelegatingFilterProxy –は、Spring管理のBean – FilterChainProxy –に委任するだけで、SpringBeanの完全なライフサイクル管理などの恩恵を受けることができます。
7. ログインフォーム
ログインフォームページは、ビュー名をURLにマップする簡単なメカニズムを使用してSpringMVCに登録されます。 さらに、次の間に明示的なコントローラーは必要ありません。
registry.addViewController("/login.html");
もちろん、これはlogin.jspに対応します。
<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="login" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
</body>
</html>
春のログインフォームには、次の関連するアーティファクトがあります。
- login –認証プロセスをトリガーするためにフォームがPOSTされるURL
- username –ユーザー名
- password –パスワード
8. SpringLoginのさらなる構成
上記のSpringSecurity構成を紹介したときに、ログインメカニズムのいくつかの構成について簡単に説明しました。 それでは、もう少し詳しく見ていきましょう。
Spring Securityのデフォルトのほとんどを上書きする理由の1つは、
完全に構成されたログイン要素は、次のようになります。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage.html",true)
.failureUrl("/login.html?error=true")
}
または、対応するXML構成:
<form-login
login-page='/login.html'
login-processing-url="/perform_login"
default-target-url="/homepage.html"
authentication-failure-url="/login.html?error=true"
always-use-default-target="true"/>
8.1. ログインページ
次に、 loginPage()メソッドを使用してカスタムログインページを構成します:
http.formLogin()
.loginPage("/login.html")
同様に、XML構成を使用できます。
login-page='/login.html'
これを指定しない場合、Springセキュリティは / loginURLに非常に基本的なログインフォームを生成します。
8.2. ログイン用のPOSTURL
Spring LoginがPOSTして認証プロセスをトリガーするデフォルトのURLは、 / login、で、 Spring Security4の前は/j_spring_security_checkでした。
loginProcessingUrl メソッドを使用して、このURLをオーバーライドできます。
http.formLogin()
.loginProcessingUrl("/perform_login")
XML構成を使用することもできます。
login-processing-url="/perform_login"
このデフォルトのURLを上書きすることで、アプリケーションが実際にSpringセキュリティで保護されていることを隠蔽しています。 この情報は外部から入手できないようにする必要があります。
8.3. 成功のランディングページ
ログインに成功すると、デフォルトでWebアプリケーションのルートであるページにリダイレクトされます。
これは、 defaultSuccessUrl()メソッドを介してオーバーライドできます。
http.formLogin()
.defaultSuccessUrl("/homepage.html")
またはXML構成の場合:
default-target-url="/homepage.html"
always-use-default-target 属性がtrueに設定されている場合、ユーザーは常にこのページにリダイレクトされます。 その属性がfalseに設定されている場合、ユーザーは認証を求められる前に、アクセスしたい前のページにリダイレクトされます。
8.4. 失敗のランディングページ
ログインページと同様に、ログイン失敗ページは、デフォルトで / login?エラーでSpringSecurityによって自動生成されます。
これをオーバーライドするには、 failureUrl()メソッドを使用できます。
http.formLogin()
.failureUrl("/login.html?error=true")
またはXMLの場合:
authentication-failure-url="/login.html?error=true"
9. 結論
このSpringLogin Example では、単純な認証プロセスを構成しました。 また、Springセキュリティログインフォーム、セキュリティ構成、および利用可能なより高度なカスタマイズのいくつかについても説明しました。
この記事の実装は、 GitHubプロジェクトにあります。これはEclipseベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。
プロジェクトがローカルで実行される場合、サンプルHTMLには次の場所からアクセスできます。
http://localhost:8080/spring-security-mvc-login/login.html