HI,
As per the document I setup REST API ‘add on’.
Then created new entity…
Updated application.properties file with jmix.rest.anonymousUrlPatterns=/rest/entities/Country
And also set up initAnonymousUser() with rest-minimal role .
Still I getting issue while hitting REST API - Reading forbidden
Hi
Have you assigned the rest API role to the user?
Yes, In DatabaseUserRepository I updated initAnonymousUser() with rest-minimal role.
I see you are trying to access Entity Country, did you also give REST user access to this entity?
I am trying to set AnonymousUser access.Is there any way to setup Anonymous user access to on Entity. Can you please let us know the steps
Apart from setting the jmix.rest.anonymousUrlPatterns=/rest/entities/Country
property, you should give the anonymous user rights to the Country
entity. For example, create a resource role:
package com.company.demo.security;
import com.company.demo.entity.Country;
import io.jmix.security.model.EntityAttributePolicyAction;
import io.jmix.security.model.EntityPolicyAction;
import io.jmix.security.role.annotation.EntityAttributePolicy;
import io.jmix.security.role.annotation.EntityPolicy;
import io.jmix.security.role.annotation.ResourceRole;
@ResourceRole(name = "AnonymousRestRole", code = AnonymousRestRole.CODE, scope = "API")
public interface AnonymousRestRole {
String CODE = "anonymous-rest-role";
@EntityAttributePolicy(entityClass = Country.class, attributes = "*", action = EntityAttributePolicyAction.VIEW)
@EntityPolicy(entityClass = Country.class, actions = EntityPolicyAction.READ)
void country();
}
The assign it to the anonymous
user:
@Primary
@Component("UserRepository")
public class DatabaseUserRepository extends AbstractDatabaseUserRepository<User> {
// ...
@Override
protected void initAnonymousUser(User anonymousUser) {
Collection<GrantedAuthority> authorities = getGrantedAuthoritiesBuilder()
.addResourceRole(AnonymousRestRole.CODE)
.build();
anonymousUser.setAuthorities(authorities);
}
}
Hi, the example provided, as the one reported in the documentation, isn’t complete about the class DatabaseUserRepository.
Can you provide a working example, replacing the … dots with the missing part, and giving some hints on the package required for this class?
It would be very helpful.
To be more clear, I’m trying to update an entity, with the following PUT call:
http://localhost:8080/rest/entities/PTT_JobLog/5
Here is the configuration of application.properties, you can find duplicated properties, because it is not clear which property is used:
jmix.rest.anonymousUrlPatterns=/rest/entities/PTT_JobLog
jmix.rest.anonymous-url-patterns=/rest/entities/PTT_JobLog
jmix.rest.anonymousEnabled=true
jmix.rest.anonymous-enabled=true
Here is the entity definition. I understood that the REST endpoint uses the entity name, not the class name:
@JmixEntity
@Table(name="job_log_entries", schema="pto")
@Entity(name = "PTT_JobLog")
public class JobLog {
....
I have created an annotated interface to add the UPDATE permission on all the attributes of the entity:
@ResourceRole(name = "AnonymousRestRole", code = AnonymousRestRole.CODE, scope = "API")
public interface AnonymousRestRole {
String CODE = "anonymous-rest-role";
@EntityAttributePolicy(entityClass = JobLog.class,
attributes = "*",
action = EntityAttributePolicyAction.MODIFY)
@EntityPolicy(entityClass = JobLog.class,
actions = EntityPolicyAction.UPDATE)
void jobLog();
}
The void method is named as the class name, with the first letter in lowercase.
Finally I have updated the DatabaseUserRepository in order to implement the required methods:
@Primary
@Component("PTT_UserRepository")
public class DatabaseUserRepository extends AbstractDatabaseUserRepository<User> {
@Override
protected Class<User> getUserClass() {
return User.class;
}
@Override
protected void initSystemUser(User systemUser) {
Collection<GrantedAuthority> authorities = getGrantedAuthoritiesBuilder()
.addResourceRole(FullAccessRole.CODE)
.build();
systemUser.setAuthorities(authorities);
}
@Override
protected void initAnonymousUser(User anonymousUser) {
Collection<GrantedAuthority> authorities = getGrantedAuthoritiesBuilder()
.addResourceRole(AnonymousRestRole.CODE)
.addResourceRole(RestMinimalRole.CODE)
.build();
anonymousUser.setAuthorities(authorities);
}
}
Executing the PUT, I receive the following error:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
It seems that the anonymous configuration is ignored. I tried also a call using OAuth authentication and a named user, and everything works.
When you see the “Full authentication is required to access this resource” it most probably means that the URL of the request doesn’t match the patterns specified for anonymous access.
In your case, the following patterns are required (because the PUT request has id part):
jmix.rest.anonymous-url-patterns=/rest/entities/PTT_JobLog,\
/rest/entities/PTT_JobLog/*
Also, you need the READ permission for the entity (it isn’t assumed when you enable UPDATE):
@EntityAttributePolicy(entityClass = JobLog.class,
attributes = "*",
action = EntityAttributePolicyAction.MODIFY)
@EntityPolicy(entityClass = JobLog.class,
actions = {EntityPolicyAction.READ, EntityPolicyAction.UPDATE})
void jobLog();
Many thanks. The missing part was the final ‘/*’ in the allowed path. Also the clarification on READ permission was very helpful.