Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringCloud微服务实战系列(十九)Ouath2在真实场景中的应用之客户端接入(第一种写法)

SpringCloud微服务实战系列(十九)Ouath2在真实场景中的应用之客户端接入(第一种写法)

作者头像
品茗IT
发布于 2020-05-28 08:30:07
发布于 2020-05-28 08:30:07
1.2K00
代码可运行
举报
文章被收录于专栏:品茗IT品茗IT
运行总次数:0
代码可运行

SpringCloud微服务实战系列(十九)Ouath2在真实场景中的应用之客户端接入(第一种写法)

一、概述

《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中

已经介绍了资源服务器是如何搭建的。

《SpringCloud微服务实战系列(十八)Ouath2在真实场景中的应用之授权服务器》]中

已经介绍了授权服务器是如何搭建的。

本篇就是对Oauth2的实际应用方法的客户端接入方式的其中一种方法进行介绍。这种方法跟另外一种的区别是:

  1. 可以配置用户信息查询地址并自动查询补入。
  2. Nginx转发未携带请求host则会出错

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

在Spring Oauth2中,Oauth2的使用过程中将角色分为三种:ResourceServer,AuthorizationServer,OauthClient.

由于篇幅较大,这里将Oauth2的搭建分成三个部分。本篇介绍OauthClient的其中一种写法。

这种方式是基于spring-security-oauth2-client的自动化配置。在Springboot官方文档可以找到这种配置方法。https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-security.html#boot-features-security-oauth2

代码可以在https://www.pomit.cn/java/spring/springcloud.html中的Oauth2相关中的组件下载即可。

二、客户端接入

客户端接入是一个复杂的过程,按照Springboot官方文档的指引,我这里把完整的流程写出来。

下面讲述下这个过程是怎样的。

2.1 引入依赖

需要引入spring-boot-starter-web、spring-cloud-starter-security和spring-security-oauth2-client相关jar包.

依赖如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-security</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-oauth2-client</artifactId>
	</dependency>
</dependencies>
2.2 配置文件

这里使用yaml文件写配置,配置文件application.yml:

application.yml:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server:
   port: 8181
spring:
   profiles:
      active: loc
   application:
      name: oauthClient
logging:
   level:
      root: info

这里

  1. 应用名称为oauthClient
  2. 指定配置为loc。

application-loc.yml:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
env: loc

spring:
   security:
      oauth2:
         client:
            registration:
               oauthClient:
                  clientId: MwonYjDKBuPtLLlK
                  clientSecret: 123456
                  clientName: oauthClient
                  provider: oauthAuth
                  authorizationGrantType: authorization_code
                  redirectUriTemplate: http://tw.pomit.cn/custom-callback
            provider:
               oauthAuth:
                  tokenUri: http://sso.pomit.cn/oauth/token
                  authorizationUri: http://sso.pomit.cn/oauth/authorize
                  userInfoUri: http://res.pomit.cn/api/userInfo
                  userNameAttribute: data

这里配置的东西可能会让你产生疑惑,下面一一讲述:

  1. spring.security.oauth2.client.registration.oauthClient是客户端的配置,其中最后的后缀oauthClient是你的应用名,千万别照搬了。clientId和clientSecret是客户端的密钥,需要在授权服务器加上这个客户端,provider指的是授权服务器,authorizationGrantType是授权类型,redirectUriTemplate是回调地址,授权服务器授权成功要有回调地址的。
  2. spring.security.oauth2.client.provider.oauthAuth是关于授权服务器的配置,其中最后的后缀oauthAuth是你的授权服务器应用名,千万别照搬了。tokenUri是token获取地址,后缀基本上都是/oauth/token;authorizationUri是授权地址,后缀基本上都是/oauth/authorize;userInfoUri是获取用户信息接口,这个要配置资源服务器的地址,是自己定义的,userNameAttribute是参数字段名。

基本配置就是这样了,如果中间出现问题,要多试几次查找问题。

2.3 启动

使用main直接启动即可。无需其他配置。

OauthClientApplication:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

}
2.4 安全控制配置

这个安全控制,只是普通的Spring Security的安全配置,外加一行oauth2的配置。

需要继承WebSecurityConfigurerAdapter,并加上@EnableWebSecurity。

