spring-boot & spring-security-oauth2

(此处省略2000字废话),第一次写博客,直接进入正题了。

从初学者的角度来看,初次使用spring-boot和spring-security-oauth2整合,第一步自然是搭建一个“Hello World”先跑起来。那么二话不说,先来一个spring-boot的“Hello World”。

本小菜使用idea+maven搭建项目,假设已经有了一个基本的maven-archetype-web架构,如图:

 

关于架构的目录结构,每个人都有自己的看法,小菜的设计思路是client发送请求,按照“web”-“service”-“dao”的顺序与数据库交互,生成“po”。框架的配置放在“config”中,一些dao层或者其他层的封装放在“common”中,String、Excel等工具类放在util中,“api”是提供给外部访问的接口层,可以调用“service”,也可以调用“web”。

一、搭建一个spring-boot的web项目。

1、添加jar包:

<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开发就是靠他们了。

2、spring-boot启动类

主要是配置@SpringBootApplication,大概意思就是告诉spring-boot程序入口在这里。
3、"web"访问层Controller类

4、启动spring-boot

可以直接从App.class的main方法run或者debug启动,也可以使用mvn spring-boot:run命令启动

输入http://localhost:8080/home,测试结果:

 二、spring-security-oauth2基本使用

经过上面的步骤,相信和本菜一样的小菜鸟多少熟悉了idea&maven的使用。接下来是使用spring-security-oauth2保护接口的安全。

1、导入依赖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

 2、配置授权服务的类型

授权类型主要有

authorization_code:授权码类型

implicit:隐式授权类型

password:资源所有者(即用户)密码类型

client_credentials:客户端凭据(客户端ID以及Key)类型

refresh_token:通过以上授权获得的刷新令牌来获取新的令牌

这里不考虑第2、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}"





 

posted @ 2016-12-03 22:25  百思送葬队  阅读(16206)  评论(0编辑  收藏  举报