詳解spring security之httpSecurity使用示例
httpSecurity
類似于spring security的xml配置文件命名空間配置中的<http>元素。它允許對特定的http請求基于安全考慮進(jìn)行配置。默認(rèn)情況下,適用于所有的請求,但可以使用requestMatcher(RequestMatcher)或者其它相似的方法進(jìn)行限制。
使用示例:
最基本的基于表單的配置如下。該配置將所有的url訪問權(quán)限設(shè)定為角色名稱為"ROLE_USER".同時也定義了內(nèi)存認(rèn)證模式:使用用戶名"user"和密碼“password”,角色"ROLE_USER"來認(rèn)證。
@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的認(rèn)證方式
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<OpenIDAuthenticationToken> {
public UserDetails loadUserDetails(OpenIDAuthenticationToken token) throws UsernameNotFoundException {
return new User(token.getName(), "NOTUSED", AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
增加響應(yīng)安全報(bào)文頭
默認(rèn)情況下當(dāng)使用WebSecuirtyConfigAdapter的默認(rèn)構(gòu)造函數(shù)時激活。
僅觸發(fā)Headers()方法而不觸發(fā)其它方法或者接受WebSecurityConfigureerAdater默認(rèn)的,等同于:
@Configuration
@EnableWebSecurity
public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.contentTypeOptions();
.xssProtection()
.cacheControl()
.httpStrictTransportSecurity()
.frameOptions()
.and()
...;
}
}
取消安全報(bào)文頭,如下:
@Configuration
@EnableWebSecurity
public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
...;
}
}
使用部分安全報(bào)文頭
觸發(fā)headers()方法的返回結(jié)果,例如,只使用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管理
下面的配置展示了只允許認(rèn)證用戶在同一時間只有一個實(shí)例是如何配置的。若一個用戶使用用戶名為"user"認(rèn)證并且沒有退出,同一個名為“user”的試圖再次認(rèn)證時,第一個用戶的session將會強(qiáng)制銷毀,并設(shè)置到"/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");
}
}
當(dāng)使用SessionManagementConfigurer的maximumSessio(int)時不用忘記為應(yīng)用配置HttpSessionEventPublisher,這樣能保證過期的session能夠被清除。
在web.xml中可以這樣配置:
<listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>; </listener>
配置PortMapper
允許配置一個從HttpSecurity的getSharedObject(Class)方法中獲取的PortMapper。當(dāng)http請求跳轉(zhuǎn)到https或者h(yuǎn)ttps請求跳轉(zhuǎn)到http請求時(例如我們和requiresChanenl一起使用時),別的提供的SecurityConfigurer對象使用P誒賬戶的PortMapper作為默認(rèn)的PortMapper。默認(rèn)情況下,spring security使用PortMapperImpl來映射http端口8080到https端口8443,并且將http端口的80映射到https的端口443.
配置示例如下,下面的配置將確保在spring security中的http請求端口9090跳轉(zhuǎn)到https端口9443 并且將http端口80跳轉(zhuǎn)到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");
}
}
配置基于容器的預(yù)認(rèn)證
在這個場景中,servlet容器管理認(rèn)證。
配置示例:
下面的配置使用HttpServletRequest中的principal,若用戶的角色是“ROLE_USER”或者"ROLE_ADMIN",將會返回Authentication結(jié)果。
@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");
}
}
開發(fā)者希望使用基于容器預(yù)認(rèn)證時,需要在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的預(yù)認(rèn)證
配置示例,下面的配置試圖從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服務(wù)
配置示例,下面的配置展示了如何允許基于token的remember-me的認(rèn)證。若http參數(shù)中包含一個名為“remember-me”的參數(shù),不管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的訪問都需要認(rèn)證,并且授權(quán)訪問權(quán)限給用戶"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訪問權(quán)限為“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");
}
}
注意:匹配起效是按照順序來的。因此如果下面的配置是無效的,因?yàn)闈M足第一個規(guī)則后將不會檢查第二條規(guī)則:
http
.authorizeRequests()
.antMatchers("/**").hasRole("USER")
.antMatchers("/admin/**").hasRole("ADMIN")
增加CSRF支持
默認(rèn)情況下,當(dāng)使用WebSecurityConfigurerAdapter時的默認(rèn)構(gòu)造方法時CSRF是激活的。你可以使用如下方法關(guān)閉它:
@Configuration
@EnableWebSecurity
public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
...;
}
}
增加logout支持
默認(rèn)支持,當(dāng)使用WebSecurityConfigurerAdapter時Logout是支持的。當(dāng)用戶發(fā)出“/logout”請求時,系統(tǒng)將會銷毀session并且清空配置的rememberMe()認(rèn)證,然后清除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時自動綁定。默認(rèn)情況下,匿名用戶有一個AnonymousAuthenticationToken標(biāo)示,包含角色"ROLE_ANONYMOUS"。
下面的配置展示了如何指定匿名用戶應(yīng)該包含"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");
}
}
基于表單的認(rèn)證
若FormLoginConfigurer的loginpage(String)沒有指定,將會產(chǎn)生一個默認(rèn)的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");
}
}
下面的示例展示了自定義的表單認(rèn)證:
@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 基本認(rèn)證
配置示例:
@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");
}
}
配置要觸發(fā)的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");
}
}
小結(jié):
本文是從httpSecurity代碼中整理得來的,有助于對spring security的全面理解。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-08-08
分析講解SpringMVC注解配置如何實(shí)現(xiàn)
這篇文章主要介紹了本文要介紹用注解方式代替web.xml與SpringMVC的配置文件,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05
spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用
這篇文章主要給大家介紹了關(guān)于spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
java實(shí)現(xiàn)的導(dǎo)出Excel工具類實(shí)例
這篇文章主要介紹了java實(shí)現(xiàn)的導(dǎo)出Excel工具類,結(jié)合具體實(shí)例形式分析了java導(dǎo)出Excel導(dǎo)出并生成Excel表格相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-10-10
SpringBoot中的定時任務(wù)和異步調(diào)用詳解
這篇文章主要介紹了SpringBoot中的定時任務(wù)和異步調(diào)用詳解,SpringBoot 定時任務(wù)是一種在SpringBoot應(yīng)用中自動執(zhí)行任務(wù)的機(jī)制,通過使用Spring框架提供的@Scheduled注解,我們可以輕松地創(chuàng)建定時任務(wù),需要的朋友可以參考下2023-10-10
Java中使用正則表達(dá)式的一個簡單例子及常用正則分享
這篇文章主要介紹了Java中使用正則表達(dá)式的一個簡單例子及常用正則分享,本文用一個驗(yàn)證Email的例子講解JAVA中如何使用正則,并羅列了一些常用的正則表達(dá)式,需要的朋友可以參考下2015-06-06
httpclient的disableConnectionState方法工作流程
這篇文章主要為大家介紹了httpclient的disableConnectionState方法工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11

