aquero
aquero

Reputation: 863

Keycloak- Angular-Rest Integration - Roles are always empty

When I read about integrating keycloak with Angular+REST application, mostly I see an approach having two clients, one public and one bearer-only. Is this the best solution or can I use a single confidential client for both application. I read that using confidential client for javascript is not the best way to do as there is no way to keep the secret hidden in javascript.

Also, after integrating keycloak to both rest and UI project using the two clients approach, authentication seems to be working. But I am not getting any roles in the rest side. I am using spring security adapter and springboot 1.5.18 for the backend. My keycloak server version is 3.4.12 and keycloak spring adapter version is 3.4.3. Keycloak configuration files are also provided below.

keycloak.json (Angular project)

{
  "realm": "dev",
  "auth-server-url": "https://<keycloakserver> /auth",
  "resource": "frontend-dev",
  "public-client": true,
  "use-resource-role-mappings": true,
 "confidential-port": 0,
  "ssl-required": "external",
  "disable-trust-manager": true
}

application.properties (springboot)

keycloak.realm=dev
keycloak.bearer-only=true
keycloak.auth-server-url=https:// <keycloakserver> /auth
keycloak.resource= backend-dev
keycloak.use-resource-role-mappings=true
keycloak.credentials.secret=222-3333-4444-5555
#development only properties
keycloak.ssl-required=external
keycloak.disable-trust-manager=true

Keycloak Java configuration

@KeycloakConfiguration

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)

public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {


 /**

  * Registers the KeycloakAuthenticationProvider with the authentication manager.

  */

 @Autowired

 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

  KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();

  keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());

  auth.authenticationProvider(keycloakAuthenticationProvider);

 }



 /**

  * Defines the session authentication strategy.

  */

 @Bean

 @Override

 protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {

  return new NullAuthenticatedSessionStrategy();

 }



 @Bean

 public KeycloakConfigResolver keycloakConfigResolver() {

  return new KeycloakSpringBootConfigResolver();

 }



 @Bean

 public FilterRegistrationBean

 keycloakAuthenticationProcessingFilterRegistrationBean(KeycloakAuthenticationProcessingFilter filter) {

  FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);

  registrationBean.setEnabled(false);

  return registrationBean;

 }


 @Bean

 public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(KeycloakPreAuthActionsFilter filter) {

  FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);

  registrationBean.setEnabled(false);

  return registrationBean;

 }


 @Bean

 @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)

 public AccessToken accessToken() {

  HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())

   .getRequest();

  return ((KeycloakSecurityContext)((KeycloakAuthenticationToken) request.getUserPrincipal()).getCredentials())

   .getToken();

 }


 @Override

 protected void configure(HttpSecurity http) throws Exception {

  super.configure(http);

  http.authorizeRequests().antMatchers("/**").permitAll();

 }

}

To protect a rest resource used the annotation

@RolesAllowed(“Name of the role”)

Even after assigning a client role to the user it was throwing 403-Access denied error

I also tried to get the roles manually using the code

   SecurityContext securityContext = SecurityContextHolder.getContext();
   securityContext.getAuthentication().getAuthorities();

But it was always returning an empty array.

Upvotes: 0

Views: 2241

Answers (1)

aquero
aquero

Reputation: 863

I was able to finally solve the issue. Problem was with the missing Scope configuration in the frontend keycloak client. For all the clients full scope was turned off due to security reason. Because of that unless we set explicitly in the client scope configuration of the frontend client to include the backend client roles, it wont be part of the token.

Upvotes: 2

Related Questions