I am using spring boot application with Keycloack to secure my REST API I have created two user roles on keycloack those are admin and user I need admin privileged user to have to access my API I have created keycloack adapter using OpenID and for authorization, i am using Oath 2.0 method but it always says forbidden even I give admin password credentials it works fine on GET method
Controller class
@PostMapping(value = "/operationChannel", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@RolesAllowed("admin")
public ResponseEntity<ResponseBean> doChannelOperationWithConfiguredValue( @RequestHeader("Authorization") String auth ,@RequestBody @Valid RequestBean requestBean) throws Exception {
System.out.println("REQUEST CAME FROM HTTP SIDE");
logUtil.WriteInfoLog("REQUEST CAME FROM HTTP SIDE : "+requestBean.toString());
System.out.println(requestBean.toString());
logUtil.WriteRequestInfoLog(requestBean.toString());
requestBean.setOperationClient(SysConfigValues.OP_CL_COPER);
requestBean.setModule(SysConfigValues.MODULE_ECH);
requestBean.setModuleName("ECH");
requestBean.setIp(InetAddress.getLocalHost().getHostAddress());
System.out.println("REQUEST TO BE SENT TO ESM");
System.out.println(requestBean.toString());
logUtil.WriteInfoLog("REQUEST TO BE SENT TO ESM : "+requestBean.toString());
ResponseBean responseBean = services.sendRequest(requestBean);
return new ResponseEntity<>(responseBean, HttpStatus.OK);
}
Keycloack Security config class
package com.epic.cms.online.operationservice.config;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpMethod;
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.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@KeycloakConfiguration
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@Import(KeycloakSpringBootConfigResolver.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = new KeycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
/**
* Defines the session authentication strategy.
*/
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(buildSessionRegistry());
}
@Bean
protected SessionRegistry buildSessionRegistry() {
return new SessionRegistryImpl();
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
// .antMatchers("/customers*").hasRole("USER")
// .antMatchers("/cms*").hasRole("admin")
// .antMatchers(HttpMethod.POST).hasAnyRole( "admin")
.anyRequest().permitAll();
}
}
yaml file
keycloak:
auth-server-url: http://127.0.0.1:8080/auth
enabled: true
realm: cms
resource: operation-service
public-client: true
bearer-only: true
postman output
API
POST http://localhost:9002/cms/online/v1/channel/operationChannel
403
12 ms
Network
addresses: {…}
Request Headers
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2VkdCektBYUQ5SFhmZ0RnRjcwVWwxWlFkNVk1MUFmSmtqWEFNSDdud2p3In0.eyJleHAiOjE2NjI3MDA0OTYsImlhdCI6MTY2MjcwMDE5NiwianRpIjoiZjY4ZmNlYzEtOTFhYS00ZDJjLTg2ZDUtYWE5MzlhMmI0ZmRkIiwiaXNzIjoiaHR0cDovLzEyNy4wLjAuMTo4MDgwL2F1dGgvcmVhbG1zL2NtcyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiIzZGVlMDI3My05OTMxLTQ1NjgtYmYwMS05NTI4ZDM3Nzg1NjAiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJvcGVyYXRpb24tc2VydmljZSIsInNlc3Npb25fc3RhdGUiOiIzOGI2NGU5OS01ZTI3LTQyNDUtYjc5NS1hNTlhMzVkNDM0YjciLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6OTAwMiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1jbXMiLCJvZmZsaW5lX2FjY2VzcyIsImFkbWluIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.S9T-bGdC8eV63Un6KHTnfeQSlA6yL51CMeVmdLYhtpRCUBfQM7kcimVk5cCFZ_fQbuBOc-CmjcgkdiD0oeht3ZvVlJPyWwcDKCYMS_eJi8qpfeZEiqY14ML2HyGPwsuYCIbG5gw0PHor71iVNHRa7LknuNfE2gj-4RgnmPCW5oEtjhBZsAZx8_Y2f9j09uE7NEuVhyQpPBKL_4cwaxKtBxxL6t3pF0RVb0ejpoo92LNh610Sn_BqU8wd1BpWXWrO08XCWm3bpf7_Nyql8otnlY68yjTLKMyOklmk7OjmjiwubISF9Mri2GHE-o8fFIO6JU3G7bjb4KYv0MtmsTQBTg
Content-Type: application/json
Postman-Token: ca64ff87-bb16-4cf1-bfd4-a239bef5edf2
Host: localhost:9002
Content-Length: 104
Cookie: JSESSIONID=21EAFD996742B4B49420750ABE209CBA
Request Body
{
"operation": "09",
"userName": "admin",
"channelId": "5",
"connectionType": "1"
}
Response Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 09 Sep 2022 05:10:38 GMT
Response Body
{"timestamp":"2022-09-09T05:10:38.947+00:00","status":403,"error":"Forbidden","path":"/cms/online/v1/channel/operationChannel"}