How to throw an informative exception from AccessDecisionManager that uses voters - java

I have the following situation: my application's authorization mechanism is implemented using Spring security. The central class implements AccessDecisionManager and uses voters (each of which implements AccessDecisionVoter) to decide whether to grant access to some method or not. The algorithm that tallies the votes is custom:
public class PermissionManagerImpl extends AbstractAccessDecisionManager {
public void decide(
Authentication authentication,
Object object,
ConfigAttributeDefinition config) throws AccessDeniedException {
Iterator<?> iter = getDecisionVoters().iterator();
boolean wasDenied = false;
while (iter.hasNext()) {
AccessDecisionVoter voter = (AccessDecisionVoter) iter.next();
int result = voter.vote(authentication, object, config);
switch (result) {
// Some tallying calculations
}
}
if (wasDenied) {
throw new AccessDeniedException("Access is denied");
}
}
}
Upon denying an access to some method, the client of the application is interested in obtaining an informative exception that specifies exactly why the access is denied. This implies passing some information from voters to the decision manager. Unfortunately, the only information the standard AccessDecisionVoter passes back to the decision manager is one of the possible return values (ACCESS_GRANTED, ACCESS_ABSTAIN or ACCESS_DENIED).
What is the best way to do it?
Thanks.

Well, the AccesssDecisionVoter interface actually returns an int in this situation. Granted, the built-in voter implementations always only return one of the three constants you mentioned (and these are what the standard access decision managers check for), but then they don't really have anything extra to return - the RoleVoter for instance will deny access if and only if the principal doesn't have the required role.
Since you're using your own implementations both of the voters and the access decision manager, you have several options available as I see it:
Return other values of integers as some form of error code; treat ACCESS_GRANTED, ACCESS_ABSTAIN and ACCESS_DENIED as their typical values, but treat any other integer as "access denied" with an error code. Ideally have a lookup table of error codes available - essentially a poor man's enum.
Within your voter, return ACCESS_DENIED as usual, and set some publically accessible property (either on the voter object itself or perhaps some statically-accessible field) with the error reason. In your manager, if you get access denied from your custom voter, check the property to get the details.
As above, set an error property within the voter; but ensure that the instance of Authentication being passed in is one of your own custom subclasses that provides a good
location to set/retrieve this information.
Throw an AccessDeniedException (or suitable subclass) from within your voter itself. This is not ideal as it presupposes the logic in the access decision manager; but you could either let this bubble straight up, or if needed catch it within the manager (a custom subclass would definitely be good for this) and rethrow if access really is denied (something similar to what the ProviderManager class does with its lastException variable).
None of these sticks out as the obviously correct and elegant answer, but you should be able to get something workable from whichever one is most appropriate. Since there is no explicit support within the voter framework for communicating reasons (it's a straight boolean response fundamentally) I don't think you can do much better.

Thanks for people who answered.
I think I have found a quite elegant way to do what I wanted and still use the standard voters API. The 2nd parameter to the vote method of AccessDecisionVoter is the secured object. I can create a contract between the decision manager and the voters, that this object is of a specific class/interface that is a wrapper, through which the original secured object can be fetched and also additional information can be added by the voters that deny the access.
I saw a pattern like this in other frameworks as well. This solution has the following advantages over other possible solutions:
The voters can remain stateless, so they can be singletons
The standard interface of the AccessDecisionVoter is used and no new return values are added
The additional information is saved in an object that is discarded automatically because no one uses it after the AbstactDecisionManager's decide method, so no cleanup code is required
Cheers.

Can't you implement AccessDecisionManager directly, without using the voters? You can then throw an AccessDeniedException with the correct information. Maybe RoleVoters are not the right abstraction to use in your case.

Related

Perform multiple operations and commit

A system handles two types of resources. There are write and delete APIs for managing the resources. A client (user) will use a library API to manage these resources. Each resource write (or create) will result in updating a store or a database.
The API would look like:
1) Create Library client. The user will use the returned client to operate on the resources.
MyClient createClient(); //to create the client
2) MyClient interface. Providing operations on a resource
writeResourceType1(id);
deleteResourceType1(id);
writeResourceType2(id);
deleteResourceType2(id);
Some resources are dependent on the other. The user may write them out-of-order (might write a resource before writing its dependent). In order to prevent the system from having an inconsistent state, all changes (resource updates) will be written to a staging location. The changes will be written to the actual store only when the user indicates he/she has written everything.
This means I would need a commit kind of method in the above MyClient interface. So, access pattern will look like
Client client = provider.createClient();
..
client.writeResourceType1(..)
client.writeResourceType1(..)
client.deleteResourceType2(..)
client.commit(); //<----
I'm not comfortable having the commit API in the MyClient interface. I feel it is polluting it and a wrong it is a wrong level of abstraction.
Is there a better way to handle this?
Another option I thought of is getting all the updates as part of a single call. This API would act as a Batch API
writeOrDelete(List<Operations> writeAndDeleteOpsForAllResources)
The downside of this is this the user has to combine all the operations on their end to call this. This is also stuffing too much into a single call. So, I'm not inclined to this approach.
While both ways that you've presented can be viable options, the thing is that at some point in time, the user must somehow say: "Ok, these are are my changes, take them all or leave them". This is exactly what commit is IMO.
And this alone makes necessary some kind of call that must present in the API.
In the first approach that you've presented its obviously explicit, and is done with commit method.
In the second approach its rather implicit and is determined by the content of the list that you pass into writeOrDelete method.
So in my understanding, commit must exist somehow, but the question is how do you make it less "annoying" :)
Here are couple of tricks:
Trick 1: Builder / DSL
interface MyBuilder {
MyBuilder addResourceType1(id);
MyBuilder addResourceType2(id);
MyBuilder deleteResourceType1/2...();
BatchRequest build();
}
interface MyClient {
BatchExecutionResult executeBatchRequest(BatchRequest req);
}
This method is more or less like the second method, however it has a clear way of "adding resources". A single point of creation (pretty much like MyClient not, just I believe that eventually it will have more methods, so maybe its a good idea to separate. As you stated: "I'm not comfortable having the commit API in the MyClient interface. I feel it is polluting it and a wrong it is a wrong level of abstraction")
Additional argument for this approach is that now you know that there is a builder and its an "abstraction to go" in your code that uses this, you don't have to think about passing a reference to the list, think about what happens if someone calls stuff like clear() on this list, and so on and so forth. The builder has a precisely defined API of what can be done.
In terms of creating the builder:
You can go with something like Static Utility class or even add a method to MyClient:
// option1
public class MyClientDSL {
private MyClientDSL {}
public static MyBuilder createBuilder();
}
// option 2
public interface MyClient {
MyBuilder newBuilder();
}
References to this approach: JOOQ (they have DSL like this), OkHttp that have builders for Http Requests, Bodies and so forth (decoupled from the OkHttpClient itself).
Trick 2: Providing an execution code block
Now this can be tricky to implement depending on what kind of environment do you run in,
but basically an idea is borrowed from Spring:
In order to guarantee a transaction while working with databases they provide a special annotation #Transactional that while placed on the methods basically says: "everything inside the method is running in transaction, I'll commit it by myself so that the user won't deal with transactions/commits at all. I'll also roll back upon exception"
So in code it looks like:
class MyBusinessService {
private MyClient myClient; // injected
#Transactional
public void doSomething() {
myClient.addResourceType1();
...
myClient.addResourceType2();
...
}
}
Under the hood they should maintain ThreadLocals to make this possible in multithreaded environment, but the point is that the API is clean. The method commit might exist but probably won't be used at the most of the cases, leaving alone the really sophisticated scenarios where the user might really "need" this fine-grained control.
If you use spring/ any other containter that manages your code, you can integrate it with spring (the technical way of doing this is out of scope of this question, but you get the idea).
If not, you can provide the most simplistic way of it:
public class MyClientCommitableBlock {
public static <T> T executeInTransaction(CodeBlock<T> someBlock)
builder) {
MyBuilder builder = create...;
T result = codeBlock(builder);
// build the request, execute and commit
return result;
}
}
Here is how it looks:
static import MyClientCommitableBlock.*;
public static void main() {
Integer result = executeInTransaction(builder -> {
builder.addResourceType1();
...
return 42;
});
}
// or using method reference:
class Bar {
Integer foo() {
return executeInTransaction(this::bar);
}
private Integer bar(MyBuilder builder) {
....
}
}
In this approach a builder while still defining precisely a set of APIs might not have an "explicit" commit method exposed to the end user. Instead it can have some "package private" method to be used from within the MyClientCommitableBlock class
Try if this suits you
Let us have a flag in staging table with column named status
Status Column values
New : Record inserted by user
ReadyForProcessing : Records ready for processing
Completed : Records processed and updated in Actual Store
Add this below method instead of commit(), and once user invokes this method/service, pick up the records which are for this user and which are in status: New and post it into the Actual Store from the staging location
client.userUpdateCompleted();
There is another option as well let us take out the client intervention by giving client.commit(); or client.userUpdateCompleted(); and instead we can have a batch process using Scheduler which runs at specific intervals which scans the Staging Table and populates the meaningful and user update completed records into the Actual Store

