春のセキュリティ(2) - WebSecurityConfigurer構成とフィルタ順序

  認証プロセスとアクセス許可が春する方法を知っている必要があります前に、セキュリティは我々が認証されたのは、すべてのユーザーが必要とすることを知っていますか?私たちは、春のセキュリティは、フォームベースの認証をサポートする方法を知りたいですか?そのため、あなたは仕事のWebSecurityConfigurerAdapterタイプを設定する方法を理解する必要があります。しかし、また、より自分の呼び出し元ワークフローを理解するためには、明確にフィルタの順序を理解する必要があります。

1. WebSecurityConfigurerAdapter

  WebSecurityConfigurerを作成するためのWebSecurityConfigurerAdapter簡単な方法を提供し、基本クラスとして、クラスは、カスタム設定クラスによって達成することができます。それは自動的にAbstractHttpConfigurerはあなたがAbstractHttpConfigurerを拡張するクラスを作成する必要があります達成したい、行こうSpringFactoriesLoaderから延びる見つけて、/ファイルMETA-INFを作成し、クラスパスにパスをspring.factories。例えば:

 org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = sample.MyClassThatExtendsAbstractHttpConfigurer
复制代码

そのソースコード解析:

   //1.init初始化:获取HttpSecurity和配置FilterSecurityInterceptor拦截器到WebSecurity
    public void init(final WebSecurity web) throws Exception {
            //获取HttpSecurity
	   final HttpSecurity http = getHttp();
    	//配置FilterSecurityInterceptor拦截器到WebSecurity
	    web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {
	    	public void run() {
		    	FilterSecurityInterceptor securityInterceptor = http
				    	.getSharedObject(FilterSecurityInterceptor.class);
		    	web.securityInterceptor(securityInterceptor);
		    }
	    });
    }
    ......
    //2.获取HttpSecurity的过程
    protected final HttpSecurity getHttp() throws Exception {
	if (http != null) {
		return http;
	}

	DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor
			.postProcess(new DefaultAuthenticationEventPublisher());
	localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);

	AuthenticationManager authenticationManager = authenticationManager();
	authenticationBuilder.parentAuthenticationManager(authenticationManager);
	Map<Class<? extends Object>, Object> sharedObjects = createSharedObjects();

	http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
			sharedObjects);
	if (!disableDefaults) {
		// 默认的HttpSecurity的配置
		http
	                //添加 CSRF 支持,使用WebSecurityConfigurerAdapter时,默认启用,禁用csrf().disable()
			.csrf().and() 
			//添加WebAsyncManagerIntegrationFilter
			.addFilter(new WebAsyncManagerIntegrationFilter())
			//允许配置异常处理
			.exceptionHandling().and()
			//将安全标头添加到响应
			.headers().and()
			//允许配置会话管理
			.sessionManagement().and()
			//HttpServletRequest之间的SecurityContextHolder创建securityContext管理
			.securityContext().and()
			//允许配置请求缓存
			.requestCache().and()
			//允许配置匿名用户
			.anonymous().and()
			//HttpServletRequestd的方法和属性注册在SecurityContext中
			.servletApi().and()
			//使用默认登录页面
			.apply(new DefaultLoginPageConfigurer<>()).and()
			//提供注销支持
			.logout();
		// @formatter:on
		ClassLoader classLoader = this.context.getClassLoader();
		List<AbstractHttpConfigurer> defaultHttpConfigurers =
				SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);

		for(AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
			http.apply(configurer);
		}
	}
	configure(http);
	return http;
    }
...
//3.可重写方法实现自定义的HttpSecurity
protected void configure(HttpSecurity http) throws Exception {
	logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");

	http
		.authorizeRequests()
			.anyRequest().authenticated()
			.and()
		.formLogin().and()
		.httpBasic();
}
....
复制代码

  セキュリティの初期化モジュールのソースコードは、「GET HttpSecurity」で見ることができinitと「WebSecurity社への設定FilterSecurityInterceptorインターセプターは、」我々は、すべてのユーザーが認証する必要がどのように春知りたいですか?私たちは、春のセキュリティは、フォームベースの認証をサポートする方法を知りたいですか?限り例外方法は、保護されたボイドのconfigure(HttpSecurity HTTP)を書き換えることができますがスローされます。だから我々はHttpSecurity方法、およびその構成方法の役割を理解する必要があります。次のセクションでは、HttpSecurityを議論します。

