blog

スプリング・セキュリティ・チュートリアル

1.Springセキュリティ SpringセキュリティはSpringファミリーのセキュリティ管理フレームワークで、アプリケーションの2つの主要な領域は "認証 "と "認可 "です。Spring Se...

Sep 19, 2020 · 8 min. read
シェア

TOC

スプリング・セキュリティ

Spring SecurityはSpringファミリーのセキュリティ管理フレームワークで、アプリケーションの2つの主要な領域は "認証 "と "認可 "です。Spring SecurityはSpringプロジェクトのセキュリティフレームワークであり、基盤となるSpring Bootセキュリティモジュールのデフォルトの選択技術です。

この2つの主要な領域がSpring Securityの2つのゴールです。

  • "認証 "は、本人が宣言する主体を確立するプロセスです。
  • "認可 "は、サブジェクトがアプリケーションでアクションを実行することを許可されているかどうかを決定するプロセスです。認可が必要な時点に到達するために、認証プロセスによってサブジェクトの身元はすでに確立されています。

実験環境の準備

環境の準備:

  • JDK1.8
  • SpringBoot2.2.1
  • Maven 3.2+
  • 開発ツール
    • IntelliJ IDEA
    • smartGit
新しいプロジェクトを作成した後、バージョンを書かずにspring-boot-starter-securityシナリオのスターターが正常に設定されているか確認します。
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-security</artifactId>
 </dependency>

ログレベルの変更

Spring Securityのログレベルを設定します。デフォルトはinfoですが、debugに変更できます。

## logback 
logging:
 level:
 org:
 springframework:
 security: info

ユーザー名/パスワードの設定

何気なくインターフェイスを書いて、アクセスすると、ログインページの次のイメージにジャンプしますが、なぜですか?mavenの設定だけの導入は、その後、アカウントのパスワードは何ですか?実際には、これはSpring Securityのデフォルトのログインページであり、ページのコードは、jarパッケージ内にあり、デフォルトのユーザー名はuserであり、パスワードはランダムに生成されたuuid形式のパスワードです!

パスワードはコンソールに表示されます。ヒントをたどって、自動設定クラスを見つけてください。
デフォルトのパスワードを変更するには、新しいapplication.yml設定ファイルを作成し、次の設定を追加します
## spring security 
spring:
 security:
 user:
 name: nicky
 password: 123
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 @Override
 protected void configure(AuthenticationManagerBuilder auth) throws Exception { //auth.inMemoryAuthentication()
 auth.inMemoryAuthentication()
 .withUser("nicky")
 .password(bcryptPasswordEncoder().encode("123"))
 .roles("admin");
 }
	
	@Bean
 public PasswordEncoder bcryptPasswordEncoder() {
 return new BCryptPasswordEncoder();
 }
}
bcrypt password bcrypt
ldap password ldap
{ldap}password MD4 {MD4}password
MD5 password {MD5}password
noop password noop
pbkdf2 password pbkdf2
password {pbkdf2}password scrypt
SHA-1 password SHA-1
SHA-652 SHA-652 {SHA-256}password
SHA652 SHA-652 {SHA-256}password

データベース検証

展開:ユーザ名とパスワードをデータベース方式で検証したい場合は、UserDetailsServiceメソッドをカスタマイズします:

@Override
 protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
 auth.userDetailsService(userDetailsService)
 .passwordEncoder(new CustomPasswordEncoder());
 auth.parentAuthenticationManager(authenticationManagerBean());
 }

UserDetailsServiceImpl.java

package com.example.springboot.oauth2.service;
import com.example.springboot.oauth2.entity.User;
import com.example.springboot.oauth2.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
 * <pre>
 *
 * </pre>
 *
 * <pre>
 * 
 * 修正記録
 * 修正版: 変更者: 日付: 15:15 内容を変更する:
 * </pre>
 */
@Slf4j
@Service("userService")
public class UserDetailsServiceImpl implements UserDetailsService {
 @Autowired
 UserMapper userRepository;
 @Override
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 User user = userRepository.findByUsername(username);
 if(user == null){
 log.info("ログインユーザー[{}] !",username);
 throw new UsernameNotFoundException("ログインユーザー["+username + "] !");
 }
 return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthority());
 }
 private List getAuthority() {
 return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"));
// return Arrays.asList(Collections.emptyList());
 }
}
@Override
 protected void configure(HttpSecurity http) throws Exception {
 http // ログインページを設定し、アクセスを許可する
 .formLogin().usernameParameter("username").passwordParameter("password").loginPage("/login").permitAll()
 // 基本ログインを設定する
 //.and().httpBasic()
 // ログアウトページを設定する
 .and().logout().logoutUrl("/logout").logoutSuccessUrl("/")
 // オープンインターフェースアクセス、アクセスにログイン認証は必要ない
 .and().authorizeRequests().antMatchers("/oauth/**", "/login/**", "/logout/**").permitAll()
 // apiこのインターフェイスには管理者権限が必要である。
 .antMatchers("/api/**").hasRole("admin")
 // その他のリクエストには認証が必要
 .anyRequest().authenticated()
 // クロスドメイン保護を無効にする;
 .and().csrf().disable();
 }

