keycloak~自定義directgrant直(zhi)接認(ren)證
direct grant我們把它理解為通過rest接口直接認證,這是oauth2里的密碼認證方式,即grant_type=password,它不需(xu)要(yao)走授權碼(ma)這種(zhong)復(fu)雜的(de)(de)流程,相當于傳統的(de)(de)表(biao)單(dan)認(ren)證(zheng);keycloak事(shi)實上為(wei)我們準備了一個direct grant,只不過它只能(neng)使用username和(he)password進(jin)行認(ren)證(zheng),如果你希望使用email,phoneNumber來進(jin)行密碼(ma)認(ren)證(zheng),則需(xu)要(yao)另外(wai)去(qu)開發(fa)(fa),下面就是開發(fa)(fa)的(de)(de)步驟:
- 添加provider和providerFactory
你的SelfDirectGrantAuthenticator需要繼承ValidatePassword ,當然繼承AbstractDirectGrantAuthenticator也是可以的,ValidatePassword是AbstractDirectGrantAuthenticator的一個子類,都是在直接授權時使用的,它的作用是校驗用戶的密碼,KC的這種設計有利于程序的解耦,例如除了ValidatePassword還有ValidateUsername等。
/**
* 直接繼承了驗證密碼功能的direct grant流.
*/
public class TestDirectGrantAuthenticator extends ValidatePassword {
KeycloakSession session;
public V6DirectGrantAuthenticator(KeycloakSession session) {
this.session = session;
}
@Override
public void authenticate(AuthenticationFlowContext context) {
String username = Optional.ofNullable(context.getHttpRequest().getDecodedFormParameters().getFirst("username"))
.orElse(context.getHttpRequest().getDecodedFormParameters().getFirst("username"));
String password = Optional.ofNullable(context.getHttpRequest().getDecodedFormParameters().getFirst("password"))
.orElse(context.getHttpRequest().getDecodedFormParameters().getFirst("password"));
MultivaluedMap<String, String> inputData = new MultivaluedMapImpl<>();
inputData.add(KeycloakUtil.FIELD_EMAIL_PHONE, username);
inputData.add(KeycloakUtil.PASSWORD, password);
if (KeycloakUtil.passwordLogin(this, context, session.getProvider(JpaConnectionProvider.class).getEntityManager(), session, inputData)) {
super.authenticate(context); //驗證密碼
}
}
-
注冊到org.keycloak.authentication.AuthenticatorFactory

-
keycloak管理平臺,添加驗證,可以從默認的direct grant上復制

-
將直接認證流程改成剛剛建立的

-
現在就可以在postman里,脫離瀏覽器,進行認證了,并直接返回access_token