Single class file on server memory using Spring causing problems

I don't quite know how to explain the situation, I will try to be as clear as possible.
I am currently writing a web-application, using Spring to manage the beans. Obviously, more than one people will use this application. Each user has a set of data related to himself. My problem comes with some poor design I introduced when I just entered the development field. Here is the case:
#Component
public class ServiceClass implements IService {
#Autowired
private Dependency firstDependency;
#Autowired
private UsefulObject secondDependency;
private DataSet dataSet; // THIS LINE IS IMPORTANT
public void entryPoint(String arg1, int arg2, Structure arg3) {
/* Query data from a database specific from the project (not SQL
oriented. I absolutely need this information to keep going. */
dataSet = gatherDataSet(String ar1);
/* Treat the data */
subMethodOne(arg1);
subMethodTwo(arg2);
subMethodThree(arg3);
}
private subMethodOne(String arg1) {
// Do some things with arg1, whatever
subSubMethod(arg1);
}
private subSubMethod(String arg1) {
/* Use the DataSet previously gathered */
dataSet.whateverDoing();
}
... // Functions calling sub-methods, using the DataSet;
As every user would have a different dataSet, I thought it would be good to call it at the beginning of every call to my service. In the same way, as is it used very deep in the call hierarchy, I thought it would be a good idea to store it as an attribute.
The problem I encounter is that, when two users are going through this service nearly simultaneously, I have a cross-data issue. The following happens:
First user comes in, calls gatherDataSet.
Second user comes in, calls gatherDataSet. First user is still treating !
First user still uses the dataSet object, which was overrid by Second user.
Basically, the data first user makes use of become false, because he uses data from the second user, which came in short after him.
My questions are the following:
Are there design pattern / methods to avoid this kind of behavior ?
Can you configure Spring so that he uses two instances fo two users (and so on), to avoid this kinf od problems ?
Bonus: (Kind of unrelated) How to implement a very large data mapper ?
Object member variables (fields) are stored on the heap along with the object. Therefore, if two threads call a method on the same object instance and this method updates object member variables, the method is not thread safe.
However, If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread, the use of that resource is thread safe.
With this in mind, change your design. https://books.google.co.in/books?isbn=0132702258 is a must read book for coming up with good java based software design
More stackoverflow links: Why are local variables thread safe in Java , Instance methods and thread-safety of instance variables
Spring promotes singleton pattern and (it is the default bean scope). Spring configuration for having two service class objects for two different users is called prototype bean scoping, but should be avoided as far as possible.
Consider the usage of in-memory Map or an external no-sql datastore or an external relational database
Can you configure Spring so that he uses two instances fo two users (and so on), to avoid this kinf od problems ?
You already mentioned correctly, that the design decisions you took are flawed. But to answer your specific question, which should get your use-case to work correctly, but at a impact to performance cost:
You can set spring beans to various scopes (relevant for your usecase: prototype / request or session), which will modify when spring beans get instanced. The default behaviour is one bean per spring container (singleton), hence the concurrency issues. See https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html
The easiest solution is simply to not store the dataset in a class field.
Instead, store the dataset in a local variable and pass it as an argument to other functions, this way there will not be any concurrency problems, as each call stack will have it's own instance.
Example:
public void entryPoint(String arg1, int arg2, Structure arg3) {
// Store the dataset in a local variable, avoiding concurrency problems
Dataset dataSet = gatherDataSet(String ar1);
// Treat the data passing dataset as an argument
subMethodOne(arg1, dataset);
subMethodTwo(arg2, dataset);
subMethodThree(arg3, dataset);
}
Use synchronized modifier for it.
As "Synchronization plays a key role in applications where multiple threads tend to share the same resources, especially if these resources must keep some kind of sensitive state where manipulations done by multiple threads at the same time could lead the resource to become in an inconsistent state."
public void someMethod() {
synchronized (object) {
// A thread that is executing this code section
// has acquired object intrinsic lock.
// Only a single thread may execute this
// code section at a given time.
}
}

domain driven design depends on static methods?

I have been reading a lot online/offline about where to put validation and business rules in general for domain driven design. What I could not understand is how can an entity provides methods that does validation and business rules without resorting to static methods or having a service? This is especially important for cases where the domain object does not need to be instantiate yet, but we need to validate a value that will eventually used to set the object's attribute.
I noticed blog postings such as http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/ relies on .NET's specific extension method, which is not available in programming languages such as Java. I personally don't like static methods are they cannot be overridden and hard to test.
Is there anyway I could do this without static methods or having to instantiate an unnecessary domain object just to use its validation and business rules methods. If not, does that mean domain driven design is very dependent on static methods?
Thanks
Use ValueObjects Not Entity.
In the registration case, a UserName value object could be introduced. Create a Username object when receiving the registration. Implement validation in the constructor of the UserName.
See this question and this presentation for more detail.
Edit1:
1.How to handle cases where different validation rules applied for different context. For example: The username must not have numbers for certain type of members, but it is required for other types of members?
Maybe different factory methods could do that. like UserName.forGoldenCardMember(...) or UserName.forPlainMember(...). Or make MemberType (a hierachy maybe) to validate UserName.
Another alternative solution is use AggregateFactory(AccountFactory in this case).
2.Is constructor the only place to put the validation code? I did read online about two points of view: an object must always be valid vs. not always. Both present good arguments, but any other approach?
I prefer valid approach personally. Passing an maybe invalid value object harms encapsulabilty.
Edit2:
Require
a) validation business rule based on context(different username rules for member types)
b) keep validating all business rules even if one of them fail
Stick with Single responsibility principle by using Value Object(MemberType this case).
AggregateFactory could be introduced to ease the application layer(coarser granularity).
class AccoutFactory {
Account registerWith(Username username, MemberType type, ....) {
List<String> errors = new ArrayList<String>();
errors.addAll(type.listErrorsWith(username));
errors.add(//other error report...
if (CollectionUtils.isEmpty(errors)) {
return new Account(username,....);
} else {
throw new CannotRegisterAccountException(errors);
}
}
}
Edit3:
For questions in the comments
a) Shouldn't the Username object be the one that has a method that returns the error like
the listErrorsWith()? After all, it is the username that has different rules for different member type?
We could check this question from another perspective: MemberTypes have different rules for username. This may replace if/else block in the Username.listErrosWith(String, MemeberType) with polymorphism;
b) If we have the method in the MemberType, the knowledge will not be encapsulated in the Username.Also, we are talking about making sure Username is always valid.
We could define the validity of Username without MemberType rules. Let’s say "hippoom#stackoverflow.com" is a valid username, it is a good candidate for GoldenCard member but not good for SilverCard member.
c) I still can't see how performing validation that returns a list of errors without getting the list from exception thrown by the constructor or static method. Both does not look ideal IMHO.
Yes, the signature of listErrorsWith():List looks weired, I'd rather use validate(username) with no returning value(throw exception when fails). But this will force the cilent to catch every validation step to run validations all at once.
If you decided to use DDD in your application you need to build more complex solution. I agree with #Hippoom, you shouldn't use Entity for this purpose.
I would suggest this solution:
DTO -> Service Layer (ValidationService -> Converter) -> Persistence Layer (Repository)
Some explanation:
When you received DTO from client side with all necessary parameters, you should validate it in you service layer (e.g. Use another service like ValidationService) which can throw exception if something wrong. If all Ok, you can create Entity from your DTO in Converter and persist it in Repository.
If you want flexible solution for ValidationService I'd suggest Drools

