keycloak~巧(qiao)用(yong)client-scope實現(xian)token字段和userinfo接口的(de)授權
keycloak中的client-scope允許你為每個客戶端(duan)(duan)分配scope,而(er)scope就是授權(quan)范圍,它(ta)直接影響了token中的內容,及userinfo端(duan)(duan)點可(ke)以獲取到(dao)的用(yong)戶信(xin)息,這塊我(wo)們可(ke)以通過自定義scope/mapper,來實現(xian)粒度的控制,并(bing)且這個mapper可(ke)以控制添(tian)加到(dao)token,或(huo)者添(tian)加到(dao)userinfo端(duan)(duan)點,這兩塊配置也是獨(du)立的,下面我(wo)們通過一個登(deng)錄IP地址的mapper,來實現(xian)將登(deng)錄ip添(tian)加到(dao)token和userinfo端(duan)(duan)點。
添加Mapper對象
public class ExtensionLoginIpMapper
extends AbstractOIDCProtocolMapper
implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper {
public static final String CONFIG_NAME = "ExtensionLoginIp";//配置里的名稱
public static final String PROVIDER_ID = "oidc-extension-login-ip-mapper";
private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
private static final String LOGIN_IP = "loginIp";
static {
configProperties.add(createConfigProperty(CONFIG_NAME, "Token申請名", "在jwt中的屬性名稱,默認loginIp"));
OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, ExtensionLoginIpMapper.class);
}
protected static ProviderConfigProperty createConfigProperty(String claimName, String label, String help) {
ProviderConfigProperty property = new ProviderConfigProperty();
property.setName(claimName);
property.setLabel(label);
property.setHelpText(help);
property.setType(ProviderConfigProperty.STRING_TYPE);
return property;
}
@Override
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession,
KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx) {
try {
String key = LOGIN_IP;
if (mappingModel.getConfig().containsKey(CONFIG_NAME)) {
key = mappingModel.getConfig().get(CONFIG_NAME);
}
if (userSession.getNotes().containsKey(LOGIN_IP)) {
String val = userSession.getNote(LOGIN_IP);
token.setOtherClaims(key, val);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
}
@Override
public String getId() {
return PROVIDER_ID;
}
@Override
public String getDisplayType() {
return CONFIG_NAME;
}
@Override
public String getDisplayCategory() {
return TOKEN_MAPPER_CATEGORY;
}
@Override
public String getHelpText() {
return "Maps Extension Login Ip Address.";
}
}
將Mapper添加到Client Scope
- 添加 client scope

- 在client scope中添加mapper

設置access_token可見和userinfo可見
- Add to ID token
- Add to access token
- Add to access token

為客戶端指定scope
- 這對于根據客戶端來控制token和userinfo端點是非常必要的功能
- 這是oauth2授權的重要組成部分

通過oauth2中的密碼認證時的注意點
- 客戶端不能是
同意必選的,這種客戶端需要通過瀏覽器認證,由用戶自己確認它公開的信息


通過token獲取用戶信息
- userinfo端點:/auth/realms/{realms}/protocol/openid-connect/userinfo
- 獲取到時的用戶信息中的字段,是通過scope來控制的
