OpenID Connect应用集成
本文介绍OpenID Connect应用如何与MaxKey进行集成。
认证流程
请参照OAuth2认证流程
应用注册
应用在MaxKey管理系统进行注册,注册的配置信息如下
集成和接口
用户属性接口/api/connect/v10/userinfo
通过访问token 获取登录用户信息及签名信息,在程序中必须验证相关的签名信息。
接口名称 | OIDC授权用户信息查询接口 |
---|---|
url | https://sso.maxkey.org/maxkey/api/connect/v10/userinfo |
请求方式 | http get/post |
请求参数
参数 | 说明 |
---|---|
access_token | 调用sso/ token获得的token值。 |
实际请求如下:
| |
返回数据/ response data | |
成功返回JSON数据,如下:
zhangs是认证的用户ID |
OAuth认证接口属性列表
属性名(Attribute) | 描述 | 数据类型 |
---|---|---|
uid | uid | 字符串 |
其他请参照OAuth2
OIDC V1客户端集成
本文使用JAVA WEB程序为例
引入依赖包
gson-2.2.4.jar
maxkey-client-sdk.jar
nimbus-jose-jwt-8.10.jar
commons-codec-1.9.jar
commons-io-2.2.jar
commons-logging-1.1.1.jar
认证授权
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ page language="java" import="org.maxkey.client.oauth.oauth.*" %>
<%@ page language="java" import="org.maxkey.client.oauth.builder.*" %>
<%@ page language="java" import="org.maxkey.client.oauth.builder.api.MaxkeyApi20" %>
<%@ page language="java" import="org.maxkey.client.oauth.model.Token" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+path+"/";
String callback="http://oauth.demo.maxkey.top:8080/demo-oauth/oauth20callback.jsp";
OAuthService service = new ServiceBuilder()
.provider(MaxkeyApi20.class)
.apiKey("ae20330a-ef0b-4dad-9f10-d5e3485ca2ad")
.apiSecret("KQY4MDUwNjIwMjAxNTE3NTM1OTEYty")
.callback(callback)
.build();
Token EMPTY_TOKEN = null;
String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
request.getSession().setAttribute("oauthv20service", service);
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>OIDC V1 SSO</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<a href="<%=authorizationUrl%>&approval_prompt=auto">OIDC V1 SSO</a>
</body>
</html>
登录验证
获取令牌、用户信息及验证签名 (id_token及用户信息)
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page language="java" import="org.maxkey.client.oauth.oauth.*" %>
<%@ page language="java" import="org.maxkey.client.oauth.builder.*" %>
<%@ page language="java" import="org.maxkey.client.oauth.builder.api.MaxkeyApi20" %>
<%@ page language="java" import="org.maxkey.client.oauth.model.*" %>
<%@ page language="java" import="org.maxkey.client.oauth.*" %>
<%@ page language="java" import="org.maxkey.client.oauth.domain.*" %>
<%@ page language="java" import="org.maxkey.client.utils.*" %>
<%@ page language="java" import="com.nimbusds.jwt.JWTClaimsSet" %>
<%@ page language="java" import="com.nimbusds.jose.*" %>
<%@ page language="java" import="com.nimbusds.jwt.*" %>
<%@ page language="java" import="com.connsec.oidc.jose.keystore.*" %>
<%@ page language="java" import="com.nimbusds.jose.jwk.*" %>
<%@ page language="java" import="java.io.File" %>
<%@ page language="java" import="com.nimbusds.jose.crypto.*" %>
<%@ page language="java" import="com.google.gson.*" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
OAuthService service = (OAuthService)request.getSession().getAttribute("oauthv20service");
if(service==null){
String callback="http://oauth.demo.maxkey.top:8080/demo-oauth/oidc10callback.jsp";
service = new ServiceBuilder()
.provider(MaxkeyApi20.class)
.apiKey("ae20330a-ef0b-4dad-9f10-d5e3485ca2ad")
.apiSecret("KQY4MDUwNjIwMjAxNTE3NTM1OTEYty")
.callback(callback)
.build();
}
Token EMPTY_TOKEN = null;
Verifier verifier = new Verifier(request.getParameter("code"));
Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
//JWTClaimsSet idClaims = JWTClaimsSet.parse(accessToken.getId_token());
SignedJWT signedJWT=null;
//JWKSetKeyStore jwkSetKeyStore=new JWKSetKeyStore();
File jwksFile=new File(PathUtils.getInstance().getClassPath()+"jwk.jwks");
JWKSet jwkSet=JWKSet.load(jwksFile);
RSASSAVerifier rsaSSAVerifier = new RSASSAVerifier(((RSAKey) jwkSet.getKeyByKeyId("maxkey_rsa")).toRSAPublicKey());
try {
signedJWT = SignedJWT.parse(accessToken.getId_token());
} catch (java.text.ParseException e) {
// Invalid signed JWT encoding
}
;
OAuthClient restClient=new OAuthClient("http://sso.maxkey.top/sign/api/connect/v10/userinfo",accessToken.getToken());
OIDCUserInfo userInfo=restClient.getOIDCUserInfo(accessToken.getToken());
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>OpenID Connect 1.0 Demo</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="OpenID Connect 1.0 Demo">
<link rel="shortcut icon" type="image/x-icon" href="<%=basePath %>/images/favicon.ico"/>
<script type="text/javascript" src="<%=basePath %>/jquery-3.5.0.min.js"></script>
<script type="text/javascript" src="<%=basePath %>/jsonformatter.js"></script>
<link type="text/css" rel="stylesheet" href="<%=basePath %>/demo.css"/>
</head>
<body>
<div class="container">
<table class="datatable">
<tr>
<td colspan="2" class="title">OpenID Connect 1.0 Demo</td>
</tr>
<tr>
<td>OpenID Connect 1.0 Logo</td>
<td> <img src="<%=basePath %>/images/openid.png" width="124px" height="124px"/></td>
</tr>
<tr>
<td>Login</td>
<td><%=userInfo.getSub() %></td>
</tr>
<tr>
<td>DisplayName</td>
<td><%=userInfo.getName()%></td>
</tr>
<tr>
<td>Department</td>
<td><%=userInfo.getGender() %></td>
</tr>
<tr>
<td>email</td>
<td><%=userInfo.getEmail() %></td>
</tr>
<tr>
<td>ResponseString</td>
<td style="word-wrap: break-word;">
<textarea cols="68" rows="20" v-model="text2"><%=userInfo.getResponseString() %></textarea>
</td>
</tr>
<tr>
<td>Id_token</td>
<td style="word-wrap: break-word;"><%=accessToken.getId_token() %></td>
</tr>
<tr>
<td>Verify</td>
<td style="word-wrap: break-word;"><%=signedJWT.verify(rsaSSAVerifier) %></td>
</tr>
<tr>
<td>Issuer</td>
<td style="word-wrap: break-word;"><%=signedJWT.getJWTClaimsSet().getIssuer() %></td>
</tr>
<tr>
<td>JWTClaims</td>
<td style="word-wrap: break-word;">
<textarea cols="68" rows="20" v-model="text2"><%=signedJWT.getPayload() %></textarea>
</td>
</tr>
</table>
</div>
<script type="text/javascript">
FormatTextarea();
</script>
</body>
</html>