AccessSecurityConfiguration如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class AccessSecurityConfiguration extends WebSecurityConfigurerAdapter {
	@Override
	public void configure(HttpSecurity http) throws Exception {
		http
        .authorizeRequests()
            .mvcMatchers("/test/**").permitAll()
            .antMatchers("/").permitAll()
			.antMatchers("/index.html").permitAll()
			.antMatchers("/css/**").permitAll()
			.antMatchers("/js/**").permitAll()
			.antMatchers("/img/**").permitAll()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated().and()
            .oauth2Login().redirectionEndpoint()
			.baseUri("/custom-callback");
	}
}

其中, .oauth2Login().redirectionEndpoint().baseUri("/custom-callback");是表明了oauth2的授权回调地址。

2.5 测试web

这里写了三个web接口,来测试不用的访问控制级别的返回信息。

OauthTestRest:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.pomit.springbootwork.oauthclient.model.ResultModel;

@Controller
@RequestMapping("/")
public class OauthTestRest {

	@ResponseBody
	@RequestMapping(value = "/test/test", method = { RequestMethod.GET })
	public ResultModel test() {
		
		return ResultModel.ok("我就是test,客户端");
	}
	
	@RequestMapping(value = "/", method = { RequestMethod.GET })
	public String index() {
		
		return "/index.html";
	}
	
	@RequestMapping(value = "/logTo", method = { RequestMethod.GET })
	public String logTo() {
		
		return "/index.html";
	}

}

OauthClientRest:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient.web;

import java.security.Principal;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import cn.pomit.springbootwork.oauthclient.model.IpModel;
import cn.pomit.springbootwork.oauthclient.model.ResultModel;
import cn.pomit.springbootwork.oauthclient.util.IPUtil;

@RestController
@RequestMapping("/api")
public class OauthClientRest {

	@RequestMapping(value = "/ip", method = { RequestMethod.GET })
	public ResultModel ip(HttpServletRequest request) {
		IpModel ipModel = new IpModel();
		ipModel.setClientIpAddress(IPUtil.getIpAddr(request));
		ipModel.setServerIpAddress(IPUtil.localIp());
		return ResultModel.ok(ipModel);
	}
	
	@RequestMapping(value = "/test")
	public ResultModel test(Principal principal) {

		return ResultModel.ok(principal.getName());
	}
	
	@RequestMapping(value = "/userInfo")
	public ResultModel userinfo(Principal principal) {

		return ResultModel.ok(principal.getName());
	}
}

OauthAdminRest:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient.web;

import java.security.Principal;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import cn.pomit.springbootwork.oauthclient.model.IpModel;
import cn.pomit.springbootwork.oauthclient.model.ResultModel;
import cn.pomit.springbootwork.oauthclient.util.IPUtil;

@RestController
@RequestMapping("/admin")
public class OauthAdminRest {

	@RequestMapping(value = "/ip", method = { RequestMethod.GET })
	public ResultModel ip(HttpServletRequest request) {
		IpModel ipModel = new IpModel();
		ipModel.setClientIpAddress(IPUtil.getIpAddr(request));
		ipModel.setServerIpAddress(IPUtil.localIp());
		return ResultModel.ok(ipModel);
	}
	
	@RequestMapping(value = "/test")
	public ResultModel test(Principal principal) {

		return ResultModel.ok(principal.getName());
	}
	
	@RequestMapping(value = "/userInfo")
	public ResultModel userinfo(Principal principal) {

		return ResultModel.ok(principal.getName());
	}
}
2.6 过程中用到的其他实体和工具

IpModel :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient.model;

public class IpModel {
	private String clientIpAddress;
	private String serverIpAddress;

	public String getClientIpAddress() {
		return clientIpAddress;
	}

	public void setClientIpAddress(String clientIpAddress) {
		this.clientIpAddress = clientIpAddress;
	}

	public String getServerIpAddress() {
		return serverIpAddress;
	}

	public void setServerIpAddress(String serverIpAddress) {
		this.serverIpAddress = serverIpAddress;
	}

}

IPUtil:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient.util;

import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.servlet.http.HttpServletRequest;

public class IPUtil {
	/**
	 * @Description: 获取客户端IP地址
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
			if (ip.equals("127.0.0.1")) {
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (Exception e) {
					e.printStackTrace();
				}
				ip = inet.getHostAddress();
			}
		}
		// 多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
		if (ip != null && ip.length() > 15) {
			if (ip.indexOf(",") > 0) {
				ip = ip.substring(0, ip.indexOf(","));
			}
		}
		return ip;
	}

	/**
	 * 获取的是本地的IP地址
	 * 
	 * @return
	 */
	public static String localIp() {
		String result = "";
		try {
			InetAddress address = InetAddress.getLocalHost();
			result = address.getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return result;
	}
}

ResultModel:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.pomit.springbootwork.oauthclient.model;

/**
 * @author cff
 */
public class ResultModel {
	private String errorCode;
    private String message;
    private Object data;