2. HttpSecurity

  HttpSecurity Webベースのセキュリティは、特定のHTTP要求のために構成することができます。一般的に使用されるいくつかは、次の表が含まれ、多くの方法があります。

方法 説明 ユースケース
CSRF() CSRFのサポートを追加し、WebSecurityConfigurerAdapterを使用し、デフォルトで有効になって 無効:. CSRFは、()(無効)
openidLogin() 検証のOpenIDに基づいて、 openidLogin()permitAll();
authorizeRequests() オープンアクセスHttpServletRequestのリクエストの使用を制限 authorizeRequests()。anyRequest()。認証されました()
フォーム・ログイン() 認証の開いているフォームは、不特定のFormLoginConfigurer#loginPage(文字列)場合、それはデフォルトのログインページが生成されます。 formLogin()。loginPage( "/認証/ログイン")。failureUrl( "/認証/?ログイン失敗")
oauth2Login() オープンOAuth 2.0の認証やOpenIDの接続1.0 認証されたauthorizeRequests().. anyRequest()。()...と()。oauth2Login()
私を覚えてますか() オープン構成は、テストを「私を忘れないでください」 authorizeRequests()。antMatchers( "/ **")。hasRoleも( "USER")。と()。formLogin()。permitAll()。と()。リメンバー・ミー()
かaddFilter() カスタムフィルタを追加します かaddFilter(新しいは、customFilter())
addFilterAt() 指定されたフィルター上の同じ位置にカスタムフィルタを追加します。 addFilterAt(新しいは、customFilter()、UsernamePasswordAuthenticationFilter.class)
addFilterAfter() フィルタ位置に指定されたカスタムフィルタを追加します。 addFilterAfter(新しいは、customFilter()、UsernamePasswordAuthenticationFilter.class)
requestMatchers() オープン設定HttpSecurity、開いたときにのみマッチRequestMatcher requestMatchers()。antMatchers( "/ API / **")
antMatchers() requestMatchersで使用するためのマッチングRequestMatcher() requestMatchers()。antMatchers( "/ API / **")
ログアウト() ログのサポートを追加します。ときに自動的に適用されますWebSecurityConfigurerAdapter、。デフォルトでは、アクセスURL「/ログアウト」、クリアするHTTPセッションの無効なユーザーには、「/ログイン?成功」にリダイレクトその後、構成された明確なSecurityContextHolder、および任意の#rememberMe()の認証をクリア ログアウト()deleteCookies( "削除")invalidateHttpSession(偽).logoutUrl( "/カスタム・ログアウト")logoutSuccessUrl( "/ログアウト成功")。。。。

HttpSecurity私たちはHttpSecurityを設定するために使用するための多くの方法があります。それらを設定していないここに非常に多く、勉強に行くことができます興味を持っています。

3. WebSecurityConfigurerAdapter使用

WebSecurityConfigurerAdapter例:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 @Autowired
 private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
 protected void configure(HttpSecurity http) throws Exception {    
     http
     //request 设置
     .authorizeRequests()   //http.authorizeRequests() 方法中的自定义匹配
     .antMatchers("/resources/**", "/signup", "/about").permitAll() // 指定所有用户进行访问指定的url          
     .antMatchers("/admin/**").hasRole("ADMIN")  //指定具有特定权限的用户才能访问特定目录,hasRole()方法指定用户权限,且不需前缀 “ROLE_“  
     .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")//          
     .anyRequest().authenticated()  //任何请求没匹配的都需要进行验证                                           
     .and()        //login设置  自定义登录页面且允许所有用户登录
     .formLogin()      
     .loginPage("/login") //The updated configuration specifies the location of the log in page  指定自定义登录页面
     .permitAll(); // 允许所有用户访问登录页面. The formLogin().permitAll() 方法
     .and 
     .logout()  //logouts 设置                                                              
     .logoutUrl("/my/logout")  // 指定注销路径                                              
     .logoutSuccessUrl("/my/index") //指定成功注销后跳转到指定的页面                                        
     .logoutSuccessHandler(logoutSuccessHandler)  //指定成功注销后处理类 如果使用了logoutSuccessHandler()的话, logoutSuccessUrl()就会失效                                
     .invalidateHttpSession(true)  // httpSession是否有效时间,如果使用了 SecurityContextLogoutHandler,其将被覆盖                                        
     .addLogoutHandler(logoutHandler)  //在最后增加默认的注销处理类LogoutHandler                
     .deleteCookies(cookieNamesToClear);//指定注销成功后remove cookies
     //增加在FilterSecurityInterceptor前添加自定义的myFilterSecurityInterceptor
     http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
   }
