OAuth2 Authorization Server
基于Spring Security 5 的 Authorization Server的写法
先看演示

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 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>2.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cjs.example.oauth2</groupId>
<artifactId>cjs-authorization-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cjs-authorization-server</name>
<properties>
<java.version>1.8</java.version>
<docker.image.prefix>cjssso</docker.image.prefix>
</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</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>0.2.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!-- https://www.webjars.org/documentation#springboot -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
<version>0.50</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.1.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<!-- https://github.com/spotify/docker-maven-plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 9000
# servlet:
# context-path: /uaa
logging:
level:
root: debug
Security配置
package com.cjs.example.oauth2.config;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.UUID;
/**
* @Author ChengJianSheng
* @Date 2022/3/29
*/
@Configuration
public class OAuth2AuthorizationServerSecurityConfiguration {
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
return http.formLogin(Customizer.withDefaults()).build();
}
@Bean
@Order(2)
public SecurityFilterChain standardSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> authorize
.antMatchers("/webjars/**", "/login", "/login-error").permitAll()
.anyRequest().authenticated())
.formLogin().loginPage("/login").failureUrl("/login-error");
return http.build();
}
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient client1 = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("client-1")
.clientSecret("$2a$10$zNvOs9Ex0cD794OyWwDIXutF7F4hHYjLuEwI.U30p3nNIyumfON42")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUri("http://127.0.0.1:8081/message/login/oauth2/code/mycustom")
.redirectUri("http://127.0.0.1:8081/message/authorized")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(false).build())
.build();
RegisteredClient client2 = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("client-2")
.clientSecret("$2a$10$csxC.p5gNQbnpv8Mt5dqPevS66QL2USHERtQ8hEA1TWETIk1Zo3SS")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("http://www.baidu.com")
.scope("message:read")
.build();
return new InMemoryRegisteredClientRepository(client1, client2);
}
@Bean
public JWKSource jwkSource(KeyPair keyPair) {
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
@Bean
public JwtDecoder jwtDecoder(KeyPair keyPair) {
return NimbusJwtDecoder.withPublicKey((RSAPublicKey) keyPair.getPublic()).build();
}
@Bean
public ProviderSettings providerSettings() {
return ProviderSettings.builder().issuer("http://localhost:9000").build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withUsername("zhangsan")
.password("$2a$10$5nlwTDZ9LNbz7UMKcseY3u6YqbkGrMe2tQirfrwrCJAKrDAM78bUa")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("123456"));
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
}
自定义登录页面
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Spring Security OAuth 2.0 Sample</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.css" th:href="@{/webjars/bootstrap/css/bootstrap.css}" />
</head>
<body>
<div class="container">
<h1>Login</h1>
<p th:if="${loginError}" style="font-weight:bold;color:red;">Wrong username or password</p>
<form th:action="@{/login}" method="post">
<div class="form-row">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" name="username" placeholder="请输入用户名" autofocus="autofocus" class="form-control">
<small class="form-text text-muted">user1 / password</small>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" placeholder="请输入密码" class="form-control">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="verificationCode">验证码</label>
<input type="text" id="verificationCode" name="verificationCode" placeholder="请输入验证码" class="form-control">
</div>
</div>
<button type="submit" class="btn btn-primary">登录</button>
</form>
</div>
<script src="/webjars/jquery/jquery.min.js" th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js" th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</body>
</html>
默认的Controller
package com.cjs.example.oauth2.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @Author ChengJianSheng
* @Date 2022/4/2
*/
@Controller
public class DefaultController {
@GetMapping("/")
public String root() {
return "redirect:/index";
}
@GetMapping("/index")
public String index() {
return "index";
}
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/login-error")
public String loginError(Model model) {
model.addAttribute("loginError", true);
return login();
}
}
获取token
GET http://localhost:9000/oauth2/authorize?response_type=code&client_id=client-2&redirect_uri=http://www.baidu.com
POST /oauth2/token HTTP/1.1
Host: localhost:9000
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=xxx&redirect_uri=http://www.baidu.com

抓包


项目结构