getting information about the principal

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.

Spring Security - how can I ask invoke access control methods directly?

There's a lot of documentation on how to use jsp tags, aop, annotations, the application context, and all of these sorts of things... but how do I access the access control methods directly? What class do I need to create, if any? Is there hidden bean I need to be aware of? It doesn't seem like SecurityContextHolder is the right place to look.
What I'd like to do is something like this:
if(springSecurityObject.isAuthorized("hasAnyRole('DIRECTOR', 'ADMIN')")) {
// ... do something
}
Or even better:
if(springSecurityObject.hasAnyRole('DIRECTOR', 'ADMIN')) {
// ... do something
}
Thanks!
EDIT: It seems like the spring security people are using the granted authorities on the user object itself:
https://fisheye.springsource.org/browse/spring-security/taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java?r=fc399af136492c6c37cdddca6d44e5fe57f69680
I think it would probably have been helpful if they abstracted out a ton of this code and put it into a nice set of classes instead - something that both the tag libraries and actual users could use. They are private helper methods after all... a common smell that they should probably exist in some classes instead.
Since they are doing the plumbing manually, I guess I have to assume that what I want doesn't exist.
The only thing I can think of is invoking your UserDetailsService manually, calling getAuthorities() on the returned Authentication and then calling contains() or containsAll() on the returned collection.
So you'd have something like:
final UserDetails jimmyDetails = myDetailsService.loadUserByUsername("Jimmy");
final Collection<GrantedAuthority> jimmyAuthorities = jimmyDetails.getAuthorities();
// make it a Collection<String> by iterating and calling .getAuthority()
plainAuthorities.contains("ROLE_YOU_NEED_TO_CHECK_FOR");
Writing your own helper methods that do this would not be too hard, although I agree that having them in the API would be nice.

Categories