(此处省略2000字废话),第一次写博客,直接进入正题了。java
从初学者的角度来看,初次使用spring-boot和spring-security-oauth2整合,第一步天然是搭建一个“Hello World”先跑起来。那么二话不说,先来一个spring-boot的“Hello World”。web
本小菜使用idea+maven搭建项目,假设已经有了一个基本的maven-archetype-web架构,如图:spring
关于架构的目录结构,每一个人都有本身的见解,小菜的设计思路是client发送请求,按照“web”-“service”-“dao”的顺序与数据库交互,生成“po”。框架的配置放在“config”中,一些dao层或者其余层的封装放在“common”中,String、Excel等工具类放在util中,“api”是提供给外部访问的接口层,能够调用“service”,也能够调用“web”。数据库
1、搭建一个spring-boot的web项目。json
一、添加jar包:api
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
spring-boot基于spring-mvc,所以还须要浏览器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
如图:
依赖成功后,在External Libraies中会显示须要的jar包,接下来的快速简单web开发就是靠他们了。spring-mvc
二、spring-boot启动类安全
主要是配置@SpringBootApplication,大概意思就是告诉spring-boot程序入口在这里。
三、"web"访问层Controller类
四、启动spring-boot服务器
能够直接从App.class的main方法run或者debug启动,也可使用mvn spring-boot:run命令启动
输入http://localhost:8080/home,测试结果:
2、spring-security-oauth2基本使用
通过上面的步骤,相信和本菜同样的小菜鸟多少熟悉了idea&maven的使用。接下来是使用spring-security-oauth2保护接口的安全。
一、导入依赖jar包
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
引入后启动项目,观察控制台,大概意思就是spring-security-oauth2给spring-mvc增长了一些Filter,由于都是出自于spring家族,咱们不须要关心他们内部怎么实现,以及会不会有bug,咱们关心的是如何去使用,更深点的是出了问题如何解决以及性能方面的考虑。本菜水平有限,此处只能列出使用。
那么继续访问http://localhost:8080/home,发现须要输入用户名、密码,默认用户名user,密码会打印在控制台。
大功告成,spring-security-oauth2起做用了...
好吧,这只是开始,那么它是如何起的做用呢?
此处意思大概就是使用了“Basic”模式,后面是验证信息,本菜大胆猜想是用户名密码。固然官方说这是不安全的,很容易被其余人模拟浏览器请求,例如curl和httpClient。
为了方便以后调试,将服务器端口号设置为9999,设置登陆密码。resources目录下新增application.yml文件,内容:
spring:
application:
name: oauth2_test
server:
port: 9999
management:
context_path: /
security:
user:
password: 123123
logging:
level:
# org.springframework.security: DEBUG
重启server,登陆名和密码变为user 123123
二、配置受权服务的类型
受权类型主要有
authorization_code:受权码类型
implicit:隐式受权类型
password:资源全部者(即用户)密码类型
client_credentials:客户端凭据(客户端ID以及Key)类型
refresh_token:经过以上受权得到的刷新令牌来获取新的令牌
这里不考虑第二、4种受权类型。受权方法能够经过实现“AuthorizationServerConfigurer”接口或者继承“AuthorizationServerConfigurerAdapter”类,重写configure方法实现。
简单介绍spring-security-oauth2的实现机制主要是经过token,客户端发送请求时附上服务端给的token信息,若是验证正确则经过,authorization_code在获取token以前须要“第三方”认证,假设第三方提供给客户端一个受权码,客户端便可以拿着“第三方”给的受权码去服务器请求token。请求时须要一些参数,主要以下:
clientId:(必输)用来标识客户的Id
secret:(可选)客户端安全码,若是有的话
scope:用来限制客户端的访问范围,若是为空(默认)的话,那么客户端拥有所有的访问范围
authorizedGrantTypes:此客户端可使用的受权类型,默认为空
authorities:此客户端可使用的权限(基于Spring Security authorities)
对应的请求中默认参数名分别为client_id、secret、scope、grant_type、不须要。
配置示例代码:
package com.pch.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
/**
* Created by Administrator on 2016/12/4.
*/
@RestController
public class UserController {
@RequestMapping("/user")
public Principal user(Principal user) {
return user;
}
}
package com.pch.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
/**
* Created by Administrator on 2016/12/4.
*/
@Configuration
@EnableResourceServer
public class CustomResouceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.tokenStore(tokenStore)
// .resourceId("resourceId")
;
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/home")
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/user")
.access("#oauth2.hasScope('read')")
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
;
}
}
package com.pch.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
/**
* Created by Administrator on 2016/12/4.
*/
@Configuration
@EnableResourceServer
public class CustomResouceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.tokenStore(tokenStore)
// .resourceId("resourceId")
;
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/home")
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/user")
.access("#oauth2.hasScope('read')")
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
;
}
}
这里不示例“authorization_code”方式认证
假设可使用“CURL”命令,使用password方式认证命令:
curl -X POST client_id:@localhost:9999/oauth/token -d "grant_type=password" -d "client_id=client_id" -d "username=user" -d "password=123123"
将返回示例json:
{"access_token":"ea3595d6-e4c5-41d7-a6c8-f2e618f751a4","token_type":"bearer","refresh_token":"7792fdc7-53af-4bf5-8741-16ba9477db44","expires_in":2839,"scope":"read write"}
curl localhost:9999/home -H "Authorization: ${token_type} ${access_token}"