详解spring security之httpSecurity使用示例
作者:一天不进步,就是退步 发布时间:2023-08-03 09:46:17
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<OpenIDAuthenticationToken> {
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的全面理解。
来源:https://www.cnblogs.com/davidwang456/p/4549344.html
猜你喜欢
- 问题现象:HTTP Status 403-Invalid CSRF Token 'null' was found on th
- springboot微服务内置了tomcat,在工程目录下执行:mvn clean package,可以将项目打成jar,通过java -j
- synchronized关键字顾名思义,是用于同步互斥的作用的。这里精简的记一下它的使用方法以及意义:1. 当synchronized修饰
- 一.优先队列的应用优先队列在程序开发中屡见不鲜,比如操作系统在进行进程调度时一种可行的算法是使用优先队列,当一个新的进程被fork()出来后
- 如题,主要使用AsReadOnly这个方法就可以了List<int> a = new List<int> {1, 2
- 1. 注解开发依赖注入1.1 使用@Autowired注解开启自动装配模式@Servicepublic class BookServiceI
- 对openfeign不清楚的同学可以参考下我的这篇文章:springboot~openfeign从此和httpClient说再见对于open
- ①概念二叉搜索树又称二叉排序树,它或者是一棵空树**,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
- 前言继承是面向对象语法的三大特征之一。继承可以降低代码编写的冗余度,提高编程的效率。通过继承,子类获得了父类的成员变量和方法。一个子类如何继
- 本文主要对SpringBoot2.x参数校验进行简单总结,其中SpringBoot使用的2.4.5版本。一、引入依赖<dependen
- 一,网络编程中两个主要的问题一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。在TCP/IP协议中I
- 一、题目描述题目实现:在进行网络编程时,由于进行网络连接是比较消耗资源的,因此,可以对连接的等待时间进行设置,如果在规定的时间没有进行连接,
- 很久之前也写过一篇使用Jitpack发布Android开源库的文章,详见Android发布项目到jitpack的完整步骤近来因为工作原因,又
- 最近做了一个MyEclipse项目,但是没开始多久就发现了这个问题:只要文件被修改过,不论多小的修改,保存的时候都会跳出一个框框,里面写着t
- Linux下的五种I/O模型1)阻塞I/O(blocking I/O)2)非阻塞I/O (nonblocking I/O)3) I/O复用(
- @TransactionalEventListener监听事务项目背景最近在项目遇到一个问题A方法体内有 INSERT、UPDATE或者DE
- 目录一、ThreadLocal简介二、ThreadLocal简单使用三、ThreadLocal的实现原理1、set方法源码2、get方法源码
- 前提最近发现各个频道推荐了很多ULID相关文章,这里对ULID的规范文件进行解读,并且基于Java语言自行实现ULID,通过此实现过程展示U
- 在java的开发中,java开发人员建议,尽量少用内部类,要把内部类提出他所处的那个类,单独生成一个类。直接来代码:package com.
- switch语句的格式如下:(它的功能是选出一段代码执行) switch(整数选择因子) { case 整数值1 : 语句; break;