参考
https://github.com/jgrandja/spring-security-oauth-5-2-migrate/tree/main/client-app
OAuth2 Authorization Server的更多相关文章
- Spring Cloud(6.1):搭建OAuth2 Authorization Server
配置web.xml 添加spring-cloud-starter-security和spring-security-oauth2-autoconfigure两个依赖. </dependency& ...
- 使用Identity Server 4建立Authorization Server (6) - js(angular5) 客户端
预备知识: http://www.cnblogs.com/cgzl/p/7746496.html 第一部分: http://www.cnblogs.com/cgzl/p/7780559.html 第二 ...
- 使用Identity Server 4建立Authorization Server (4)
预备知识: http://www.cnblogs.com/cgzl/p/7746496.html 第一部分: http://www.cnblogs.com/cgzl/p/7780559.html 第二 ...
- 每周开源项目分享-年轻人的第一个OAuth2.0 Server:hydra
年轻人的第一个OAuth2.0 Server:hydra hydra 是什么呢? OpenID Connect certified OAuth2 Server - cloud native, secu ...
- Spring Cloud(6.3):搭建OAuth2 Resource Server
配置web.xml 添加spring-cloud-starter-security,spring-security-oauth2-autoconfigure2个依赖. <!-- Spring c ...
- Spring Authorization Server 全新授权服务器整合使用
前言 Spring Authorization Server 是 Spring 团队最新开发适配 OAuth 协议的授权服务器项目,旨在替代原有的 Spring Security OAuth 经过半年 ...
- Spring Authorization Server的使用
Spring Authorization Server的使用 一.背景 二.前置知识 三.需求 四.核心代码编写 1.引入授权服务器依赖 2.创建授权服务器用户 3.创建授权服务器和客户端 五.测试 ...
- Spring Authorization Server 0.2.3发布,放出联合身份DEMO
很快啊Spring Authorization Server又发新版本了,现在的版本是0.2.3.本次都有什么改动呢?我们来了解一下. 0.2.3版本特性 本次更新的新特性不少. 为公开客户端提供默认 ...
- Spring Authorization Server授权服务器入门
11月8日Spring官方已经强烈建议使用Spring Authorization Server替换已经过时的Spring Security OAuth2.0,距离Spring Security OA ...
- Spring Authorization Server 实现授权中心
Spring Authorization Server 实现授权中心 源码地址 当前,Spring Security 对 OAuth 2.0 框架提供了全面的支持.Spring Authorizati ...
随机推荐
- 使用Amber计算单点能三步走
技术背景 Amber是一个在分子动力学中非常常用的一个软件,可以用于进行分子动力学模拟计算,可以与一些软件配合进行增强采样.这里我们简单介绍一下如何使用Amber去计算一个分子构象的单点势能值,及其对 ...
- javase项目 正常导入jar 包
1,在 java project 目录下新建 lib 文件夹 2,将 mysql 的 jar 包 复制到 新建的 lib 文件夹 3,选中 lib 下的 jar 包 , 右键点击选择 build pa ...
- 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.11.20)
百度网盘会员账号共享(11.20更新) 账号:zqv29268 密码:7003wayb 账号:rpz75364 密码:riyk1648 账号:0580quqn 密码:148hxhe 账号:132620 ...
- [转帖]shell编程之循环语句
目录 一.循环语句 for循环 for语句的结构 嵌套循环 while语句的结构 while语句应用示例 until语句的结构 until语句示例 二.跳出循环 continue跳出循环 break跳 ...
- [转帖]OpenSSL版本历史
OpenSSL版本历史 新闻日志 这是所有 OpenSSL 公告的简洁日志.它们几乎是发布通知. 日期物品 2021 年 7 月 29 日OpenSSL 3.0 的 Beta 2 现已推出.这是一个候 ...
- [转帖]通过拓扑 label 进行副本调度
https://docs.pingcap.com/zh/tidb/stable/schedule-replicas-by-topology-labels#%E5%9F%BA%E4%BA%8E%E6%8 ...
- [转帖]Kafka-Kraft 模式架构部署
news文章来源: Kafka-Kraft 模式架构部署 Kafka网址:https://kafka.apache.org/ PS:因环境原因此文档内端口都有修改! 1.去官网下载二进制包 PS:3. ...
- [转帖]Centos 7 查看磁盘io ,找出占用io读写很高的进程
1,先用iostat查看磁盘io 是否读写负载很高 用iostat -x 1 10 如果 iostat 没有,要 yum install sysstat安装这个包,第一眼看下图红色圈圈的那个如果%ut ...
- [转帖]Linux性能优化(十五)——CPU绑定
一.孤立CPU 1.孤立CPU简介 针对CPU密集型的任务,CPU负载较高,推荐设置CPU Affinity,以提高任务执行效率,避免CPU进行上下文切换,提高CPU Cache命中率. 默认情况下, ...
- 45从零开始用Rust编写nginx,静态文件服务器竟然还有这些细节
wmproxy wmproxy已用Rust实现http/https代理,socks5代理, websocket代理,反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透等,力争打 ...