OAuth2.0是一个关于受权的开放网络协议。git
该协议在第三方应用与服务提供平台之间设置了一个受权层。第三方应用须要服务资源时,并非直接使用用户账号密码登陆服务提供平台,而是经过服务提供平台的受权层获取token令牌,用户能够在受权时指定token的权限范围和有效期。第三方应用获取到token之后,才能够访问用户资源。github
OAuth 2.0定义了四种受权方式:web
假设有X用户、A系统、B系统,X是A系统中的用户,B系统须要访问A系统获取X用户的信息。spring
再举个受权码模式的例子:某网站QQ快速登陆、帐号绑定。apache
百度搜索“oauth2.0”浏览器
QQ互联官方文档,http://wiki.connect.qq.com安全
Spring Security是一个用于快速实现Web应用安全、认证的框架,能够快速和Spring Boot整合。服务器
开发者能够编写配置类继承WebSecurityConfigurerAdapter类,重写config方法自定义登陆页面、登陆失败逻辑、权限不足逻辑等,而且能够编写Filter实现更加复杂的图片验证码、短信验证码功能。网络
Spring Security也能够快速实现OAuth2.0受权服务器和资源服务器。在一个Spring Boot应用中,能够使用@EnableAuthorizationServer注解实现受权服务器,使用@EnableResourceServer注解实现资源服务器。app
例如
1 @SpringBootApplication 2 @EnableAuthorizationServer 3 @EnableResourceServer 4 public class BasicOauth2Application { 5 6 public static void main(String[] args) { 7 SpringApplication.run(BasicOauth2Application.class, args); 8 } 9 }
在application.properties文件配置client-id和client-secret参数
security.oauth2.client.client-id=net5ijy
security.oauth2.client.client-secret=123456
1 <parent> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-parent</artifactId> 4 <version>1.5.13.RELEASE</version> 5 </parent> 6 7 <dependencies> 8 <dependency> 9 <groupId>org.springframework.boot</groupId> 10 <artifactId>spring-boot-starter-web</artifactId> 11 </dependency> 12 <dependency> 13 <groupId>org.springframework.boot</groupId> 14 <artifactId>spring-boot-starter-security</artifactId> 15 </dependency> 16 <dependency> 17 <groupId>org.springframework.security.oauth</groupId> 18 <artifactId>spring-security-oauth2</artifactId> 19 </dependency> 20 </dependencies> 21 22 <build> 23 <plugins> 24 <plugin> 25 <groupId>org.apache.maven.plugins</groupId> 26 <artifactId>maven-compiler-plugin</artifactId> 27 <configuration> 28 <source>1.8</source> 29 <target>1.8</target> 30 <encoding>UTF-8</encoding> 31 </configuration> 32 </plugin> 33 </plugins> 34 </build>
加@EnableAuthorizationServer和@EnableResourceServer注解。
1 @SpringBootApplication 2 @EnableAuthorizationServer 3 @EnableResourceServer 4 public class BasicOauth2Application { 5 6 public static void main(String[] args) { 7 SpringApplication.run(BasicOauth2Application.class, args); 8 } 9 }
配置Security登陆用户
security.user.name=admin
security.user.password=123456
配置client-id和client-secret参数
security.oauth2.client.client-id=net5ijy
security.oauth2.client.client-secret=123456
编写controller
1 @RestController 2 @RequestMapping(value = "/") 3 public class TestController { 4 5 Logger log = LoggerFactory.getLogger(TestController.class); 6 7 @RequestMapping(value = "order/demo") 8 public String getDemo() { 9 Authentication auth = SecurityContextHolder.getContext() 10 .getAuthentication(); 11 log.info(auth.toString()); 12 return "Hello world"; 13 } 14 }
使用浏览器访问:
http://localhost:7000/oauth/authorize?response_type=code&client_id=net5ijy&redirect_uri=http://localhost:8080&scope=all
地址
http://localhost:7000/oauth/authorize
参数
response_type |
code |
client_id |
根据实际的client-id填写,此处写net5ijy |
redirect_uri |
生成code后的回调地址,http://localhost:8080 |
scope |
权限范围 |
登陆,使用的用户名、密码就是在application.properties中配置的admin和123456
security.user.name=admin
security.user.password=123456
容许受权
看到浏览器重定向到了http://localhost:8080并携带了code参数,这个code就是受权服务器生成的受权码
使用curl命令获取token令牌
curl --user net5ijy:123456 -X POST -d "grant_type=authorization_code&scope=all&redirect_uri=http%3a%2f%2flocalhost%3a8080&code=Q1dzfj" http://localhost:7000/oauth/token
地址
http://localhost:7000/oauth/token
参数
grant_type |
受权码模式,写authorization_code |
scope |
权限范围 |
redirect_uri |
回调地址,http://localhost:8080须要urlencode |
code |
就是上一步生成的受权码 |
返回值
1 { 2 "access_token": "547e258c-9c88-4130-a6d5-770b6b6ef3a4", 3 "token_type": "bearer", 4 "refresh_token": "19cf0168-913e-4f64-a766-72c0d43928ba", 5 "expires_in": 43199, 6 "scope": "all" 7 }
这样就获取到了token令牌,该token的访问权限范围是all权限,在12小时后失效。
curl http://localhost:7000/order/demo?access_token=547e258c-9c88-4130-a6d5-770b6b6ef3a4
在资源url后面加上access_token参数。
使用curl命令获取token令牌
curl --user net5ijy:123456 -X POST -d "grant_type=password&username=admin&password=123456&scope=all" http://localhost:7000/oauth/token
地址
http://localhost:7000/oauth/token
参数
grant_type |
密码模式,写password |
scope |
权限范围 |
username |
申请受权用户的用户名 |
password |
申请受权用户的密码 |
返回值
1 { 2 "access_token": "20d4f648-2ce4-4198-9f2a-025211efb689", 3 "token_type": "bearer", 4 "refresh_token": "9caccc03-5b81-48f9-a32e-45538c2f779c", 5 "expires_in": 43199, 6 "scope": "all" 7 }
这样就获取到了token令牌,该token的访问权限范围是all权限,在12小时后失效。
curl http://localhost:7000/order/demo?access_token=20d4f648-2ce4-4198-9f2a-025211efb689
https://github.com/xuguofeng/springsecurityoauth2