Does Spring Security Acl support class-level permissions? For example, let's suppose I have an Asset class, and I want to allow read permissions to all instances of the Asset class to any user with role ROLE_USER. As long as I could see, ObjectIdentityImpl only accepts object instances.
Thanks
The Spring Security ACL is not really handy for this. I would suggest you use a pre-authorize annotation instead:
#PreAuthorize("hasRole('ROLE_USER')")
public List<Asset> getAllAssets();
Make sure you have pre- and post-annotations enabled in your configuration.
The org.springframework.security.acls.model.ObjectIdentity is one of the core Spring Security ACL interfaces representing the identity of an individual domain object to secure. It imposes type and identifier properties. If you need class level permissions, you can use e.g. "Class" as a type and actual class name as an identifier (e.g. "Asset" or "my.package.Asset").
Depending on a concrete scenario, it may be also needed to implement org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy and org.springframework.security.acls.model.ObjectIdentityGenerator interfaces accordingly.
Related
In a Java Spring Boot DDD project we have several APIs exposed.
Now for only one of these APIs we need that the "Token" entity contains one more attribute: "Locales".
In use cases that use "Token" without "Locales" I would not want the getter of that new attribute to be accessible.
For this I am considering two options:
Add "Locales" to the "Token" entity and also another "Type" attribute (an Enum)
that, depending on whether it is of one type or another, when
accessing the "Locales" getter, returns the elements or an
Optional.Empty (or an exception). This way only the use cases that are
for the "LocalizedToken" will get the "Locales", but in my
opinion the interface is less clear and more errors could happen when
using attributes that are not really used in all APIs.
Extend "Token" with a "LocalizedToken" entity and make use cases that use each
exposed API only have access to the type it needs. For example, with
generics, create use case: CreateTokens<T extends Token>. This
option looks cleaner but requires a lot more modifications, as these
generics are spread throughout the domain, repositories, etc.
In your opinion, which is the best approach? Or any other suggestion?
Thanks!
I have several methods for a restful webservice with this signature
public #ResponseBody SomeObject someMethodSignature(Principal principal){
given that it's legacy code, is there a way to get other information from principal (Principal is an interface from java.security with only one useful method getName()) other than the name without the need to pass anything else to the method as parameter? Like permissions and stuff like that?
thanks
If you are using Spring Security as you say, then the Principal object should be an instance of Spring Security's Authentication interface. See the API Javadoc.
This means you can cast the principal and invoke the getAuthorities method on it, like so
((Authentication)principal).getAuthorities();
Note that other security-related methods of HttpServletRequest are also overridden, so you could also change your method to take a request object and invoke, for example the isUserInRole method if that would suit your requirements. This would avoid you having to add any dependency on Spring Security in your classes.
The Principal only carries the name (usualy the login returned by the Authentication infrastructure) there isn't much more info to get. However, you check the JAAS reference you will see that there are other classes that carry info like the AuthPermission that is used to hold names that identify stuff your Principal is authorized to use and, therefore, we use this to activate (typically) menu options.
The interface Principal doesn't contain many information, but implementations may. As in Tomcat and Weblogic, you can find some more interesting information.
I am struggling to understand how to take advantage/use the MBeanInfo (and related MBeanAttributeInfo, ModelMBeanInfo etc.) and related to it Descriptors.
As far as I understand MBean*Info is simply like a Class object containing information on available methods/attributes/constructors etc. Also, as far as I see it, this information is immutable and generated for us in the process of MBeanServer.registerMBean or using StandardMBean class (maybe the MBeanServer actually uses the StandardMbean class?) which uses reflection to generate this information. Is this more or less correct?
Also, I guess there exist a concept of a ModelMBean, to which we are able to pass our own MBeanInfo programmatically. What is the point of doing so if the same can be achieved via a StandardMbean with reflection?
Finally, Descriptors were put in place to allow users to extend information on the mbeans by providing (name,value) pairs in the form of descriptor. This can be attached to any of the MBean*Info classes (constructor, attribute, operation etc.) However, it can be attached during the construction of the Info object, as it is immutable. Therefore, using StandardMbean, that generates this info on its own, there is no way to inject extra information, as the descriptor we get from the MBeanInfo is immutable too... Am I missing something here? What would be the easy way to add extra information to descriptors of contructors/fields/methods on a MBean?
... this information is immutable and generated for us in the process of MBeanServer.registerMBean or using StandardMBean class ... which uses reflection to generate this information. Is this more or less correct?
Yes. The information is built about the bean and then registered with the server to it can be published to the clients. Not sure if the MBeanServer creates a StandardMBean under the covers.
What is the point of doing so if the same can be achieved via a StandardMbean with reflection?
The MBean*Info classes allow you to programmatically publish a JMX mapping to a concrete type without the need of the interface/impl. This allows external packages such as Spring to be able to detect and publish JMX beans that call through to discovered beans with special #ManagedResource attributes.
This is also how my SimpleJMX package is able to publish beans with its annotations. All you need to do is add the following to one of your classes and SimpleJMX programmatically creates MbeanInfo instances which describe the class. You do not need to define a JMX interface/impl yourself.
#JmxResource(description = "Lookup cache", domainName = "j256")
public class LookupCache {
#JmxAttributeField(description = "Number of hits in the cache")
private int hitCount;
...
Internally, SimpleJMX creates a instance of its class that implements javax.management.DynamicMBean. That interface is what exposes the get, set, invoke action methods. It also returns the MBeanInfo which describes the class for JMX publishing.
Am I missing something here? What would be the easy way to add extra information to descriptors of contructors/fields/methods on a MBean?
I don't use Descriptors with SimpleJMX so I don't know how they are used. They look to be meta information about a method or parameter such as deprecated, defaultValue, etc.. This seems to be static information so immutable as well.
I'd like to know the answer to this simple question.
When I create an entity object and I want to restrict a setting of an attribute (for example I don't want to allow anyone to set an integer value less then 1 to an attribute), should I implement it in the setter of this attribute or should I check this restriction latter in a class that handles these objects ? Generally, can I implement getters and setters however I want as long as my getters return and setters set attributes ?
I know there are some rules (code conventions) in java, so I don't want to break any of them.
Thanks in advance, hope that my question is clear enough and sorry for any grammar mistakes I might have made :/ .
Yes getters/setters are useful for that.
for example:
public void setAge(int age){
if(age < 0){
throw new IllegalArgumentException("Invalid age : " + age);
//or if you don't want to throw an exception you can handle it otherways too
}
}
You can also use Java-EE's Bean Validators for this
public class Person{
#Min(value = 0)
#Max(value = 99)
private Integer age;
//some other code
}
My preferred approach is to use JSR 303 (Bean Validation API) to ensure that the properties of the class are valid.
It is quite alright to perform validation in setters, but this is not always a desirable approach. There is the potential of mixing the needs of several contexts that are not related to each other. For example, some of your properties must never be set from the user-interface, and would instead be computed by a service, before being persisted. In such an event, it is not desirable to have this logic inside a setter, for you would need to know the context in which the setter is being invoked; you'll need to apply different rules in your UI layer and in your persistence layer. JSR 303 allows you to separate these concerns using validation groups, so that your UI validation group is different from your persistence validation group.
In JPA 2.0, when you annotate your class using constraints that are evaluated by a JSR 303 validator, your persistence provider can automatically evaluate these constraints on the PrePersist, PreUpdate and PreRemove (typically not done; see below) lifecycle events of entities. To perform validation of entities in your JPA provider, you must specify either the validation-mode element or the javax.persistence.validation.mode property in your persistence.xml file; the values must be either AUTO (the default) or CALLBACK (and not NONE).
The presence of a Bean Validation provider is sufficient to ensure that validation occurs on JPA entity lifecycle events, as the default value is AUTO. You get this by default, in a Java EE 6 application server; Glassfish uses the RI implementation of JSR 303 which is Hibernate Validator, and it works quite well with EclipseLink as well.
The CALLBACK mode will allow you to override the validation groups that are to be applied when the lifecycle events are triggered. By default, the default Bean validation group (Default) will be validated for update and persist events; the remove event does not involve any validation. The CALLBACK mode allows you to specify a different validation group for these events, using the properties javax.persistence.validation.group.pre-persist, javax.persistence.validation.group.pre-update and javax.persistence.validation.group.pre-remove.
Do keep in mind that JSR 303 validation can be used outside a Java EE container, although the Bean Validation API documentation link that I've posted above is from the Java EE 6 API documentation.
This is the goal of getters and setters.
If we cannot add some behavior in these methods, well... why don't we use public attributes ?
From my understanding of your question, it pretty much related to encapsulation OO principle.
You can have a look at this article: http://www.tutorialspoint.com/java/java_encapsulation.htm
Getters and setters are great for adding the restrictions, just like Jigar Joshi has in his answer. That way you get feedback immediately and can handle the problem when it is introduced.
Another solution would be to use object validation (something like a JSR-303 implementation) which would allow you to annotate the field with a min and max values. Something like
#Min(value=1)
private int myvalue;
Then you can validate the entire object in one go and get all messages if you have other constrained fields. This is obviously not useful everywhere, but if it fits your need it is an option.
Finally, when you say "entity" I think of something stored in a database or related to ORM tools. If that is the case, you will want to be careful with what you do in your getter. For instance, if you do lazy initialization in the getter some ORM suppliers will mark the entity as dirty and attempt to flush it to the database possibly causing an unintended write.
I'm stuck with validation in my current use case.
My app has standard structure (WEB <-> EJB3 Services <-> EJB3 DAO <-> DB).
I have an entity which has validation annotations applied to it.
#Entity
class PhoneNumber {
...
private NumberType numberType;
}
where
enum NumberType {
FIXED,
MOBILE,
ANY
}
Now I have new validation rule to be applied. On PhoneNumber update there should be not possible to change NumberType to ANY if it was set previously to either FIXED or MOBILE.
My Bean Validation rules are checked just before db operations, and the rule above should be applied in service layer (at least I think so) to have a DB access to get previous entity version to compare.
But without having bean not yet validated I'm forced to check manually if e.g. numberType is not null.
Can you please provide me some advices or general rules how to deal with more complex busines validations (not only checking single field's values in isolation) when using Bean Validation?
I don't think Bean Validation is the right solution for implementing this kind of business logic.
Instead you could implement this check in the setNumberType() method of the PhoneNumber entity. There you have the old value at hand and compared to an implementation in the service layer there is no chance to perform an illegal state transition by circumventing (accidentally or intentionally) the service implementing the check.
Here you can find a good description of how to write a custom validator which can do "cross-field" validation.