使用Springboot搭建OAuth2.0 Server的方法示例

作者:iigadmin 时间:2023-01-28 07:19:16 

OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。

本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为RFC 6749。

OAuth 简介

OAuth 是由 Blaine Cook、Chris Messina、Larry Halff 及 David Recordon 共同发起的,目的在于为 API 访问授权提供一个安全、开放的标准。

基于 OAuth 认证授权具有以下特点:

  • 安全。OAuth 与别的授权方式不同之处在于:OAuth 的授权不会使消费方(Consumer)触及到用户的帐号信息(如用户名与密码),也是是说,消费方无需使用用户的用户名与密码就可以申请获得该用户资源的授权。

  • 开放。任何消费方都可以使用 OAuth 认证服务,任何服务提供方 (Service Provider) 都可以实现自身的 OAuth 认证服务。

  • 简单。不管是消费方还是服务提供方,都很容易于理解与使用。

OAuth 的解决方案如下图所示。

图 1. OAuth Solution

使用Springboot搭建OAuth2.0 Server的方法示例

如 图 1 所示 OAuth 解决方案中用户、消费方及其服务提供方之间的三角关系:当用户需要 Consumer 为其提供某种服务时,该服务涉及到需要从服务提供方那里获取该用户的保护资源。OAuth 保证:只有在用户显式授权的情况下(步骤 4),消费方才可以获取该用户的资源,并用来服务于该用户。

从宏观层次来看,OAuth 按以下方式工作:

  • 消费方与不同的服务提供方建立了关系。

  • 消费方共享一个密码短语或者是公钥给服务提供方,服务提供方使用该公钥来确认消费方的身份。

  • 消费方根据服务提供方将用户重定向到登录页面。

  • 该用户登录后告诉服务提供方该消费方访问他的保护资源是没问题的。 前提

阅读本文之前,你需要了解:

  • Spring Boot

  • Spring MVC

  • Spring Security

  • Google 浏览器插件Postman

pom.xml文件如下


<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>cn.iigrowing.study.oauth2</groupId>
<artifactId>demo01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>my.oauth01</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>

本项目需要添加的依赖非常简单,一共只有两个,一个是Spring Web,另一个是Spring OAuth2。

接下来是本文的核心,一共三个配置类。

SecurityConfig


package cn.iigrowing.study.oauth2.demo01;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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 SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("123456").authorities("ROLE_USER");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and().csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout().permitAll();
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

}

此处主要做了两件事情:

配置系统用户,这里使用内存存储,添加了用户名为 user ,角色为 USER 的用户


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 auth.inMemoryAuthentication()
   .withUser("user").password("123456").authorities("ROLE_USER");
}

配置了默认表单登陆以及禁用了 csrf 功能,并开启了 httpBasic 认证


@Override
 protected void configure(HttpSecurity http) throws Exception {
   http.httpBasic()
     .and().csrf().disable()
     .authorizeRequests()
     .antMatchers("/login").permitAll()
     .anyRequest().authenticated()
     .and()
     .formLogin()
     .and()
     .logout().permitAll();
 }

AuthorizationServerConfig


package cn.iigrowing.study.oauth2.demo01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client").secret("123456").scopes("read")
.authorizedGrantTypes("authorization_code")
.redirectUris("https://www.getpostman.com/oauth2/callback");
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}

}

这个类是OAuth2认证的核心配置类,在这个类中,配置了OAuth Client的信息,这里有几个地方需要注意:

  • @EnableAuthorizationServer 这个注解告诉 Spring 这个应用是 OAuth2 的授权服务器

  • 必须配置 authorizedGrantTypes

,它代表了OAuth Client允许认证的类型,其值主要有:

  • authorization_code

  • password

  • client_credentials

  • implicit refresh_token

这个配置项接受的类型是个数组,允许配置多个;关于这几种类型的区别,请查看这里不再赘述

redirectUris 关于这个配置项,是在 OAuth2协议中,认证成功后的回调地址,因为稍后我们会使用 Postman 作为测试工具,故此处值固定为 https://www.getpostman.com/oauth2/callback ,此值同样可以配置多个 ResourceServerConfig


package cn.iigrowing.study.oauth2.demo01;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
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;
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(“users-info”);

}

@Override
public void configure(HttpSecurity http) throws Exception {

http

.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

.and()

.requestMatchers()

.antMatchers(“/users/**”)

.and().authorizeRequests()

.antMatchers(“/users/**”)

.authenticated();

}
}

这个类表明了此应用是OAuth2 的资源服务器,此处主要指定了受资源服务器保护的资源链接,我们将提供以下的资源:


@RestController
@RequestMapping("users")
public class UserController {

@GetMapping("me")
 public Principal me(Principal principal) {
   return principal;
 }
}

注:

资源服务器可以和授权服务器是同一个,也可以分开部署

最后,我们还需添加 application.yml , 配置资源服务器的filter的顺序


server:
port: 8043
context-path: /uaa
logging:
level:
 org.springframework.security: DEBUG
spring:
application:
 name: oauth-server
security:
oauth2:
 resource:
  serviceId: ${PREFIX:}resource
  # refer to: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.5-Release-Notes#oauth-2-resource-filter
  filter-order: 3

此处的 filter-order 非常重要,因为自Spring Boot 1.5.* 之后,resource server 的 filter 的顺序默认在 basic authentication filter chain 之后,所以如果不配置此项,将会导致使用 access_token 访问 resource server 的时候返回 401 状态码。

来源:http://www.iigrowing.cn/shi_yong_springboot_da_jian_oauth2_0_server.html

标签:Spring,boot,OAuth2.0,Server
0
投稿

猜你喜欢

  • C#根据前台传入实体名称实现动态查询数据

    2021-06-17 09:28:43
  • Java 实现Excel文档添加超链接的代码

    2021-09-05 20:06:52
  • Jackson的用法实例分析

    2021-11-13 09:13:40
  • Android开发gradle拉取依赖的加速配置

    2023-05-31 03:16:08
  • Android中AutoCompleteTextView自动提示

    2022-06-21 19:07:36
  • 使用Java编写一个简单的Web的监控系统

    2023-02-18 04:00:19
  • Android编程基础之简单Button事件响应综合提示控件Toast应用示例

    2023-06-30 16:27:34
  • Android基于HttpUrlConnection类的文件下载实例代码

    2022-08-28 02:18:49
  • 浅谈Visual C#进行图像处理(读取、保存以及对像素的访问)

    2023-04-04 20:25:00
  • MyBatis通用Mapper和PageHelper的过程详解

    2022-09-29 16:17:03
  • C# Winform下载文件并显示进度条的实现代码

    2022-11-26 04:39:02
  • C#反射之基础应用实例总结

    2023-08-29 04:50:56
  • datatable去掉重复行的方法

    2023-09-02 19:59:41
  • Java求字符串中出现次数最多的字符串以及出现次数

    2023-06-03 03:45:34
  • Android自定义DigitalClock控件实现商品倒计时

    2023-07-17 20:13:28
  • JAVA集合框架工具类自定义Collections集合方法

    2022-01-11 16:24:13
  • Android MessageQueue消息队列主要作用详解

    2021-11-11 15:25:39
  • java设计模式之简单工厂模式简述

    2021-06-14 17:11:20
  • Android四种数据存储的应用方式

    2023-07-25 05:01:06
  • Java main 方法面试题的详细整理

    2023-11-24 23:53:30
  • asp之家 软件编程 m.aspxhome.com