ホームページ  >  記事  >  データベース  >  SpringSecurity+Redis 認証プロセスとは何ですか?

SpringSecurity+Redis 認証プロセスとは何ですか?

王林
王林転載
2023-06-03 15:22:20966ブラウズ

概要の概要

今日の市場で権限管理に使用されている一般的なテクノロジ スタックの組み合わせは、

  • ssm shrio

  • です。

    SpringCloud SpringBoot SpringSecurity

SpringSecurity+Redis 認証プロセスとは何ですか?

この組み合わせには、当然、独自の一致特性があります。SpringBoot の自動インジェクション構成原理により、この組み合わせは、 SpringSecurityのフィルターコンテナ(DelegatingFilterProxy)を管理しますが、このフィルターがSpringSercurity全体のコアとなります。 SpringSercurity の権限認証プロセス全体をマスターし、SpringBoot を使用すると、それを に自動的に挿入できます。ssm
を使用してセキュリティを統合すると、大量の構成ファイルが消費され、開発が容易ではありません。セキュリティのマイクロサービス権限スキームクラウドと完全に統合できるため、セキュリティは Shrio よりも強力で完全です。

セキュリティのコア構成ファイル

コア: クラス SecurityConfigWebSecurityConfigurerAdapter を拡張します

WebSecurityConfigurerAdapter を継承した後、configure メソッドに注目しますもちろん、セキュリティ認証プロセス全体の関連する構成については、構成する前にプロセスを簡単に理解します。

権限認証プロセス全体を簡単に見た後、SpringSecurity の中核は次のとおりであると簡単に結論付けることができます。以下にいくつかの設定項目が続きます

  • #Interceptor

  • Filter

  • Handler (ハンドラー、例外ハンドラー、ログイン) success ハンドラー)

次に、最初に構成を通じて認証プロセスを完了しましょう。 ! ! ! #セキュリティの認証プロセス

次の認証機能を実装するとします

##1。これはログイン リクエストです

最初に検証コードが正しいかどうかを判断する必要があります (検証コード フィルター、addFilerbefore による事前インターセプトの実装)
  • 次に、ユーザー名とパスワードが正しいかどうかを判断する必要があります (使用組み込みのユーザー名とパスワードのフィルター
  • UsernamePasswordAuthenticationFilter
  • )

    IO ストリームを通じて例外情報を書き出すように例外ハンドラー (Handler) を構成します
  • パスワード検証プロセスについて:
  • UsernamePasswordAuthenticationFilter のパスワード検証ルールは、AuthenticationManagerBuilder (認証マネージャー) の UserDetailsS​​ervice のルールに基づいて検証されます:
コア メソッド:


1.public
UserDetails

*loadUserByUsername(String username)

データベースに移動して、リクエスト パラメータのユーザー名を使用して存在するかどうかをクエリします。存在する場合は、UserDetails にカプセル化され、検証が行われます。プロセスは、AuthenticationManagerBuilder を通じて UserDetail のユーザー名とパスワードを取得することです。検証するには、

    を通じてアカウント パスワードを設定するように yaml ファイルを設定できるようにします。
  • UserDetail パスワードと組み合わせたデータベースを介してアカウントを設定します

  • (UserDetailsS​​ervice のメソッド。UserDetailsS​​ervice は AuthenticationManagerBuilder に注入する必要があることに注意してください)

    	@Override
    	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    		SysUser sysUser = sysUserService.getByUsername(username);
    		if (sysUser == null) {
    			throw new UsernameNotFoundException("用户名或密码不正确");
    		}
    		// 注意匹配参数,前者是明文后者是暗纹
    		System.out.println("是否正确"+bCryptPasswordEncoder.matches("111111",sysUser.getPassword()));
    		return new AccountUser(sysUser.getId(), sysUser.getUsername(), sysUser.getPassword(), getUserAuthority(sysUser.getId()));
    	}
  • この検証に合格すると、フィルタが許可されますが、それ以外の場合は、カスタムまたはデフォルトのプロセッサ ハンドルを使用します

コア構成ファイル:

package com.markerhub.config;

import com.markerhub.security.*;
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.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	LoginFailureHandler loginFailureHandler;

	@Autowired
	LoginSuccessHandler loginSuccessHandler;

	@Autowired
	CaptchaFilter captchaFilter;

	@Autowired
	JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

	@Autowired
	JwtAccessDeniedHandler jwtAccessDeniedHandler;

	@Autowired
	UserDetailServiceImpl userDetailService;

	@Autowired
	JwtLogoutSuccessHandler jwtLogoutSuccessHandler;

	@Bean
	JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
		JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager());
		return jwtAuthenticationFilter;
	}

	@Bean
	BCryptPasswordEncoder bCryptPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}

	private static final String[] URL_WHITELIST = {

			"/login",
			"/logout",
			"/captcha",
			"/favicon.ico",

	};


	protected void configure(HttpSecurity http) throws Exception {

		http.cors().and().csrf().disable()

				// 登录配置
				.formLogin()
				.successHandler(loginSuccessHandler)
				.failureHandler(loginFailureHandler)

				.and()
				.logout()
				.logoutSuccessHandler(jwtLogoutSuccessHandler)

				// 禁用session
				.and()
				.sessionManagement()
				.sessionCreationPolicy(SessionCreationPolicy.STATELESS)

				// 配置拦截规则
				.and()
				.authorizeRequests()
				.antMatchers(URL_WHITELIST).permitAll()
				.anyRequest().authenticated()

				// 异常处理器
				.and()
				.exceptionHandling()
				.authenticationEntryPoint(jwtAuthenticationEntryPoint)
				.accessDeniedHandler(jwtAccessDeniedHandler)

				// 配置自定义的过滤器
				.and()
				.addFilter(jwtAuthenticationFilter())
				.addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class)

		;

	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailService);
	}
}

2。ログイン リクエストではありません

JwtfFilter による表示 ログイン状態かどうか

  • Redis 統合使用時の注意事項

  • 本質的には、まだフィルターを作成しています。 chain:

ログイン要求の前にフィルターを追加します

  • redis に保存されている確認コードの有効期限に注意してください。有効期限を超えると、検証コード インターセプターによってインターセプトされます

  • 検証コードを生成するためのインターフェイスを準備し、Redis に保存する必要があります

  • 使用後は確認コードを削除する必要があります

  • ##
    // 校验验证码逻辑
    	private void validate(HttpServletRequest httpServletRequest) {
    
    		String code = httpServletRequest.getParameter("code");
    		String key = httpServletRequest.getParameter("token");
    
    		if (StringUtils.isBlank(code) || StringUtils.isBlank(key)) {
    			System.out.println("验证码校验失败2");
    			throw new CaptchaException("验证码错误");
    		}
    
    		System.out.println("验证码:"+redisUtil.hget(Const.CAPTCHA_KEY, key));
    		if (!code.equals(redisUtil.hget(Const.CAPTCHA_KEY, key))) {
    			System.out.println("验证码校验失败3");
    			throw new CaptchaException("验证码错误");
    		}
    
    		// 一次性使用
    		redisUtil.hdel(Const.CAPTCHA_KEY, key);
    	}

以上がSpringSecurity+Redis 認証プロセスとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。