【spring security oauth2】入门例子(helloworld ) 1- 基础版


相关文章:
【spring security oauth2】入门例子(helloworld ) 1- 基础版
【spring security oauth2】入门例子(helloworld ) 2 进阶版

OAuth2.0概述

OAuth2.0是一个关于授权的开放网络协议。

该协议在第三方应用与服务提供平台之间设置了一个授权层。第三方应用需要服务资源时,并不是直接使用用户帐号密码登录服务提供平台,而是通过服务提供平台的授权层获取token令牌,用户可以在授权时指定token的权限范围和有效期。第三方应用获取到token以后,才可以访问用户资源。

OAuth 2.0定义了四种授权方式:

  • 授权码模式(authorization code):功能最完整、流程最严密的授权模式。特点是通过第三方应用的后台服务器,与服务提供平台的认证服务器进行互动获取资源。
  • 简化模式(implicit):不通过第三方应用服务器,直接在浏览器中向认证服务器申请token令牌,跳过了授权码这个步骤。所有步骤在浏览器中完成,token对用户可见,且第三方应用不需要认证。
  • 密码模式(resource owner password credentials):用户向第三方应用提供自己的用户名和密码。第三方应用使用这些信息,向服务提供平台索要授权。在这种模式中,用户必须把自己的密码给第三方应用,但是第三方应用不得储存密码。这通常用在用户对第三方应用高度信任的情况下,比如第三方应用是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。
  • 客户端模式(client credentials):指第三方应用以自己的名义,而不是以用户的名义,向服务提供平台进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向第三方应用注册,第三方应用以自己的名义要求服务提供平台提供服务,其实不存在授权问题。

授权码模式

假设有X用户、A系统、B系统,X是A系统中的用户,B系统需要访问A系统获取X用户的信息。

  • B系统中放置向A系统申请授权的入口;
  • X用户点击进入A系统授权页,如果未登录需要登录;
  • X用户允许授权给B系统;
  • A系统重定向到B系统,并携带authorization_code授权码;
  • B系统使用authorization_code授权码到A系统获取token令牌;
  • B系统可以使用token令牌到A系统获取用户资源。

再举个授权码模式的例子:某网站QQ快速登录、账号绑定。

  • 用户点击网站的QQ登录图标
  • 页面跳转到QQ提供的授权页,如果PC上没有登录QQ账号,需要登录
  • 用户允许授权
  • 重定向到网站回调地址,携带授权码authorization_code
  • 网站使用授权码获取token
  • 使用token拉取QQ账号信息
  • 使用QQ账号信息登录、账号绑定等

Spring Security概述

Spring Security是一个用于快速实现Web应用安全、认证的框架,可以快速和Spring Boot整合。

开发者可以编写配置类继承WebSecurityConfigurerAdapter类,重写config方法自定义登录页面、登录失败逻辑、权限不足逻辑等,并且可以编写Filter实现更加复杂的图片验证码、短信验证码功能。

Spring Security也可以快速实现OAuth2.0授权服务器和资源服务器。在一个Spring Boot应用中,可以使用@EnableAuthorizationServer注解实现授权服务器,使用@EnableResourceServer注解实现资源服务器。

整体架构:
在这里插入图片描述

1. 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.13.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
    </dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2、Spring Boot启动类配置

加@EnableAuthorizationServer和@EnableResourceServer注解。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@EnableAuthorizationServer
@EnableResourceServer
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

3、application.properties配置

配置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

4、受保护资源

编写controller

默认是对所有的资源进行保护,后面可以通过配置进行精细化管理。

package com.example.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/")
public class TestController {

    Logger log = LoggerFactory.getLogger(TestController.class);

    @RequestMapping(value = "order/demo")
    public String getDemo() {
        Authentication auth = SecurityContextHolder.getContext()
                .getAuthentication();
        log.info(auth.toString());
        return "Hello world";
    }
}

5、测试授权码模式

1)获取authorization_code授权码

使用浏览器访问,模拟百度网站点击微信登陆,弹出一个微信的访问界面:
http://localhost:7000/oauth/authorize?response_type=code&client_id=net5ijy&redirect_uri=http://www.baidu.com&scope=all