复制代码

注:この例では、参考値です

4.フィルタ次数

春のセキュリティフィルタの順序:

フィルタクラス 説明
ChannelProcessingFilter アクセス制御プロトコルフィルタは、我々はHTTPからHTTPSに切り替え、別のプロトコルにリダイレクトする可能性があります
SecurityContextPersistenceFilter SecurityContextがSecurityContextHolder情報やリクエストの終了時に空にセキュリティコンテキストを作成します。
ConcurrentSessionFilter 同時アクセス制御フィルタ、主な機能:SessionRegistryは、セッション情報がどの同時アクセス制御、セッションの有効期限が切れたかどうかを決定する取得しました。
HeaderWriterFilter いくつかのヘッダを追加するには、HTTPレスポンス
CsrfFilter クロスドメインフィルタ、フィルタCSRF保護
LogoutFilter フィルターの取り扱いをログに記録します
X509AuthenticationFilter 事前承認処理機構のX509のサポートを追加
CasAuthenticationFilter 後続の認証が正常に行うことができるように、認証フィルタは、その後、フィルタは、完全に組み立てられたSecurityContextHolder認証対象を含むことになります
UsernamePasswordAuthenticationFilter 後続の認証を適切に実行することができるように、フィルタは、完全に組み立てられたSecurityContextHolder認証対象を含むことになるた後、フィルタを、認定。フォーム認証は、最も一般的な方法の認定です。
BasicAuthenticationFilter 後続の認証が正常に行うことができるように、認証フィルタは、その後、フィルタは、完全に組み立てられたSecurityContextHolder認証対象を含むことになります
SecurityContextHolderAwareRequestFilter ServletRequestのこのフィルタは、パッケージにそのような要求は、より豊富なAPIを持っていました
JaasApiIntegrationFilter (JAAS)認証フィルタ
RememberMeAuthenticationFilter 認証処理フィルタメモリ、前面フィルタを行わない場合、すなわち、現在の要求が有効になっているリメンバー・ミー関数の認証処理がSecurityContextHolderに記憶された認証対象の後に、ユーザからクッキー、および認証プロセスを解析します。
AnonymousAuthenticationFilter 匿名认证处理过滤器,当SecurityContextHolder中认证信息为空,则会创建一个匿名用户存入到SecurityContextHolder中
SessionManagementFilter 会话管理Filter,持久化用户登录信息,可以保存到session中,也可以保存到cookie或者redis中
ExceptionTranslationFilter 异常处理过滤器,主要拦截后续过滤器(FilterSecurityInterceptor)操作中抛出的异常。
FilterSecurityInterceptor 安全拦截过滤器类,获取当前请求url对应的ConfigAttribute,并调用accessDecisionManager进行访问授权决策。

spring security的默认filter链:

 SecurityContextPersistenceFilter
->HeaderWriterFilter
->LogoutFilter
->UsernamePasswordAuthenticationFilter
->RequestCacheAwareFilter
->SecurityContextHolderAwareRequestFilter
->SessionManagementFilter
->ExceptionTranslationFilter
->FilterSecurityInterceptor
复制代码

在上节我们已分析了核心的filter源码以及功能。可回看上节源码分析更加深入的了解各个filter工作原理。

总结:

  在认证和访问授权过程前,首先必须进行WebSecurityConfigurer符合自身应用的security Configurer,也要清楚filter链的先后顺序,才能更好理解spring security的工作原理以及在项目中出现的问题定位。了解完准备工作,接下来将展开对认证和访问授权模块的工作流程研究以及项目示例分析。最后如有错误可评论告知。

转载于:https://juejin.im/post/5d0b1eb35188252f921b1535

おすすめ

転載: blog.csdn.net/weixin_34104341/article/details/93181624