spring security之httpSecurity使用示例


httpSecurity

   類似於spring security的xml配置文件命名空間配置中的<http>元素。它允許對特定的http請求基於安全考慮進行配置。默認情況下,適用於所有的請求,但可以使用requestMatcher(RequestMatcher)或者其它相似的方法進行限制。

使用示例:

最基本的基於表單的配置如下。該配置將所有的url訪問權限設定為角色名稱為"ROLE_USER".同時也定義了內存認證模式:使用用戶名"user"和密碼“password”,角色"ROLE_USER"來認證。

  @Configuration
  @EnableWebSecurity
  public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

 配置基於openId的認證方式

 basic示例,不使用attribute exchange

             @Configuration
      @EnableWebSecurity
      public class OpenIDLoginConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .openidLogin() .permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() // the username must match the OpenID of the user you are // logging in with .withUser("https://www.google.com/accounts/o8/id?id=lmkCn9xzPdsxVwG7pjYMuDgNNdASFmobNkcRPaWU") .password("password") .roles("USER"); } }

下面展示一個更高級的示例,使用attribute exchange

      @Configuration
      @EnableWebSecurity
      public class OpenIDLoginConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .openidLogin() .loginPage("/login") .permitAll() .authenticationUserDetailsService(new AutoProvisioningUserDetailsService()) .attributeExchange("https://www.google.com/.") .attribute("email") .type("http://axschema.org/contact/email") .required(true) .and() .attribute("firstname") .type("http://axschema.org/namePerson/first") .required(true) .and() .attribute("lastname") .type("http://axschema.org/namePerson/last") .required(true) .and() .and() .attributeExchange(".yahoo.com.") .attribute("email") .type("http://schema.openid.net/contact/email") .required(true) .and() .attribute("fullname") .type("http://axschema.org/namePerson") .required(true) .and() .and() .attributeExchange(".myopenid.com.") .attribute("email") .type("http://schema.openid.net/contact/email") .required(true) .and() .attribute("fullname") .type("http://schema.openid.net/namePerson") .required(true); } } public class AutoProvisioningUserDetailsService implements AuthenticationUserDetailsService&lt;OpenIDAuthenticationToken&gt; { public UserDetails loadUserDetails(OpenIDAuthenticationToken token) throws UsernameNotFoundException { return new User(token.getName(), "NOTUSED", AuthorityUtils.createAuthorityList("ROLE_USER")); } }

增加響應安全報文頭

默認情況下當使用WebSecuirtyConfigAdapter的默認構造函數時激活。

僅觸發Headers()方法而不觸發其它方法或者接受WebSecurityConfigureerAdater默認的,等同於:

      @Configuration
      @EnableWebSecurity
       public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .headers() .contentTypeOptions(); .xssProtection() .cacheControl() .httpStrictTransportSecurity() .frameOptions() .and() ...; } }

取消安全報文頭,如下:

      @Configuration
      @EnableWebSecurity
      public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .headers().disable() ...; } }

使用部分安全報文頭

觸發headers()方法的返回結果,例如,只使用HeaderConfigurer的cacheControll()方法和HeadersConfigurer的frameOptions()方法.

      @Configuration
      @EnableWebSecurity
      public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .headers() .cacheControl() .frameOptions() .and() ...; } }

配置session管理

