在上一篇文章《OIDC 在 Authing 控制台配置 认证(二)》(以下简称《认证(二)》)中,我们讲述了如何在 Authing 平台配置项目集成中需要的 OIDC 的配置,以及在后期开发过程中如何获取配置。同时,也提前让大家预习和熟悉了一些项目搭建和编码过程中需要的知识点。
接下来这一小节,就让我们一起来顺利完成项目搭建和编码过程吧。
项目搭建
使用 Spring Initializr 快速构建项目
打开 IDEA,点击 New Project 创建一个新项目,选择 Spring Initializr 创建一个 Spring Boot 项目,输入项目的 Group 以及 Artifact 信息。
添加 Spring Web, Spring Security 依赖。
另外,集成过程中需要在 pom.xml 中添加一些其他的依赖包,如下:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<!--远程调用接口使用-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
</dependency>
使用 maven 工具构建项目
打开 IDEA,点击 New Project 创建一个新项目,选择 maven 创建一个 maven 项目,然后点击 Next,填写项目名称,最后 Finish 即可。
接下来在 pom.xml 中添加父工程依赖和集成过程中需要的其它依赖包。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<!--远程调用接口使用-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
</dependency>
说明:其中,hutool-all 工具包的作用是远程调用接口,当收到回调请求时,会使用该工具包远程调用 Authing 接口,即通过 code 换取 token 的流程,后续自动回调接口编码会使用到。
🎉🎉🎉至此,你已经完成了 使用 Spring Initializr 和 maven 两种方式构建项目,请选择一种适合自己项目开发的方式即可。
项目编码
测试项目
创建好项目后,在 IDEA 中运行项目,使用浏览器访问
http://localhost:8080
会自动跳转到 /login
路由,可以看到页面上出现了一个基础的登录表单,说明项目初始化成功。配置项目中的配置文件
找到
src/main/resources/application.properties
,将其重命名为 application.yml
,并添加如下内容:spring:
security:
oauth2:
client:
registration:
authing:
client-id: {替换为你的App ID如:App Secret5e72d72e3798fb03e1d57b13}
client-secret: {替换为你的App Secret如:931f19ce2161e5560c072f586c706ee6}
redirect-uri: {替换为登录的回调地址}
client-authentication-method: post
authorization-grant-type: authorization_code
scope:
- openid
- profile
provider:
authing:
issuer-uri: https://{替换为你的Issuer,如:authing-net-sdk-demo}.authing.cn/oidc
user-name-attribute: preferred_username
需要将这里的 {client_id}、{secret_secret}、{issuer-uri} 、{redirect-uri} 替换成 《认证(二)》 中应用配置中的实际信息。
自动回调接口编码
在项目下新建一个 package(package cn.authing.springsecurityoidc.controller),然后新建一个 CallBackController,此接口作用是通过 Authing OIDC 的 code 获取 token 的过程。 注意,下面的参数都是 OIDC 的标准,不能乱改,这也是标准协议的规定,参数名所对应的值也就是之前在 Authing 平台应用所配置的那些。
package cn.authing.springsecurityoidc.controller;
import cn.hutool.http.HttpUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class CallBackController {
@GetMapping("/callback")
public String getTokenByCode(String code){
//'https://<你的应用域名>.authing.cn/oidc/token
// --data-urlencode 'code=61yhuOVrgyhKlFTU~bnEKA_fnnz' \
// --data-urlencode 'client_id=5e37979f7b757ead14c534af' \
// --data-urlencode 'client_secret=64b517f8de3648091654eb4ee9b479d3' \
// --data-urlencode 'grant_type=authorization_code' \
// --data-urlencode 'redirect_uri=https://baidu.com'
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("code",code);
paramMap.put("client_id","61319680ea8b30c9ca9ca071");
paramMap.put("client_secret","cc8a53d7e22ce6b845330ced6cc5d9f2");
paramMap.put("grant_type","authorization_code");
paramMap.put("redirect_uri","http://localhost:8080/callback");
String result = HttpUtil.post("https://cjtjls-demo.authing.cn/oidc/token", paramMap);
return result;
}
}
添加配置文件类
在项目下新建一个 package(cn.authing.springsecurityoidc.config),然后新建一个SpringSecurityConfig,Spring Security 默认拦截所有的接口,此配置类是为了放行我们自己需要开放的接口。
package cn.authing.springsecurityoidc.config;
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;
import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity(debug = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().disable();
http.csrf().and().cors().disable();
http.authorizeRequests()
.mvcMatchers("callback","")
.permitAll()
.anyRequest().authenticated();
// 授权码模式回调
http.oauth2Login(withDefaults());
}
}
运行项目
一切准备就绪了,现在启动项目并访问
http://localhost:8080
,即可看到 Authing 登录窗口。Spring Security 默认会保护首页,在访问首页时会进行认证,未认证的访问请求会跳转到
/login
。 注册并登录后,会跳转回首页,此时可以看到页面上的欢迎语显示了当前登录用户的用户名。当登录成功后,会自动回调到我们之前自己编码的接口,即前面所概述的 Code 换取 Token 的过程。此时界面会拿到返回值,如下:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InhENWlTYVJiU0dZQzFmdWFTRVdQXy1hejBORW5qSmtoZG00bTJ3X3ZwMHcifQ.eyJqdGkiOiJnbHdLbmMzbzlXYlVLUE5pWUF1V00iLCJzdWIiOiI2MTRmZDlhZTQyYjE5MmZjMzI4MjNiMTAiLCJpYXQiOjE2MzU5MjQwNjgsImV4cCI6MTYzNzEzMzY2OCwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSIsImlzcyI6Imh0dHBzOi8vY2p0amxzLWRlbW8uYXV0aGluZy5jbi9vaWRjIiwiYXVkIjoiNjEzMTk2ODBlYThiMzBjOWNhOWNhMDcxIn0.KG6_SCaXfm082WAuPZu2-gR2cuA1Heg50EeVF1ldAO_fvb72pkmgs7EiWXjLJwYUj3CNejIS1GwcDy9gVWw8jfO-aRxUyRMplDY-axzgu5frCxYrg_K7LhlU1xvQJIMKTx7HY7rldbbAX0JzqJx-xHCJItUiggvHjvF9-B1twmMP7Ua-UQxQdgkFd1SmbN9LwqxCo8AzsbX6jcBNJ3Ughv0_jUxYp6QPAeIEkXmOYlwdJR-4Rdn9XxPya5yF4wxgwZ_oybjViESr7BDwEXEPVWTF6czGzctmfhCD7EEE4sLWaP6TSmXAHyCYp6TVNpVNAXg2sKQSfbwPdR8PxOhFmg",
"expires_in": 1209600,
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InhENWlTYVJiU0dZQzFmdWFTRVdQXy1hejBORW5qSmtoZG00bTJ3X3ZwMHcifQ.eyJzdWIiOiI2MTRmZDlhZTQyYjE5MmZjMzI4MjNiMTAiLCJiaXJ0aGRhdGUiOm51bGwsImZhbWlseV9uYW1lIjpudWxsLCJnZW5kZXIiOiJVIiwiZ2l2ZW5fbmFtZSI6bnVsbCwibG9jYWxlIjpudWxsLCJtaWRkbGVfbmFtZSI6bnVsbCwibmFtZSI6bnVsbCwibmlja25hbWUiOm51bGwsInBpY3R1cmUiOiJodHRwczovL2ZpbGVzLmF1dGhpbmcuY28vYXV0aGluZy1jb25zb2xlL2RlZmF1bHQtdXNlci1hdmF0YXIucG5nIiwicHJlZmVycmVkX3VzZXJuYW1lIjpudWxsLCJwcm9maWxlIjpudWxsLCJ1cGRhdGVkX2F0IjoiMjAyMS0xMS0wMVQxMToyOToyMi4zMDlaIiwid2Vic2l0ZSI6bnVsbCwiem9uZWluZm8iOm51bGwsIm5vbmNlIjoiekx6WndwR05faEpDdDNRTVlvMk12TmplT2o4aTM0U0tpR3ZlMVc0d2R1ayIsImF0X2hhc2giOiJFcGZUR1M2dFNpVnhiMkdPbkxUazNRIiwiYXVkIjoiNjEzMTk2ODBlYThiMzBjOWNhOWNhMDcxIiwiZXhwIjoxNjM3MTMzNjY4LCJpYXQiOjE2MzU5MjQwNjgsImlzcyI6Imh0dHBzOi8vY2p0amxzLWRlbW8uYXV0aGluZy5jbi9vaWRjIn0.iRoYa0JLoBJPXAPD8LjHnuvjQsQ5o5g9qUjPAj1aTMbZqa9GI3gUfxW-smudKJCJmGfYDYJaRP8_szdS03cXCt8u4rGc7y6e6y2Fqq1pssz3VlpRm9t_7LxJrUeBFu1ef87KWO0WZg5Nd6mdoIEAJXwRSW8BbTE_ARg8DZiOcrk3YJ2PxFqb6Tepf3Vw6XyxkHjOfDgJNDnnwHsiMGdXzTMYJwMNKkEjP8xQJl9oh9nOSDF_33-4Btn3nuQQPZ6ndTEcPbaYOo6PN_0IaisjuE3rzyCdGNXxgPrbXg2qywMKZrtj-AKROZ43IA2ito_MtJ6292N6IlFv9SR0Gr4hpw",
"scope": "openid profile",
"token_type": "Bearer"
}
项目地址
https://github.com/Authing/example-spring-boot-oidc
总结
恭喜 🎉,到此你已经学会了 Spring Security 5 集成 Authing OIDC 认证授权的整个流程。后续还有更多的干货,持续关注吧!