问题
Keycloak policy enforcer not working with a sample Sprint boot application.
I am using Keycloak version 6.0.1 and trying to integrate a sample Sprint boot application (Sprint boot version 2.1.3). My objective to setup policies and permissions in Keycloak and use Keycloak policy enforcer in my sample Spring boot application so that all authorization decisions are automatically enforced using appropriate permission defined in Keycloak and no code is required in Sample application.
My Sample spring boot application just prints a list of users from a in memory List:
public class JPAUserResource {
@Autowired
private UserRepository userRepo;
@GetMapping(path = "/jpausers")
public List<JPAUser> retrieveAllUsers() {
return userRepo.findAll();
}
}
My application.properties file has following content:
server.port=38080
spring.jpa.show-sql=true
spring.h2.console.enabled=true
logging.level.org.springframework.security=DEBUG
logging.level.org.keycloak.adapters.authorization=DEBUG
#Keycloak Configuration
keycloak.auth-server-url=http://192.168.154.190:18180/auth
keycloak.realm=master
keycloak.resource=login-app
keycloak.principal-attribute=preferred_username
keycloak.credentials.secret=195925d6-b258-407d-a65d-f1fd12d7a876
keycloak.policy-enforcer-config.enforcement-mode=enforcing
keycloak.realm-key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjyYRe6LxBxO9hVtr4ScsMCBp3aPE9qbJLptPIMQCZR6JhVhOxA1kxhRmVYHXR5pdwiQWU8MriRhAY1JGniG6GNS1+BL+JaUiaGxov4rpD2SIMdrs8YjjSoD3Z8wvsMAopzWG48i9T/ppNaqKTkDZHbHAXOYJn+lymQ4EqpQrJ1Uh+SUA8XcLvWUQ12ty9BieujudWhnAgQ4zxyJY3I8sZwjaRIxndzSlyPJo45lWzXkpqcl92eU/Max7LRM4WKqsUvu86DgqlXbJcz8T+GUeF30ONQDSLX9rwNIT4ZiCVMT7x6YfKXZW6jxC0UiXxZuT23xk8A9iCP4rC9xo1NfGTwIDAQAB
keycloak.policy-enforcer-config.paths[0].path=/jpausers
keycloak.policy-enforcer-config.paths[0].methods[0].method=GET
My Keycloak authorization settings are as below:
{
"allowRemoteResourceManagement": true,
"policyEnforcementMode": "ENFORCING",
"resources": [
{
"name": "Default Resource",
"type": "urn:login-app:resources:default",
"ownerManagedAccess": false,
"attributes": {},
"_id": "501febc8-f3e1-411f-aecf-376b4786c24e",
"uris": [
"/*"
]
},
{
"name": "jpausers",
"ownerManagedAccess": false,
"displayName": "jpausers",
"attributes": {},
"_id": "a8f691db-39ef-4b2c-80fb-37224e270f1e",
"uris": [
"/jpausers"
],
"scopes": [
{
"name": "GET"
},
{
"name": "POST"
}
]
}
],
"policies": [
{
"id": "94518189-3794-451c-9996-eec22543d802",
"name": "Default Policy",
"description": "A policy that grants access only for users within this realm",
"type": "js",
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"code": "// by default, grants any permission associated with this policy\n$evaluation.grant();\n"
}
},
{
"id": "0242cf72-365d-49ae-8d5b-4ced24736f24",
"name": "test_jpa",
"type": "role",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS",
"config": {
"roles": "[{\"id\":\"jpa\",\"required\":false}]"
}
},
{
"id": "5c34e2b4-a56a-45f9-a1cc-94788bcb41b0",
"name": "test_perm1",
"type": "resource",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS",
"config": {
"resources": "[\"jpausers\"]",
"applyPolicies": "[\"test_jpa\"]"
}
}
],
"scopes": [
{
"id": "4ee351e6-7095-453a-a4f4-badbc9ec1ba0",
"name": "GET",
"displayName": "GET"
},
{
"id": "9119aab2-75a0-49d1-a076-8d9210c3e457",
"name": "POST",
"displayName": "POST"
}
]
}
When I send a request to my Rest API '/jpausers', it fails with following messages on console:
*19:17:52.044 [http-nio-38080-exec-1] INFO o.k.a.authorization.PolicyEnforcer - Paths provided in configuration.
19:17:52.045 [http-nio-38080-exec-1] DEBUG o.k.a.authorization.PolicyEnforcer - Trying to find resource with uri [/jpausers] for path [/jpausers].
19:17:52.151 [http-nio-38080-exec-1] DEBUG o.k.a.authorization.PolicyEnforcer - Initialization complete. Path configurations:
19:17:52.151 [http-nio-38080-exec-1] DEBUG o.k.a.authorization.PolicyEnforcer - PathConfig{name='null', type='null', path='/jpausers', scopes=[], id='a8f691db-39ef-4b2c-80fb-37224e270f1e', enforcerMode='ENFORCING'}
19:17:52.154 [http-nio-38080-exec-1] DEBUG o.k.a.authorization.PolicyEnforcer - Policy enforcement is enabled. Enforcing policy decisions for path [http://192.168.109.97:38080/jpausers].
19:17:52.156 [http-nio-38080-exec-1] DEBUG o.k.a.a.KeycloakAdapterPolicyEnforcer - Sending challenge
19:17:52.157 [http-nio-38080-exec-1] DEBUG o.k.a.authorization.PolicyEnforcer - Policy enforcement result for path [http://192.168.109.97:38080/jpausers] is : DENIED
19:17:52.157 [http-nio-38080-exec-1] DEBUG o.k.a.authorization.PolicyEnforcer - Returning authorization context with permissions:*
UMA Authorization is disabled. I had first retrieved access token using Openid Connect token API with Password credentials grant type and then I am trying to access my Rest API '/jpausers' with access token.
Can someone help with the issue here ? How do I fix this ? Do I have to enable UMA to make policy enforcer work ?
回答1:
With quick look, I can see your mapping is not complete in application.properties
, you have not mapped your HTTP method to scope you have configured in keycloak. Some thing like this
keycloak.policy-enforcer-config.paths[0].path=/jpausers
keycloak.policy-enforcer-config.paths[0].methods[0].method=GET
keycloak.policy-enforcer-config.paths[0].methods[0].scopes[0]=GET
回答2:
I think you are missing keycloak.securityConstraints[0].securityCollections[0].name= jpausers
来源:https://stackoverflow.com/questions/56636542/how-to-use-keycloak-policy-enforcer-with-spring-boot-application