说明
Keycloak是一个开源的身份认证和授权管理系统,它提供了一系列的功能,包括单点登录、身份验证、社交登录、用户管理、角色管理、权限管理等等。Keycloak可以被集成到各种应用程序中,包括Web应用程序、移动应用程序和服务。它支持OpenID Connect、OAuth 2.0和SAML 2.0等标准协议。
OpenID Connect、OAuth 2.0和SAML 2.0主要区别
OpenID Connect、OAuth 2.0和SAML 2.0是三种不同的身份验证和授权协议。它们的主要区别如下:
OpenID Connect
基于OAuth 2.0协议,用于身份验证和授权。
用于Web应用程序和移动应用程序。
提供了用户身份验证和授权的标准化方法。
支持JSON Web Token(JWT)。OAuth 2.0
用于授权,而非身份验证。
用于Web应用程序和移动应用程序。
允许用户授权第三方应用程序访问其资源。
支持JSON Web Token(JWT)。SAML 2.0
用于身份验证和授权。
用于Web应用程序和企业应用程序。
允许用户在不同的应用程序之间共享身份验证信息。
使用XML格式的安全令牌。
注意keycloak默认在创建client时,默认已经是OpenID Connect了。
idToken和accessToken
idToken是身份令牌,包含有关用户身份验证的信息,例如用户ID和用户名。idToken是通过OpenID Connect协议发出的,用于验证用户身份和授权访问资源。
accessToken是访问令牌,包含有关用户授权的信息,例如授权范围和过期时间。accessToken是通过OAuth 2.0协议发出的,用于访问受保护的资源。
获取token(idToken、accessToken、refreshToken)
String serverUrl = "http://keycloak.xxxxx.org:8088";
String realm = "xxxxx";
String username = "xxxxx";
String password = "xxxxx";
String clientId = "xxxxx-client";
String clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxx";
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl(serverUrl)
.realm(realm)
.clientId(clientId)
.clientSecret(clientSecret)
.username(username)
.password(password)
.grantType(OAuth2Constants.PASSWORD)
.scope(OAuth2Constants.SCOPE_OPENID)
.build();
AccessTokenResponse tokenResponse = keycloak.tokenManager().getAccessToken();
String accessToken = tokenResponse.getToken();
String idToken = tokenResponse.getIdToken();
System.out.println("[token]=======" + accessToken + ",[idToken]====" + idToken + ",[refreshToken]====" + tokenResponse.getRefreshToken());
// Get user resource
RealmResource realmResource = keycloak.realm(realm);
UserResource userResource = realmResource.users().get("5962a29c-9a13-483e-9ad3-f2a57dbde9a9");
// Get user representation
UserRepresentation user = userResource.toRepresentation();
// Print user information
System.out.println("User ID: " + user.getId());
System.out.println("Username: " + user.getUsername());
System.out.println("Email: " + user.getEmail());
token数据信息
- accessToken
{
"exp": 1685084733,
"iat": 1684911933,
"jti": "310e0c34-206d-48d5-a944-27ae4c6068ff",
"iss": "http://keycloak.xxxx.org:8088/realms/xxxx",
"aud": [
"realm-management",
"account"
],
"sub": "deb8d8b7-f0f9-41a0-a7aa-c9c1a891db36",
"typ": "Bearer",
"azp": "xxxx-client",
"session_state": "d5a45e06-cf57-4297-9f34-f2280ea18133",
"realm_access": {
"roles": [
"access-idm",
"offline_access",
"access-task",
"access-modeler",
"uma_authorization",
"access-admin"
]
},
"resource_access": {
"realm-management": {
"roles": [
"view-users",
"query-groups",
"query-users"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid email profile",
"sid": "d5a45e06-cf57-4297-9f34-f2280ea18133",
"userGroups": [
"xxxxUsers"
],
"email_verified": true,
"name": "Admin Admin",
"preferred_username": "xxxx",
"given_name": "Admin",
"family_name": "Admin"
}
- idToken
{
"exp": 1685084733,
"iat": 1684911933,
"auth_time": 0,
"jti": "ffbc5e1b-21b7-4e54-acf8-49d71ff9ba6c",
"iss": "http://keycloak.xxxx.org:8088/realms/xxxx",
"aud": "xxxx-client",
"sub": "deb8d8b7-f0f9-41a0-a7aa-c9c1a891db36",
"typ": "ID",
"azp": "xxxx-client",
"session_state": "d5a45e06-cf57-4297-9f34-f2280ea18133",
"at_hash": "CmzwF7NlpMFbDo8sQTDI_A",
"sid": "d5a45e06-cf57-4297-9f34-f2280ea18133",
"userGroups": [
"xxxxUsers"
],
"email_verified": true,
"name": "Admin Admin",
"preferred_username": "xxxx",
"given_name": "Admin",
"family_name": "Admin"
}
Access Token和JWT Token区别:
Access Token和JWT Token都是用于身份验证和授权的令牌,但它们有以下区别:
- Access Token是OAuth 2.0协议中的一种令牌,用于访问受保护的资源。它通常由授权服务器颁发,并包含有关令牌持有者和授权的信息。而JWT-Token是一种轻量级的令牌,用于在不同的应用程序之间传递身份验证和授权信息。
- Access Token通常是短期的,过期后需要重新获取,而JWT Token可以设置过期时间,也可以使用刷新令牌进行更新。
- Access Token通常需要与授权服务器进行交互以验证和更新令牌,而JWT Token可以在不需要与授权服务器交互的情况下进行验证和解码。
JWT Token可以由服务端或客户端生成,具体取决于应用程序的设计和需求。
如果应用程序需要在用户登录时生成JWT Token并将其存储在客户端(如浏览器)中,那么客户端将负责生成JWT Token。这种情况下,客户端通常会使用用户的登录凭据(如用户名和密码)来生成JWT Token。
如果应用程序需要在每次对受保护的资源进行请求时生成JWT Token,那么服务端将负责生成JWT Token。这种情况下,服务端通常会使用应用程序的密钥来生成JWT Token。
客户端的访问类型
Keycloak的客户端访问类型有以下几种:
- Public
公开客户端,不需要任何认证即可访问。
适用于客户端应用,且需要浏览器登录的场景。如:前端web系统。 - Confidential
机密客户端,需要提供客户端ID和客户端密钥才能访问。
适用于服务端应用,且需要浏览器登录以及需要获取access token的场景。如:服务端渲染的web系统。 - Bearer-only
仅支持Bearer Token的客户端,用于API服务。
适用于服务端应用,不需要浏览器登录,只允许使用bearer token请求的场景
这些访问类型的作用是用于控制客户端的访问权限和安全性。