Springboot繼承Keycloak實(shí)現(xiàn)單點(diǎn)登錄與退出功能
什么是 keycloak
keycloak是一個(gè)開(kāi)源的進(jìn)行身份認(rèn)證和訪問(wèn)控制的軟件。是由Red Hat基金會(huì)開(kāi)發(fā)的,我們可以使用keycloak方便的向應(yīng)用程序和安全服務(wù)添加身份認(rèn)證,非常的方便?;?Java 開(kāi)發(fā),支持多種數(shù)據(jù)庫(kù)。
由于網(wǎng)上博客大部分都只有登陸沒(méi)有退出,自己花了一些時(shí)間研究了一下,這里將相關(guān)內(nèi)容進(jìn)行記錄,基于Keyclaok 20的版本,實(shí)現(xiàn)springboot服務(wù)單點(diǎn)登錄與退出
一、依賴
<!-- 在父工程中 -->
<dependencyManagement>
<dependencies>
<!-- 導(dǎo)入依賴 -->
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>22.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 在子工程中 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
</dependency>
</dependencies>二、keycloak配置
這個(gè)是主要的,用設(shè)置攔截器實(shí)現(xiàn)登陸與退出
package com.example.basic.conf;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@KeycloakConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class KeycloakSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
public org.keycloak.adapters.KeycloakConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.logout()
//攔截logout請(qǐng)求
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.addLogoutHandler(keycloakLogoutHandler())
.logoutSuccessHandler(logoutSuccessHandler())
.deleteCookies("JSESSIONID")
.and()
//設(shè)置哪些可以忽略掉授權(quán)
.authorizeRequests()
.antMatchers("/user/login", "/token/generate",
"/access/**", "/js/**","/css/**","/fonts/**", "/index.html", "/error").permitAll()
//除了上面忽略掉授權(quán)請(qǐng)求,剩下所有必須經(jīng)過(guò)授權(quán)才可以訪問(wèn)
.antMatchers("/**").authenticated()
.and().cors()
.and().csrf().disable();
}
//處理logout自動(dòng)跳轉(zhuǎn)請(qǐng)求
private LogoutSuccessHandler logoutSuccessHandler() {
return new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Authentication authentication)
throws IOException, ServletException {
KeycloakAuthenticationToken keycloakAuthenticationToken = (KeycloakAuthenticationToken)authentication;
KeycloakSecurityContext keycloakSecurityContext =
keycloakAuthenticationToken.getAccount().getKeycloakSecurityContext();
String idTokenHint = keycloakSecurityContext.getIdTokenString();
String issuer = keycloakSecurityContext.getIdToken().getIssuer();
String keycloakBaseUrl = issuer + "/protocol/openid-connect/logout";
String postLogoutRedirectUri = httpServletRequest.getScheme() + "://" + httpServletRequest.getHeader("host");
String logoutUrl = keycloakBaseUrl + "?post_logout_redirect_uri=" + postLogoutRedirectUri + "&id_token_hint=" + idTokenHint;
// Do logout by redirecting to Keycloak logout
httpServletResponse.sendRedirect(logoutUrl);
}
};
}
}到此這篇關(guān)于Springboot繼承Keycloak實(shí)現(xiàn)單點(diǎn)登錄與退出功能的文章就介紹到這了,更多相關(guān)Springboot Keycloak單點(diǎn)登錄與退出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Elasticsearch常見(jiàn)字段映射類型之scaled_float解讀
這篇文章主要介紹了Elasticsearch常見(jiàn)字段映射類型之scaled_float解讀。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
運(yùn)用java以及循環(huán)打印菱形詳細(xì)實(shí)例代碼
最近在看算法書的時(shí)候,看到有打印上三角的算法,然后要舉一反三,下面這篇文章主要介紹了運(yùn)用java以及循環(huán)打印菱形的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-10-10
通過(guò)簡(jiǎn)單方法實(shí)現(xiàn)spring boot web項(xiàng)目
這篇文章主要介紹了通過(guò)簡(jiǎn)單方法實(shí)現(xiàn)spring boot web項(xiàng)目,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
解釋為什么Java中“1000==1000”為false而”100==100“為true
在日常編程中,我們經(jīng)常遇到一些看似簡(jiǎn)單卻隱藏著復(fù)雜邏輯的問(wèn)題,這篇文章主要介紹了解釋為什么Java中“1000==1000”為false而”100==100“為true,需要的朋友可以參考下2024-01-01
淺析如何在Java應(yīng)用中優(yōu)雅的發(fā)送短信
很多業(yè)務(wù)場(chǎng)景里,我們都需要發(fā)送短信,比如登陸驗(yàn)證碼、告警、營(yíng)銷通知、節(jié)日祝福等等,這篇文章,我們聊聊 Java 應(yīng)用中如何優(yōu)雅的發(fā)送短信,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2023-11-11

