在《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中
已经介绍了资源服务器是如何搭建的。
在《SpringCloud微服务实战系列(十八)Ouath2在真实场景中的应用之授权服务器》]中
已经介绍了授权服务器是如何搭建的。
本篇就是对Oauth2的实际应用方法的客户端接入方式的其中一种方法进行介绍。这种方法跟另外一种的区别是:
首发地址:SpringCloud微服务实战系列(十九)Ouath2在真实场景中的应用之客户端接入(第一种写法)
如果大家正在寻找一个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官方文档的指引,我这里把完整的流程写出来。
下面讲述下这个过程是怎样的。
需要引入spring-boot-starter-web、spring-cloud-starter-security和spring-security-oauth2-client相关jar包.
依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-oauth2-clientartifactId>
dependency>
dependencies>
这里使用yaml文件写配置,配置文件application.yml:
application.yml:
server:
port: 8181
spring:
profiles:
active: loc
application:
name: oauthClient
logging:
level:
root: info
这里
application-loc.yml:
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
这里配置的东西可能会让你产生疑惑,下面一一讲述:
基本配置就是这样了,如果中间出现问题,要多试几次查找问题。
使用main直接启动即可。无需其他配置。
OauthClientApplication:
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);
}
}
这个安全控制,只是普通的Spring Security的安全配置,外加一行oauth2的配置。
需要继承WebSecurityConfigurerAdapter,并加上@EnableWebSecurity。
AccessSecurityConfiguration如下:
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的授权回调地址。
这里写了三个web接口,来测试不用的访问控制级别的返回信息。
OauthTestRest:
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:
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:
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());
}
}
IpModel :
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:
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:
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;
}
}
资源服务器:http://res.pomit.cn
授权服务器:http://sso.pomit.cn
客户端:
服务器1:http://tw.pomit.cn
3. 如果已经授权过,则不会出现授权页面。否则出现授权登录页面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W2eYMGGm-1589508361938)(https://www.pomit.cn/upload/picture/20200512/305271141179648.jpg)]
4. 授权成功后,再点获取信息:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WeYUuc6V-1589508361941)(https://www.pomit.cn/upload/picture/20200512/305271523160320.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yj4Jq3rM-1589508361943)(https://www.pomit.cn/upload/picture/20200512/305271710093568.jpg)]
品茗IT-博客专题:https://www.pomit.cn/lecture.html汇总了Spring专题、Springboot专题、SpringCloud专题、web基础配置专题。
Spring项目快速开发工具:
一键快速构建Spring项目工具
一键快速构建SpringBoot项目工具
一键快速构建SpringCloud项目工具
一站式Springboot项目生成
Mysql一键生成Mybatis注解Mapper
Spring组件化构建
SpringBoot组件化构建
SpringCloud服务化构建
喜欢这篇文章么,喜欢就加入我们一起讨论SpringCloud使用吧!
d项目工具](https://www.pomit.cn/java/spring/springcloud.html)
一站式Springboot项目生成
Mysql一键生成Mybatis注解Mapper
Spring组件化构建
SpringBoot组件化构建
SpringCloud服务化构建
喜欢这篇文章么,喜欢就加入我们一起讨论SpringCloud使用吧!
[外链图片转存中…(img-mK5hXAff-1589508361944)]