Spring Boot 和 Keycloak - GrantedAuthority 总是空着回来
Posted
技术标签:
【中文标题】Spring Boot 和 Keycloak - GrantedAuthority 总是空着回来【英文标题】:Spring Boot and Keycloak - GrantedAuthority always coming back empty 【发布时间】:2021-12-02 07:44:22 【问题描述】:我已经设置了一个 REST API,我正在尝试使用 Keycloak 进行保护,并在本地 Docker 组合中运行所有内容。 REST API 在主机/服务rest-api
上运行,Keycloak 在auth-service
上运行,并且两者前面都有一个代理容器(因此以 /auth 开头的任何内容都进入 Keycloak,其他任何内容都进入 API)。
安全配置 - 我已经尝试了一些东西,但目前它是:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfiguration
extends KeycloakWebSecurityConfigurerAdapter
@Override
protected void configure(final HttpSecurity http) throws Exception
super.configure(http);
http.authorizeRequests()
.anyRequest()
.permitAll();
http.csrf().disable();
http.cors();
@Bean
CorsConfigurationSource corsConfigurationSource()
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(
"/**",
new CorsConfiguration().applyPermitDefaultValues()
);
return source;
/**
* Global configuration.
*
* @param auth Authentication Manager Builder
* @throws Exception If security can't be configured
*/
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth)
throws Exception
SimpleAuthorityMapper grantedAuthorityMapper =
new SimpleAuthorityMapper();
grantedAuthorityMapper.setPrefix("ROLE_");
KeycloakAuthenticationProvider keycloakAuthenticationProvider =
keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
grantedAuthorityMapper
);
auth.authenticationProvider(keycloakAuthenticationProvider);
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy()
return new RegisterSessionAuthenticationStrategy(
new SessionRegistryImpl()
);
然后是一个简单的控制器:
@RestController
@CrossOrigin("*")
@RequestMapping("/api/v3/auth")
public class AuthController
/**
* Logger.
*/
private static final Logger LOGGER =
LoggerFactory.getLogger(AuthController.class);
/**
* Default constructor.
*/
AuthController()
LOGGER.info("AuthController Constructor.");
...
/**
* Checks/initiates a user login.
*
* @return Information about the current user's auth status
*/
@RolesAllowed("ROLE_user")
@GetMapping(
value = "/login1",
produces = MediaType.APPLICATION_JSON_VALUE
)
@ResponseBody
public Map<String, String> login1()
final Map<String, String> response = new HashMap<String, String>();
response.put("status", "OK");
final Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
final List<String> roles = new ArrayList<String>();
for (GrantedAuthority authority : authentication.getAuthorities())
roles.add(authority.getAuthority());
response.put(
"Current user roles",
"[" + String.join(",", roles) + "]"
);
return response;
@RolesAllowed
注释确实启动了 Keycloak 集成。我被带到登录页面,我被允许登录,然后我被传回位于 /sso/login 的 REST 应用程序,并且该响应设置了我期望的 JWT:
Set-Cookie: KEYCLOAK_ADAPTER_STATE=eyJhbGciOi...
使用https://jwt.io/ 进行调试,该令牌对我来说看起来不错,具体来说:
"realm_access":
"roles": [
"offline_access",
"uma_authorization",
"user"
]
,
但是,当我被引导回到登录页面时,我收到了 403 禁止。所以我在同一个控制器中设计了第二种方法:
@GetMapping(
value = "",
produces = MediaType.APPLICATION_JSON_VALUE
)
@ResponseBody
public Map<String, String> read()
final Map<String, String> response = new HashMap<String, String>();
response.put("status", "OK");
final Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
response.put(
"AUTHENTICATION NAME",
authentication.getName()
);
response.put(
"AUTHENTICATION PRINCIPAL",
authentication.getPrincipal().toString()
);
response.put(
"AUTHENTICATION AUTHORITIES",
authentication.getAuthorities().toString()
);
int i = 0;
for (GrantedAuthority authority : authentication.getAuthorities())
response.put(
"AUTHORITY-" + i++,
authority.getAuthority()
);
return response;
输出如下:
"AUTHENTICATION PRINCIPAL": "<GUID I expect>",
"AUTHENTICATION NAME": "<GUID I expect>",
"status": "OK",
"AUTHENTICATION AUTHORITIES": "[]"
所以...我显然从 Keycloak 获得了身份验证 JWT,看起来 Spring 正在尝试用它做正确的事情。但是 GrantedAuthority 列表总是空的,所以我总是得到 403。
对这里出了什么问题有什么建议吗?
【问题讨论】:
【参考方案1】:当然,这一切都归结为一个配置行:
keycloak.use-resource-role-mappings = true
将其更改为 false 从领域映射而不是资源映射中提取,我很好。
【讨论】:
以上是关于Spring Boot 和 Keycloak - GrantedAuthority 总是空着回来的主要内容,如果未能解决你的问题,请参考以下文章
dockerized 环境中的 Keycloak 和 Spring Boot Web 应用程序
Docker(Spring Boot 或 Thorntail)和 Keycloak
Spring Boot 我无法切换 keycloak 和基本身份验证
403 spring-boot-2-keycloak-适配器