    public ResultModel() {

    }

    public ResultModel(String errorCode, String message) {
        this.errorCode = errorCode;
        this.message = message;
    }

    public ResultModel(String errorCode, String message, Object data) {
        this.errorCode = errorCode;
        this.message = message;
        this.data = data;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void set	ErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public static ResultModel ok(String testValue) {
        ResultModel rm = new ResultModel();
        rm.setData(testValue);
        return rm;
    }
}

三、测试过程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
资源服务器:http://res.pomit.cn
授权服务器:http://sso.pomit.cn

客户端:
服务器1:http://tw.pomit.cn
  1. 未授权时:

在这里插入图片描述

  1. 点击授权登录:

在这里插入图片描述

  1. 如果已经授权过,则不会出现授权页面。否则出现授权登录页面:

在这里插入图片描述

  1. 授权成功后,再点获取信息:

在这里插入图片描述

四、微信OAUTH2授权过程

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

品茗IT-博客专题:https://www.pomit.cn/lecture.html汇总了Spring专题Springboot专题SpringCloud专题web基础配置专题。

快速构建项目

Spring项目快速开发工具:

一键快速构建Spring项目工具

一键快速构建SpringBoot项目工具

一键快速构建SpringCloud项目工具

一站式Springboot项目生成

Mysql一键生成Mybatis注解Mapper

Spring组件化构建

SpringBoot组件化构建

SpringCloud服务化构建

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/05/12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringCloud技术指南系列(四)服务注册发现之Consul服务注册
目前服务发现的解决方案有Eureka,Consul,Zookeeper等,这三个是SpringCloud官方支持的。
品茗IT
2019/09/12
1K0
SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器
在《SpringBoot入门建站全系列(三十五)整合Oauth2做单机版认证授权》和《Spring整合Oauth2单机版认证授权详情》中
品茗IT
2020/05/28
8170
SpringCloud微服务实战系列(十八)Ouath2在真实场景中的应用之授权服务器
在《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中
品茗IT
2020/05/28
1.5K0
SpringCloud微服务实战系列(二十)Ouath2在真实场景中的应用之客户端接入(第二种写法)
在《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中
品茗IT
2020/05/28
9740
SpringCloud微服务实战系列(十四)分布式锁之Zookeeper实现
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。
品茗IT
2020/05/28
8260
SpringCloud技术指南系列(六)服务注册发现之Zookeeper服务注册
目前服务发现的解决方案有Eureka,Consul,Zookeeper等,这三个是SpringCloud官方支持的。
品茗IT
2019/09/12
1.6K0
SpringCloud微服务实战系列(十三)分布式锁之Redis实现(redisson)
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。
品茗IT
2020/05/28
2.4K0
SpringCloud技术指南系列(十)配置管理之自建配置中心
详细可以查看《SpringBoot入门建站全系列(二十三)配置文件优先级及常用配置方式》.
品茗IT
2019/09/12
9680
SpringCloud技术指南系列(七)服务注册发现之Zookeeper服务调用
目前服务发现的解决方案有Eureka,Consul,Zookeeper等,这三个是SpringCloud官方支持的。
品茗IT
2019/09/12
8820
SpringCloud技术指南系列(三)服务注册发现之Eureka服务调用
目前服务发现的解决方案有Eureka,Consul,Zookeeper等,这三个是SpringCloud官方支持的。
品茗IT
2019/09/12
3710
SpringCloud微服务实战系列(十五)分布式链路跟踪Sleuth与Zipkin实现
分布式链路追踪,是一种用于分析和监控应用程序的方法,尤其是那些使用微服务架构的那些应用。分布式链路跟踪有助于查找故障发生位置和导致性能低下的原因。
品茗IT
2020/05/28
4640
SpringCloud技术指南系列(十一)API网关之Zuul使用
API网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的Facade模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤。它除了要实现请求路由、 负载均衡、 校验过滤等功能之外,还需要更多能力,比如与服务治理框架的结合、请求转发时的熔断机制、服务的聚合等一系列高级功能。
品茗IT
2019/09/12
5170
SpringBoot入门建站全系列(三十六)AspectJ做AOP日志管理
Spring的两大特性,AOP和IOC,AOP面向切面编程,可以对当前代码无侵入的情况下,使用AspectJ对切点数据进行分析存储。常常被用来做日志/流水的存储记录。
品茗IT
2020/09/03
1.7K0
SpringCloud技术指南系列(十二)API网关之Gateway使用
API网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的Facade模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤。它除了要实现请求路由、 负载均衡、 校验过滤等功能之外,还需要更多能力,比如与服务治理框架的结合、请求转发时的熔断机制、服务的聚合等一系列高级功能。
品茗IT
2019/09/12
1K0
SpringCloud技术指南系列(五)服务注册发现之Consul服务调用
目前服务发现的解决方案有Eureka,Consul,Zookeeper等,这三个是SpringCloud官方支持的。
品茗IT
2019/09/12
7660
SpringCloud技术指南系列(五)服务注册发现之Consul服务调用
基于Spring Cloud Oauth2 JWT搭建微服务的安全认证中心
Oauth协议为用户资源的授权提供了一个安全的、开放而又建议的标准。oauth的授权不会是第三方初级到用户的账号信息(如用户名与密码),及第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此oauth是安全的。oauth是Open Authorization的简写
小东啊
2019/06/26
15.7K1
基于Spring Cloud Oauth2 JWT搭建微服务的安全认证中心
SpringBoot入门建站全系列(三十五)整合Oauth2做单机版认证授权
OAuth 2.0 规范定义了一个授权(delegation)协议,对于使用Web的应用程序和API在网络上传递授权决策非常有用。OAuth被用在各钟各样的应用程序中,包括提供用户认证的机制。
品茗IT
2020/05/28
1.5K0
SpringCloud技术指南系列(九)配置管理之Zookeeper配置中心
详细可以查看《SpringBoot入门建站全系列(二十三)配置文件优先级及常用配置方式》.
品茗IT
2019/09/12
1.6K0
spring Cloud微服务 security+oauth2认证授权中心自定义令牌增强,并实现登录和退出
在之前的博客我写了 SpringCloud整合spring security+ oauth2+Redis实现认证授权,本文对返回的token实现自定义增强令牌返回结果,以及对于oauth2存在Redis的数据进行解释。
共饮一杯无
2022/11/28
1.2K0
spring Cloud微服务 security+oauth2认证授权中心自定义令牌增强,并实现登录和退出
Spring整合Sharding-JDBC分库分表详情
最初线上系统的业务量不是很大,业务数据量并不大,比如说单库的数据量在百万级别以下(事实上千万级别以下都还能支撑),那么MySQL的单库即可完成任何增/删/改/查的业务操作。随着业务的发展,单个DB中保存的数据量(用户、订单、计费明细和权限规则等数据)呈现指数级增长,那么各种业务处理操作都会面临单DB的IO读写瓶颈带来的性能问题。
品茗IT
2019/09/12
2.4K0
推荐阅读
SpringCloud技术指南系列(四)服务注册发现之Consul服务注册
1K0
SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器
8170
SpringCloud微服务实战系列(十八)Ouath2在真实场景中的应用之授权服务器
1.5K0
SpringCloud微服务实战系列(二十)Ouath2在真实场景中的应用之客户端接入(第二种写法)
9740
SpringCloud微服务实战系列(十四)分布式锁之Zookeeper实现
8260
SpringCloud技术指南系列(六)服务注册发现之Zookeeper服务注册
1.6K0
SpringCloud微服务实战系列(十三)分布式锁之Redis实现(redisson)
2.4K0
SpringCloud技术指南系列(十)配置管理之自建配置中心
9680
SpringCloud技术指南系列(七)服务注册发现之Zookeeper服务调用
8820
SpringCloud技术指南系列(三)服务注册发现之Eureka服务调用
3710
SpringCloud微服务实战系列(十五)分布式链路跟踪Sleuth与Zipkin实现
4640
SpringCloud技术指南系列(十一)API网关之Zuul使用
5170
SpringBoot入门建站全系列(三十六)AspectJ做AOP日志管理
1.7K0
SpringCloud技术指南系列(十二)API网关之Gateway使用
1K0
SpringCloud技术指南系列(五)服务注册发现之Consul服务调用
7660
基于Spring Cloud Oauth2 JWT搭建微服务的安全认证中心
15.7K1
SpringBoot入门建站全系列(三十五)整合Oauth2做单机版认证授权
1.5K0
SpringCloud技术指南系列(九)配置管理之Zookeeper配置中心
1.6K0
spring Cloud微服务 security+oauth2认证授权中心自定义令牌增强,并实现登录和退出
1.2K0
Spring整合Sharding-JDBC分库分表详情
2.4K0
相关推荐
SpringCloud技术指南系列(四)服务注册发现之Consul服务注册
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验