我需要向我的Spring Boot(MVC)应用添加身份验证。身份验证提供程序是通过OpenID进行的密钥隐藏。隐式和授权代码授予都被禁用,因此我被资源所有者凭证授予所困扰。我要实现的是针对未授权用户的基本身份验证提示。以此方式检索的凭证应用于从密钥斗篷中获取令牌和用户信息,以供Spring Security进一步使用。每个请求都应检查令牌。
我发现的大多数示例都使用org.keycloak:keycloak-spring-boot-starter
的重定向功能。尽管我发现了enable-basic-auth
here,但它对我不起作用。我知道我必须使用keycloak.bearer-only=true
来关闭重定向,但是它可以正常工作,而不是重定向,它会为未授权用户返回401。
我的安全配置:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().permitAll();
}
}
我的keycloak属性(我不使用占位符,只是为了安全起见):
keycloak.auth-server-url=https://${keycloak.host}/auth/
keycloak.realm=master
keycloak.resource=${client.name}
keycloak.enable-basic-auth=true
keycloak.credentials.secret=${client.secret}
很抱歉提出一般问题。我主要使用jdbcAuthentication,这是我第一次使用Identity Management软件。
答案 0 :(得分:0)
这是一种通过带有资源所有者密码凭据流的keycloak openid向应用程序添加基本身份验证的方法。
首先,您需要将其添加到pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>4.2.0.Final</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>
...
</dependencies>
添加keycloak服务器属性:
keycloak.auth-server-url=https://${keycloak.host}/auth/
keycloak.realm=master
keycloak.resource=${client.name}
keycloak.credentials.secret=${client.secret}
keycloak.enable-basic-auth=true
keycloak.bearer-only=true
enable-basic-auth
实际上负责启用资源所有者密码凭据流。因此,每次您使用基本授权BasicAuthRequestAuthenticator
发送请求时,都会从keycloak请求令牌。需要bearer-only
才能关闭访问代码流。每次您在没有基本授权(和外部授权会话)的情况下请求对安全资源的请求时,您都将被重定向到Keycloak服务器-我们不希望这样。使用bearer-only
,您将获得401。
最后一步是添加安全配置:
@Configuration
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@EnableWebSecurity
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Bean
public KeycloakAuthenticationProvider authenticationProvider() {
KeycloakAuthenticationProvider provider = new KeycloakAuthenticationProvider();
provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
return provider;
}
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.csrf().disable()
.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Restricted Content\"");
response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
})
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin")
.anyRequest().permitAll();
}
}
这里最有趣的部分是这个
.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Restricted Content\"");
response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
})
标准密钥斗篷AuthenticationEntryPoint
的实现是在授权失败的情况下将WWW-Authenticate
标头设置为String.format("Bearer realm=\"%s\"", realm)
。我需要将其设置为Basic realm="Restricted Content"
才能弹出基本身份验证提示。如果您想避免使用此提示(要添加自己的登录表单),请删除此部分。