玩转Spring Boot 使用Spring security

来源:互联网 发布:淘宝达人帖子 编辑:程序博客网 时间:2024/04/29 23:24

玩转Spring Boot 使用Spring security


      Spring Boot与Spring Security在一起开发非常简单,充分体现了自动装配的强大,Spring Security是Spring Boot官方推荐使用的安全框架。配置简单,功能强大。接下来将说说Spring Boot使用Spring security进行安全控制。

1.Spring Boot 内置属性参数

      Spring Boot 提供的内置配置参数以security为前缀,具体属性如下:
# SECURITY (SecurityProperties 类中)
security.basic.authorize-mode=role # 应用授权模式,ROLE=成员必须是安全的角色,AUTHENTICATED=经过身份验证的用户,NONE=没有设置安全授权
security.basic.enabled=true # 启用基本身份认证
security.basic.path=/** # 拦截策略,以逗号分隔
security.basic.realm=Spring # HTTP基本realm
security.enable-csrf=false # 启用csrf支持
security.filter-order=0 # 过滤器执行顺序
security.filter-dispatcher-types=ASYNC, FORWARD, INCLUDE, REQUEST # security 过滤器链dispatcher类型
security.headers.cache=true # 启用缓存控制 HTTP headers.
security.headers.content-type=true # 启用 "X-Content-Type-Options" header.
security.headers.frame=true # 启用 "X-Frame-Options" header.
security.headers.hsts= # HTTP Strict Transport Security (HSTS) mode (none, domain, all).
security.headers.xss=true # 启用跨域脚本 (XSS) 保护.
security.ignored= # 安全策略,以逗号分隔
security.require-ssl=false # 启用所有请求SSL
security.sessions=stateless # Session 创建策略(always, never, if_required, stateless).
security.user.name=user # 默认用户名
security.user.password= # 默认用户名密码
security.user.role=USER # 默认用户角色

# SECURITY OAUTH2 CLIENT (OAuth2ClientProperties 类中)
security.oauth2.client.client-id= # OAuth2 client id.
security.oauth2.client.client-secret= # OAuth2 client secret. A random secret is generated by default

# SECURITY OAUTH2 RESOURCES (ResourceServerProperties 类中)
security.oauth2.resource.id= # Identifier of the resource.
security.oauth2.resource.jwt.key-uri= # The URI of the JWT token. Can be set if the value is not available and the key is public.
security.oauth2.resource.jwt.key-value= # The verification key of the JWT token. Can either be a symmetric secret or PEM-encoded RSA public key.
security.oauth2.resource.prefer-token-info=true # Use the token info, can be set to false to use the user info.
security.oauth2.resource.service-id=resource #
security.oauth2.resource.token-info-uri= # URI of the token decoding endpoint.
security.oauth2.resource.token-type= # The token type to send when using the userInfoUri.
security.oauth2.resource.user-info-uri= # URI of the user endpoint.

# SECURITY OAUTH2 SSO (OAuth2SsoProperties 类中)
security.oauth2.sso.filter-order= # Filter order to apply if not providing an explicit WebSecurityConfigurerAdapter
security.oauth2.sso.login-path=/login # Path to the login page, i.e. the one that triggers the redirect to the OAuth2 Authorization Server

以上是官方给出的配置属性以及默认值列表。

2.security Starter Poms

[html] view plain copy
  1. <dependency>  
  2.             <groupId>org.springframework.boot</groupId>  
  3.             <artifactId>spring-boot-starter-security</artifactId>  
  4.         </dependency>  

3.security hello world

3.1创建工程

      创建工程springboot-security并加入security Starter Poms,完整代码如下:
[html] view plain copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.     <groupId>com.chengli</groupId>  
  5.     <artifactId>springboot-security</artifactId>  
  6.     <version>0.0.1-SNAPSHOT</version>  
  7.     <packaging>jar</packaging>  
  8.     <name>springboot-security</name>  
  9.     <url>http://maven.apache.org</url>  
  10.     <parent>  
  11.         <groupId>org.springframework.boot</groupId>  
  12.         <artifactId>spring-boot-starter-parent</artifactId>  
  13.         <version>1.4.3.RELEASE</version>  
  14.     </parent>  
  15.     <properties>  
  16.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  17.         <java.version>1.8</java.version>  
  18.     </properties>  
  19.     <dependencies>  
  20.         <dependency>  
  21.             <groupId>org.springframework.boot</groupId>  
  22.             <artifactId>spring-boot-starter</artifactId>  
  23.         </dependency>  
  24.         <dependency>  
  25.             <groupId>org.springframework.boot</groupId>  
  26.             <artifactId>spring-boot-starter-web</artifactId>  
  27.         </dependency>  
  28.         <dependency>  
  29.             <groupId>org.springframework.boot</groupId>  
  30.             <artifactId>spring-boot-starter-security</artifactId>  
  31.         </dependency>  
  32.         <dependency>  
  33.             <groupId>org.springframework.boot</groupId>  
  34.             <artifactId>spring-boot-devtools</artifactId>  
  35.             <optional>true</optional>  
  36.         </dependency>  
  37.     </dependencies>  
  38.     <build>  
  39.         <plugins>  
  40.             <plugin>  
  41.                 <groupId>org.springframework.boot</groupId>  
  42.                 <artifactId>spring-boot-maven-plugin</artifactId>  
  43.             </plugin>  
  44.         </plugins>  
  45.     </build>  
  46. </project>  

3.2创建入口启动类

[java] view plain copy
  1. package com.chengli.springboot;  
  2.   
  3. import org.springframework.boot.SpringApplication;  
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  5. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
  6. import org.springframework.web.bind.annotation.RequestMapping;  
  7. import org.springframework.web.bind.annotation.RestController;  
  8.   
  9. @RestController  
  10. @SpringBootApplication  
  11. @EnableWebSecurity //启用web安全  
  12. public class MainConfig {  
  13.     public static void main(String[] args) {  
  14.         SpringApplication.run(MainConfig.class, args);  
  15.     }  
  16.   
  17.     @RequestMapping("/security")  
  18.     public String security() {  
  19.         return "hello world security";  
  20.     }  
  21. }  


3.3创建application.properties

      在application.properties中设置默认用户名以及默认密码
[html] view plain copy
  1. security.user.name=chengli  
  2. security.user.password=123456  

3.4启动

      到这里我们直接运行MainConfig试试吧,在浏览器上输入:http://localhost:8080/security,Spring security会为我们提供一个默认的登录页面,界面如下:


输入用户名密码登录进去,页面上会显示hello world security。

4.自定义security

      实际开发中,不可能都用security提供的默认配置,我们需要自定义一些配置,比如拦截的请求路径,以及从数据库中获取用户等等,那么接下来说说一些常用的配置。以下代码建立在以上工程中。

4.1新建security配置类:SecurityConfig

      新建SecurityConfig类并继承WebSecurityConfigurerAdapter,WebSecurityConfigurerAdapter是security提供用于更改默认配置,实现configure方法,代码如下:
[java] view plain copy
  1. package com.chengli.springboot.security;  
  2.   
  3. import org.springframework.context.annotation.Configuration;  
  4. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
  5. import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
  6. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
  7. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
  8.   
  9. @Configuration  
  10. @EnableWebSecurity  
  11. public class SecurityConfig extends WebSecurityConfigurerAdapter {  
  12.       
  13.     /**定义认证用户信息获取来源,密码校验规则等*/  
  14.     @Override  
  15.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {  
  16.         //inMemoryAuthentication 从内存中获取  
  17.         auth.inMemoryAuthentication().withUser("chengli").password("123456").roles("USER");  
  18.           
  19.         //jdbcAuthentication从数据库中获取,但是默认是以security提供的表结构  
  20.         //usersByUsernameQuery 指定查询用户SQL  
  21.         //authoritiesByUsernameQuery 指定查询权限SQL  
  22.         //auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery(query).authoritiesByUsernameQuery(query);  
  23.           
  24.         //注入userDetailsService,需要实现userDetailsService接口  
  25.         //auth.userDetailsService(userDetailsService);  
  26.     }  
  27.       
  28.     /**定义安全策略*/  
  29.     @Override  
  30.     protected void configure(HttpSecurity http) throws Exception {  
  31.         http.authorizeRequests()//配置安全策略  
  32.             .antMatchers("/","/hello").permitAll()//定义/请求不需要验证  
  33.             .anyRequest().authenticated()//其余的所有请求都需要验证  
  34.             .and()  
  35.         .logout()  
  36.             .permitAll()//定义logout不需要验证  
  37.             .and()  
  38.         .formLogin();//使用form表单登录  
  39.     }  
  40.       
  41. }  


