プロジェクトアーキテクチャ:春春のセキュリティブート+ + Thymeleaf
1.リードパック(ブートとthymeleafは、独自のパッケージ、バージョン番号をインポートし、私はスモークプロパティ)
< 依存性> < のgroupId > org.springframework.security </ のgroupId > < たartifactId >スプリングセキュリティテスト</ たartifactId > < スコープ>テスト</ スコープ> </ 依存> < 依存性> < のgroupId > org.springframework.boot </ groupIdを> < たartifactId >春・ブート・スターター・セキュリティ</ たartifactId > </ 依存>
2.コア・コンフィギュレーション・クラス(最後のリリースの完全なコード)
2.1カスタムセキュリティの設定クラスは、この抽象クラスWebSecurityConfigurerAdapter継承します。
マーク2.2 @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = trueに)これら2つのノート
コンフィギュレーション(切片パラメータ、パス、クロスドメインリクエストなどをログ)を設定するhttp.formLogin()メソッドを使用してチェーンプログラミングを使用して2.3リライトのconfigure(HttpSecurity HTTP)メソッドは、次のものが必要
2.4書き換えのconfigure(WebSecurity社ウェブ)メソッド、静的リソースの解放
web.ignoring()。antMatchers( "/ ** / *。jsファイル"、 "/**/*.css"、 "/**/*.png"、 "/**/*.jpg"、「/ 。** / * GIF」、 "/**/*.map");
2.5書き換えのconfigure(AuthenticationManagerBuilder払い)法、ログイン認証をカスタマイズ
loginAuthenticationProvider:これは呼び出しに、カスタムログインの検証クラスであります
customUserDetailsService:これは呼び出しに、カスタム・アカウント・ストレージ・クラスであります
customPasswordEncoder:これは、注射を呼び出し、パスワード暗号化クラスの定義であります
loginAuthenticationProvider.setUserDetailsService(customUserDetailsService)。 loginAuthenticationProvider.setPasswordEncoder(customPasswordEncoder)。 auth.authenticationProvider(loginAuthenticationProvider)。 スーパー .configure(AUTH)。
3.security国際問題
セキュリティプロセスでは、このクラスのDaoAuthenticationProviderのadditionalAuthenticationChecksのネイティブコードのメソッド理由
その見返りに、あなたは時にフロントランディングページ失敗します悪い資格情報のニュースを。これは、システムがとてもフレンドリーに見えない原因となります。
解決策は以下のとおりです。
1.リソースフォルダにmessages_zh_CN.propertiesにこのファイルを追加します。あなたが返すようにしたい場合は、フロントをカスタマイズします。
2.カスタマイズログインバリデーションクラスloginAuthenticationProvider(最後のリリース完全なコード)
3.カスタムクラスのセキュリティ設定に応じて設定さ
完全なコード:
1.カスタムセキュリティの設定クラス
@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = 真) パブリック クラス SecurityConfigurationは延びWebSecurityConfigurerAdapter { 民間 最終CustomPasswordEncoder customPasswordEncoderと、 民間 最終CustomUserDetailsService customUserDetailsService。 民間 最終CommonPropertiesのcommonProperties。 @Autowired 公共SecurityConfiguration(CustomPasswordEncoder customPasswordEncoder、CustomUserDetailsService customUserDetailsService、CommonProperties commonProperties){ この .customPasswordEncoder =customPasswordEncoder; この .customUserDetailsService = customUserDetailsService。 この .commonPropertiesの=のcommonProperties。 } @Autowired プライベートLoginAuthenticationProvider loginAuthenticationProviderは、 / ** * HTTP配置 * @param HTTP * @throws 例外 * / @Overrideは 保護され 、ボイドのconfigureを(HttpSecurity HTTP)は、スロー例外{ http.formLogin() .loginPage( "/ログイン" ) .loginProcessingUrlを( "/ doLogin" ) // ログインページと成功したジャンプページを指定した後 .successForwardUrl( "/ loadIndex" ) .ANDを()。authorizeRequests() .antMatchers(commonProperties.getAllowList()) // URL上記のすべてのユーザーのためにアクセス(ログインなし) .permitAll() .AND() .authorizeRequestsを() .anyRequest() //は、上記に加えて、ログインする必要があります .authenticated() .AND() .logout() // 指定されたログアウトURL .logoutUrl( "/ doLogout" ) .invalidateHttpSession(trueに) .AND() .headers() .frameOptions() // フレームフレーム .sameOrigin() // CSRF保護は、特別なクロスドメインURLの無視 (.ANDを)。CSRF()。ignoringAntMatchers(commonProperties.getAllowList()) ; } / ** *静的リソース解放 *の@paramのウェブ * / @Override 公共 無効の設定(WebSecurity社のWeb){ // 静的リソースフィルター web.ignoring()antMatchers( "/ ** / * JS。"、「/。 ** / *。cssの"" /**/*.png "" /**/*.jpg "" /**/*.gif "" /**/*.map」); } / ** @paramの認証 * @throws 例外 * / @Overrideは、保護されたボイド設定(AuthenticationManagerBuilderのAUTH)をスロー例外{ loginAuthenticationProvider.setUserDetailsService(customUserDetailsService)を、 loginAuthenticationProvider.setPasswordEncoder(customPasswordEncoder)。 auth.authenticationProvider(loginAuthenticationProvider)。スーパー.configure(AUTH)。 } / ** *自定义认证管理类 * @return * @throws 例外 * / @Bean *カスタム認証方法 * @Override 公共 AuthenticationManager authenticationManagerBean()スロー{例外を 返す スーパー)(.authenticationManagerBean。 } / ** *自定义密码加密类 * @return * / @Bean 公共PasswordEncoder passwordEncoder(){ 戻りPasswordEncoderFactories.createDelegatingPasswordEncoderを(); } }
2. [カスタムアカウントストレージクラス
@Service パブリック クラス CustomUserDetailsServiceは実装UserDetailsService { 民間 最終AuthTokenService authTokenServiceを。 プライベートロガーのログ= LoggerFactory.getLogger(この.getClass()); @Autowired 公共CustomUserDetailsService(AuthTokenService authTokenService){ この .authTokenService = authTokenService。 } / ** *将用户详细信息放入セキュリティセッション中 * @paramのユーザ名 * @return * / @Overrideの 公共LoadUserByUsernameのUserDetails(文字列名){ 試み{ Assert.IsTrue(StringUtils.isNotBlank(ユーザー名)、「ユーザーまたはパスワードが間違っている、再入力してください」); // ユーザ名でユーザの詳細を取得し、許可が構築される UserDTOのUserInfo = authTokenService.getUserDetail (ユーザー名); ResourceBOリソース = userInfo.getResource(); リスト <GrantedAuthority>当局= 新しい新しいのArrayList <GrantedAuthority> (); IF(リソース=!ヌル){ buildAuth(リソース、当局); } を返す 新しい新UserBO(のUserInfo、当局); } キャッチ(例外:IllegalArgumentException E){ スロー 新しい新 UsernameNotFoundException( "ユーザーまたはパスワードが、再入力してください" ); } キャッチ(例外E){ log.error( "異常なユーザ情報取得" 、E) ; スロー 新しい新 UsernameNotFoundException(「ユーザーまたはパスワード、再入力してください」); } } }
3.カスタムパスワード暗号化クラス
@Service パブリック クラス CustomPasswordEncoderが実装PasswordEncoder { @Override パブリック文字エンコード(たCharSequenceたCharSequence)は{ 返すcharSequence.toStringを(); } @Override パブリック ブールマッチ(たCharSequenceたCharSequence、ストリングS){ 戻りs.equals(エンコード(たCharSequence))。 } }
4. カスタムセキュリティ認証クラス
@Component パブリック クラス LoginAuthenticationProviderは延びDaoAuthenticationProvider { @Autowired プライベートCustomUserDetailsService customUserDetailsServiceと、 @Autowired プライベートCustomPasswordEncoder customPasswordEncoder。 @Autowired プライベート ボイドsetJdbcUserDetailsService(){ setUserDetailsService(customUserDetailsService)。 } / ** *自定义セキュリティ国际化 * / @PostConstruct 公共 ボイドinitProvider(){ ReloadableResourceBundleMessageSource localMessageSource = 新しいですReloadableResourceBundleMessageSource(); localMessageSource.setBasenames( "messages_zh_CN" ); メッセージ = 新しいMessageSourceAccessor(localMessageSource)。 } / ** *复写认证失败方法 * @paramのuserDetails * @paramの認証 *は@throws 含むAuthenticationException * / @Overrideが 保護 ボイド additionalAuthenticationChecks(UserDetailsのuserDetails、UsernamePasswordAuthenticationToken認証)がスロー含むAuthenticationExceptionを{ 場合(authentication.getCredentials()== NULL ){ logger.debugは( "認証に失敗しました:なし認証情報がありません" )。 スロー 新しい BadCredentialsException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.badCredentials"、 "悪いの資格情報を" )); } 文字列presentedPassword = authentication.getCredentials()のtoString()。 もし(!customPasswordEncoder.matches(presentedPassword、userDetails.getPassword())){ logger.debug( "認証に失敗しました:パスワードが格納されている値と一致しません" ); スロー 新しいですBadCredentialsException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.badCredentials"、 "悪い資格証明書" )); } } }