Java Spring应用程序通过KeyClock进行基本身份验证
我需要将auth添加到我的spring boot(MVC)应用程序中。身份验证提供程序是通过OpenID进行密钥伪装的。隐式授权和授权码授权都被禁用,因此我只能使用资源所有者凭据授权。我想要实现的是对未授权用户的基本身份验证提示。通过这种方式检索到的凭据应该用于从KeyClope获取令牌和用户信息,以供spring security进一步使用。应在每个请求中检查令牌 我发现的大多数示例都使用了org.keydove:keydove spring boot starter的重定向功能。虽然我发现Java Spring应用程序通过KeyClock进行基本身份验证,java,spring-boot,spring-security,keycloak,Java,Spring Boot,Spring Security,Keycloak,我需要将auth添加到我的spring boot(MVC)应用程序中。身份验证提供程序是通过OpenID进行密钥伪装的。隐式授权和授权码授权都被禁用,因此我只能使用资源所有者凭据授权。我想要实现的是对未授权用户的基本身份验证提示。通过这种方式检索到的凭据应该用于从KeyClope获取令牌和用户信息,以供spring security进一步使用。应在每个请求中检查令牌 我发现的大多数示例都使用了org.keydove:keydove spring boot starter的重定向功能。虽然我发现启
启用基本身份验证
,但它对我不起作用。我知道我必须使用keydape.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();
}
}
我的KeyClope属性(我不使用占位符,只是为了安全):
对不起,我的问题太笼统了。我主要使用jdbcAuthentication,这是我第一次使用身份管理软件。这里有一种方法可以使用资源所有者密码凭据流通过KeyClope 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>
启用基本身份验证
实际上负责启用资源所有者密码凭据流。因此,每次您发送带有基本授权的请求时,BasicAuthRequestAuthenticator
都会从KeyClope请求令牌<代码>仅承载用于关闭访问代码流。每次您在没有基本授权的情况下(以及在授权会话之外)向安全资源发出请求时,您都会被重定向到KeyClope服务器——我们不希望这样。使用仅持票人
您将获得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());
})
标准keydape
AuthenticationEntryPoint
实现将WWW-Authenticate
头设置为String.format(“承载域=\%s\”,领域)
,以防授权失败。我需要将其设置为Basic realm=“Restricted Content”
,以便弹出基本身份验证提示。如果您想避免使用此提示(您想添加自己的登录表单),请删除此部分。注意,在您引用的文档中,它说“如果启用了此选项,则还必须提供机密”。这需要在客户端适配器的配置和域中进行配置。看到了吗,这是官方的密钥斗篷基本认证example@RyanDawson谢谢你的回复!是的,我已经打开了所有这些选项:keydove.credentials.secret=66666 A66-66a6-6a66-666a-6a6a66aa666
并且启用了直接访问授权
。您看到的失败行为是什么?我不清楚您所说的“不工作”是什么意思@RyanDawson通过删除spring boot starter security
和SecurityConfig.java
,我已经能够使用curl实现基本身份验证,但在浏览器中,我没有得到基本身份验证提示,而是得到了重定向。使用spring boot starter security
和SecurityConfig
basic auth,即使使用curl(HTTP/1.1 302
位置:http://localhost:8080/sso/login
)。localhost:8080是我的应用程序地址。更新:需要自定义authenticationEntryPoint,并且keydove.bearer only=true
。401
响应的标题错误。应该是WWW-Authenticate:Basic realm=“Restricted Content”
我稍后会发布代码
@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());
})