4.2在入口启动类MainConfig加入以下方法

      这里为了方便演示就在加入一个方法
[java] view plain copy
  1. @RequestMapping("/hello")  
  2.     public String hello() {  
  3.         return "不验证哦";  
  4.     }  

4.4启动

      启动后,在浏览器上输入:http://localhost:8080/hello,我们看到是不需要验证直接在页面上输出:不验证哦。那在输入:http://localhost:8080/security,我们看到是需要进行验证的,那么输入用户名:chengli,密码:123456,我们看到页面输出:hello world security。这里为了方便演示用户信息是放在内存中,实际项目中使用数据库验证可以使用jdbc也可以实现userDetailsService类。


4.5开启方法权限校验

      在SecurityConfig类加上注解:@EnableGlobalMethodSecurity,该注解可以开启prePostEnabled,securedEnabled,jsr250Enabled的支持,这里演示使用@EnableGlobalMethodSecurity(prePostEnabled = true),开启对prePostEnabled 支持。在方法上加入@PreAuthorize注解,@PreAuthorize注解支持使用SpEL表达式。这里我们在MainConfig类中加入以下代码:
[java] view plain copy
  1. @PreAuthorize("hasRole('ROLE_ADMIN')")  
  2.     @RequestMapping("/authorize")  
  3.     public String authorize() {  
  4.         return "有权限访问";  
  5.     }  
在增加一个用户admin,修改以下代码,如下:
[java] view plain copy
  1. 修改前:  
  2. auth.inMemoryAuthentication().withUser("chengli").password("123456").roles("USER")  
  3. 修改后:  
  4. auth.inMemoryAuthentication().withUser("chengli").password("123456").roles("USER")  
  5.         .and().withUser("admin").password("123456").roles("ADMIN");  

这里我们在启动使用chengli登录后访问/authorize会返回403错误,使用admin登录访问页面输出有权限访问。

既然登录了那就有退出,默认的退出地址在LogoutConfigurer类中,当然也是可以自定义的,这里就不说了,在定义安全策略方法中调用即可。我们也可以在浏览器中输入logout退出,这里会出现错误,因为security默认开启了csrf,这里我为了方便就禁用了csrf。禁用代码如下:
[java] view plain copy
  1. //禁用csrf  
  2.         http.csrf().disable();  

这里对于spring security的内容就不介绍了,具体的看官方文档。
如果想学习Spring security 又对英文的文档望而生怯的话,那么给大家推荐一个系列博文:http://www.iteye.com/blogs/subjects/spring_security,作者写的还比较清楚就是版本相对于现在来说有点低,如果想学习新的特性那么还是看官方的文档吧。

本例完整示例代码在QQ交流群中:springboot-security.zip

有兴趣的朋友可以加群探讨相互学习:

Spring Boot QQ交流群:599546061
原创粉丝点击