上面的链接分为地址和参数2个部分:

  • 地址 http://localhost:7000/oauth/authorize

  • 参数

    参数名含义
    response_type'code’表示授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
    client_id根据实际的client-id填写,此处写net5ijy
    redirect_uri生成code后的回调地址,http://www.baidu.com
    scope权限范围 ,限定token可以用于读操作、写操作等

在这里插入图片描述

此时,会提示输入用户名和密码,登录,使用的用户名、密码就是在application.properties中配置的admin和123456:

这个步骤指代用户输入微信的用户名和密码

security.user.name=admin
security.user.password=123456

在这里插入图片描述
用户允许把微信信息授权给百度:
在这里插入图片描述
看到浏览器重定向到了http://www.baidu.com并携带了code参数,这个code就是授权服务器生成的授权码,值为rspzkJ:
在这里插入图片描述

2)获取token令牌

使用curl命令获取token令牌,注意必须是post请求:

如果是windows,需要先安装支持curl的软件,可以curl 7.79.1 for Windows

D:\software\curl-7.79.1-win64-mingw\bin>curl --user net5ijy:123456 -X POST -d "grant_type=authorization_code&scope=all&redirect_uri=http%3A%2F%2Fwww.baidu.com&c
ode=rspzkJ" http://localhost:7000/oauth/token
{"access_token":"2ebed558-3b68-42db-a088-c0f0b9b9cf19","token_type":"bearer","refresh_token":"c460f05c-5477-4869-af86-d0e4e216ccdd","expires_in":43199,"scope":"
all"}

curl命令里的 --user net5ijy:123456 作用是什么?原因是这个请求是百度后台向微信访问的,那么百度自然需要提供用户名和密码,由于是后台请求,不像浏览器那样需要在页面弹出框输入用户名和密码,而是直接在请求中携带用户名和密码,这样微信直接据此进行验证。这个用户名对应clientId,而密码对应client_sercret,是百度提前在微信注册的。

参数含义
grant_type授权码模式,写authorization_code
scope权限范围
redirect_uri回调地址,http://www.baidu.com需要urlencode
code就是上一步生成的授权码

返回值,格式化后:

{
	"access_token": "2ebed558-3b68-42db-a088-c0f0b9b9cf19",
	"token_type": "bearer",
	"refresh_token": "c460f05c-5477-4869-af86-d0e4e216ccdd",
	"expires_in": 43199,
	"scope": "	all "
}

这样就获取到了token令牌,该token的访问权限范围是all权限,在12小时后失效。

3)使用token访问资源
http://localhost:7000/order/demo?access_token=2ebed558-3b68-42db-a088-c0f0b9b9cf19

在这里插入图片描述
在资源url后面加上access_token参数。

6、测试密码模式

1)获取token令牌

使用curl命令获取token令牌

curl --user net5ijy:123456 -X POST -d “grant_type=password&username=admin&password=123456&scope=all” http://localhost:7000/oauth/token

与授权码方式对比,这里直接去oauth/token获取token,省略了先获得code的模式

上面也分为url地址和参数2个部分:

  • 地址 http://localhost:7000/oauth/token

  • 参数

    参数含义
    grant_type密码模式,写password
    scope权限范围
    username申请授权用户的用户名 ,指微信的用户名
    password申请授权用户的密码 ,指微信的密码
D:\software\curl-7.79.1-win64-mingw\bin>curl --user net5ijy:123456 -X POST -d "grant_type=password&username=admin&password=123456&scope=all" http://localhost:70
00/oauth/token
{"access_token":"2ebed558-3b68-42db-a088-c0f0b9b9cf19","token_type":"bearer","refresh_token":"c460f05c-5477-4869-af86-d0e4e216ccdd","expires_in":40328,"scope":"
all"}

格式化返回值:

{
	"access_token": "2ebed558-3b68-42db-a088-c0f0b9b9cf19",
	"token_type": "bearer",
	"refresh_token": "c460f05c-5477-4869-af86-d0e4e216ccdd",
	"expires_in": 40328,
	"scope": "	all "
}

这样就获取到了token令牌,该token的访问权限范围是all权限,在12小时后失效。

2)使用token访问资源

http://localhost:7000/order/demo?access_token=2ebed558-3b68-42db-a088-c0f0b9b9cf19
在这里插入图片描述

参考

Spring Security实现OAuth2.0授权服务 - 基础版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值