静的リソースをインターセプトしない

設定ファイルに加え

@Override
 public void configure(WebSecurity web) throws Exception {
 //静的リソースのブロック問題を解決する
 web.ignoring().antMatchers("/asserts/**");
 web.ignoring().antMatchers("/favicon.ico");
 }

ログインページのカスタマイズ

Thymeleafテンプレートエンジンを紹介します:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-thymeleaf</artifactId>
 </dependency>

F9自動コンパイル用のThymeleafテンプレートエンジンキャッシュを無効にします。

spring:
 thymeleaf:
 cache: false

POSTはデフォルトのSpring Securityチェックインターフェイスで、インターフェイス名は/loginです。

@Controller
public class LoginController {
 @GetMapping(value = {"/login"})
 public ModelAndView toLogin() {
 return new ModelAndView("login");
 }
}

ログインページをPOSTでカスタマイズします。独自のバリデーションインターフェイスを書かない限り、POST /loginは公式のSpring Securityバリデーションインターフェイスです:

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://..rg">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
		<meta name="description" content="" />
		<meta name="author" content="" />
		<title>Signin Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link href="../static/asserts/css/bootstrap.min.css" th:href="@{asserts/css/bootstrap.min.css}" rel="stylesheet" />
		<!-- Custom styles for this template -->
		<link href="../static/asserts/css/signin.css" th:href="@{asserts/css/signin.css}" rel="stylesheet"/>
	</head>
	<body class="text-center">
		<form class="form-signin" th:action="@{/login}" method="post">
			<img class="mb-4" th:src="@{asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72" />
			<h1 class="h3 mb-3 font-weight-normal" >Oauth2.0 Login</h1>
			<label class="sr-only" >Username</label>
			<input type="text" class="form-control" name="username" required="" autofocus="" value="nicky" />
			<label class="sr-only" >Password</label>
			<input type="password" class="form-control" name="password" required="" value="123" />
			<div class="checkbox mb-3">
				<label>
 <input type="checkbox" value="remember-me" /> remember me
 </label>
			</div>
			<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
			<p class="mt-5 mb-3 text-muted">2019</p>
		</form>
	</body>
</html>

.loginPage("/login")設定ファイルを修正して、カスタムログインページを指定します。

 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http // ログインページを設定し、アクセスを許可する
 .formLogin().usernameParameter("username").passwordParameter("password").loginPage("/login").permitAll()
 // 基本ログインを設定する
 //.and().httpBasic()
 // ログアウトページを設定する
 .and().logout().logoutUrl("/logout").logoutSuccessUrl("/")
 // オープンインターフェースアクセス、アクセスにログイン認証は必要ない
 .and().authorizeRequests().antMatchers("/oauth/**", "/login/**", "/logout/**").permitAll()
 // apiこのインターフェイスには管理者権限が必要である。
 .antMatchers("/api/**").hasRole("admin")
 // その他のリクエストには認証が必要
 .anyRequest().authenticated()
 // クロスドメイン保護を無効にする;
 .and().csrf().disable();
 }

Remember me

Remember me機能を有効にすると、ログインに成功した後、ブラウザにクッキーを送信して保存し、後でこのクッキーでページを訪問し、チェックに合格する限り、自由にログインすることができます。

 <input type="checkbox" name="remember-me" value="true" /> remember me
@Override
 protected void configure(HttpSecurity http) throws Exception {
 //Remember Me機能を有効にし、ログインに成功した後、ブラウザにクッキーを送信して保存し、後でこのクッキーのあるページを訪問し、チェックに合格する限り、自由にログインすることができる。
 http.rememberMe().rememberMeParameter("remember-me");
 }

Remember meにチェックを入れると、ログインに成功します。

ブラウザを閉じて再度ログインすると、再度ログインする必要はありません。

コード例ダウンロード:

Read next

[Kotlin】Kotlin/Nativeメモリ管理ロードマップ

TL;DR: 現在の自動メモリ管理の実装には、並行性の点でいくつかの制限があり、代替案を調査中です。既存のコードは引き続き動作し、サポートされる予定です。全文はこちらをお読みください。 は、Kotlinとネイティブ・プラットフォーム固有の環境をスムーズに統合するためのソリューションとして設計されました。基本的に、そのビジョンは...

Sep 19, 2020 · 5 min read