下面的配置展示了只允許認證用戶在同一時間只有一個實例是如何配置的。若一個用戶使用用戶名為"user"認證並且沒有退出,同一個名為“user”的試圖再次認證時,第一個用戶的session將會強制銷毀,並設置到"/login?expired"的url。

            @Configuration
      @EnableWebSecurity
      public class SessionManagementSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().hasRole("USER") .and() .formLogin() .permitAll() .and() .sessionManagement() .maximumSessions(1) .expiredUrl("/login?expired"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth. inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

當使用SessionManagementConfigurer的maximumSessio(int)時不用忘記為應用配置HttpSessionEventPublisher,這樣能保證過期的session能夠被清除。

在web.xml中可以這樣配置:

      <listener>
           <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>;
      </listener>

配置PortMapper

允許配置一個從HttpSecurity的getSharedObject(Class)方法中獲取的PortMapper。當http請求跳轉到https或者https請求跳轉到http請求時(例如我們和requiresChanenl一起使用時),別的提供的SecurityConfigurer對象使用P誒賬戶的PortMapper作為默認的PortMapper。默認情況下,spring security使用PortMapperImpl來映射http端口8080到https端口8443,並且將http端口的80映射到https的端口443.

配置示例如下,下面的配置將確保在spring security中的http請求端口9090跳轉到https端口9443 並且將http端口80跳轉到https443端口。

      @Configuration
      @EnableWebSecurity
      public class PortMapperSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin() .permitAll() .and() // Example portMapper() configuration  .portMapper() .http(9090).mapsTo(9443) .http(80).mapsTo(443); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

配置基於容器的預認證

在這個場景中,servlet容器管理認證。

配置示例:

下面的配置使用HttpServletRequest中的principal,若用戶的角色是“ROLE_USER”或者"ROLE_ADMIN",將會返回Authentication結果。

    @Configuration
      @EnableWebSecurity
      public class JeeSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() // Example jee() configuration  .jee() .mappableRoles("ROLE_USER", "ROLE_ADMIN"); } }

開發者希望使用基於容器預認證時,需要在web.xml中配置安全限制。例如:

 <login-config>
          <auth-method>FORM</auth-method>
          <form-login-config>
              <form-login-page>/login</form-login-page>
              <form-error-page>/login?error</form-error-page>
          </form-login-config>
      </login-config>
     
      <security-role>
          <role-name>ROLE_USER</role-name>
      </security-role>
      <security-constraint>
          <web-resource-collection>
          <web-resource-name>Public</web-resource-name>
              <description>Matches unconstrained pages</description>
              <url-pattern>/login</url-pattern>
              <url-pattern>/logout</url-pattern>
              <url-pattern>/resources/</url-pattern>
          </web-resource-collection>
      </security-constraint>
      <security-constraint>
          <web-resource-collection>
              <web-resource-name>Secured Areas</web-resource-name>
              <url-pattern>/</url-pattern>
          </web-resource-collection>
          <auth-constraint>
              <role-name>ROLE_USER</role-name>
          </auth-constraint>
      </security-constraint>

配置基於X509的預認證

配置示例,下面的配置試圖從X509證書中提取用戶名,注意,為完成這個工作,客戶端請求證書需要配置到servlet容器中。

      @Configuration
      @EnableWebSecurity
      public class X509SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() // Example x509() configuration  .x509(); } }

配置Remember-me服務

配置示例,下面的配置展示了如何允許基於token的remember-me的認證。若http參數中包含一個名為“remember-me”的參數,不管session是否過期,用戶記錄將會被記保存下來。

 @Configuration
      @EnableWebSecurity
      public class RememberMeSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin() .permitAll() .and() // Example Remember Me Configuration  .rememberMe(); } }

限制HttpServletRequest的請求訪問

配置示例,最基本的示例是配置所有的url訪問都需要角色"ROLE_USER".下面的配置要求每一個url的訪問都需要認證,並且授權訪問權限給用戶"admin"和"user".

             @Configuration
      @EnableWebSecurity
      public class AuthorizeUrlsSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER") .and() .withUser("adminr") .password("password") .roles("ADMIN","USER"); } }

同樣,也可以配置多個url。下面的配置要求以/admin/開始的url訪問權限為“admin”用戶。

 @Configuration
      @EnableWebSecurity
      public class AuthorizeUrlsSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/**").hasRole("USER") .and() .formLogin(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER") .and() .withUser("adminr") .password("password") .roles("ADMIN","USER"); } }

注意:匹配起效是按照順序來的。因此如果下面的配置是無效的,因為滿足第一個規則后將不會檢查第二條規則:

      http
          .authorizeRequests()
              .antMatchers("/**").hasRole("USER") .antMatchers("/admin/**").hasRole("ADMIN")

增加CSRF支持

默認情況下,當使用WebSecurityConfigurerAdapter時的默認構造方法時CSRF是激活的。你可以使用如下方法關閉它:

      @Configuration
      @EnableWebSecurity
      public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() ...; } }

增加logout支持

默認支持,當使用WebSecurityConfigurerAdapter時Logout是支持的。當用戶發出“/logout”請求時,系統將會銷毀session並且清空配置的rememberMe()認證,然后清除SecurityContextHolder,最后跳向logout成功頁面或者登陸頁面。

 @Configuration
      @EnableWebSecurity
      public class LogoutSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin() .and() // sample logout customization  .logout() .logout() .deleteCookies("remove") .invalidateHttpSession(false) .logoutUrl("/custom-logout") .logoutSuccessUrl("/logout-success"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

匿名用戶控制

使用WebSecurityConfigurerAdapter時自動綁定。默認情況下,匿名用戶有一個AnonymousAuthenticationToken標示,包含角色"ROLE_ANONYMOUS"。

下面的配置展示了如何指定匿名用戶應該包含"ROLE_ANON".

             @Configuration
      @EnableWebSecurity
      public class AnononymousSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin() .and() // sample anonymous customization  .anonymous() .authorities("ROLE_ANON"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

基於表單的認證

若FormLoginConfigurer的loginpage(String)沒有指定,將會產生一個默認的login頁面。

示例配置:

 @Configuration
      @EnableWebSecurity
      public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/**").hasRole("USER") .and() .formLogin(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

下面的示例展示了自定義的表單認證:

 @Configuration
      @EnableWebSecurity
      public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").hasRole("USER") .and() .formLogin() .usernameParameter("j_username") // default is username .passwordParameter("j_password") // default is password .loginPage("/authentication/login") // default is /login with an HTTP get .failureUrl("/authentication/login?failed") // default is /login?error .loginProcessingUrl("/authentication/login/process"); // default is /login with an HTTP post  } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

配置安全通道

為使配置生效,需至少配置一個通道的映射。

配置示例:

下面例子展示了如何將每個請求都使用https通道。

 @Configuration
      @EnableWebSecurity
      public class ChannelSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/**").hasRole("USER") .and() .formLogin() .and() .channelSecurity() .anyRequest().requiresSecure(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

配置http 基本認證

配置示例:

 @Configuration
      @EnableWebSecurity
      public class HttpBasicSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/**").hasRole("USER").and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

配置要觸發的HttpRequest

重寫RequestMatcher方法、antMatcher()z、regexMatcher()等。

配置示例

下面的配置使HttpSecurity接收以"/api/","/oauth/"開頭請求。

 @Configuration
      @EnableWebSecurity
      public class RequestMatchersSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers() .antMatchers("/api/**","/oauth/**") .and() .authorizeRequests() .antMatchers("/**").hasRole("USER").and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

下面的配置和上面的相同:

 @Configuration
      @EnableWebSecurity
      public class RequestMatchersSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers() .antMatchers("/api/**") .antMatchers("/oauth/**") .and() .authorizeRequests() .antMatchers("/**").hasRole("USER").and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

同樣也可以這樣使用:

@Configuration
      @EnableWebSecurity
      public class RequestMatchersSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers() .antMatchers("/api/**") .and() .requestMatchers() .antMatchers("/oauth/**") .and() .authorizeRequests() .antMatchers("/**").hasRole("USER").and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user") .password("password") .roles("USER"); } }

 

小結:

   本文是從httpSecurity代碼中整理得來的,有助於對spring security的全面理解。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM