#Check does not work when action is called from other action - security

I have an action in Controller that is secured with #Check annotation.
#With(Secure.class)
public class Application extends Controller {
#Check("admin")
public static void securedMethod() {
//secured code
}
When I call this action from browser, it calls boolean check(String profile) from Security class. But when I call this action from another action:
Application.securedMethod();
it just calls secured code, omitting Security.check() call. I thought, #Check should not allow execution of securedMethod() unless Security.check() return true. Any ideas how can I make it behave like this?

The reason is the way the Secure controller works. The #Check annotation is only validated at the beginning of a request, via a method annotated with #Before. You can see how it's done in the sample code.
Usually it should not be a problem as you should not call a method with bigger restrictions from a method with less security restrictions (as it may lead to security issues). In your case you should validate the workflow you are using, as you may want to avoid that call.

Related

What is the use of #DeclareRoles in JakartaEE 8+ security?

In the past I always implemented authorization with some very proprietary code having an #ApplicationScoped bean with methods like isUserInAnyOfTheseRoles(String... roles), which executes appropriate database queries. I always had to call these methods at the start of a protected EJB method/REST resource, making an if-statement and possibly throwing a "NotAuthorized"-exception.
For the future I consider using JakartaEE's security mechanisms so I am reading into it. I have a problem understanding the use of the #javax.annotation.security.DeclareRoles annotation.
Amongst others I read SO answer to ejb Security questions regarding Roles and Authentication. There it is said that
The #DeclareRoles annotation on the other hand is merely used to declare a list of roles; [...]. The EJB container does not require knowledge of these roles to enforce access control checks on business methods of an EJB; instead, the bean provider/developer may use these roles in isCallerInRole tests to ensure programmatic security.
If I understand it right I need to declare the roles I use programmatically with javax.security.enterprise.SecurityContext#isCallerInRole(String). So my class might look like the following.
#DeclareRoles({"ADD_ENTITY", "DELETE_ENTITY", "UPDATE_ENTITY", "SEE_ENTITY", "SEE_ENTITY_DETAILS", "SEE_RESTRICTED_DATA", "MERGE_ENTITY", "ATTACH_METADATA"})
public class PersonService {
#Inject SecurityContext ctx;
#RolesAllowed({"SEE_ENTITY"})
public Person getPerson(long id) {
if(ctx.isCallerInRole("SEE_ENTITY_DETAILS") {...}
else if(ctx.isCallerInRole("SEE_RESTRICTED_DATA") {...}
else {...}
}
...
}
1st question:
Now if I have another class, do I need to declare all the roles again?
#DeclareRoles({"ADD_ENTITY", "DELETE_ENTITY", "UPDATE_ENTITY", "SEE_ENTITY", "SEE_ENTITY_DETAILS", "SEE_RESTRICTED_DATA", "MERGE_ENTITY", "ATTACH_METADATA"})
public class CompanyService {
#Inject SecurityContext ctx;
#RolesAllowed({"SEE_ENTITY"})
public Company geCompany(long id) {
if(ctx.isCallerInRole("SEE_ENTITY_DETAILS") {...}
else {...}
}
...
}
In the mentioned answer the EJB spec is quoted with
The DeclareRoles annotation is specified on a bean class, where it serves to declare roles that may be tested by calling isCallerInRole [...]
2nd question: Is it correct that this declaration is only used by the programmatically access and not for the declarative part? So that I do not need to declare any roles if I only use the annotation #RolesAllowed.
3rd question: What is the reason for this "duplication"? For me it is just annoying to declare the roles (by the way I do have plenty of roles in my application) twice. I do not see the point in doing so, after all it is just a string. I need to write a custom javax.security.enterprise.identitystore.IdentityStore to map roles to a user. Aligning these roles in every EJB seems to be unnecessary.
4th question: In a comment to a similar question (Define #DeclareRoles annotation programmatically) I interpret that #DeclareRoles might by a ancient relic and is no longer needed if an IdentityStore is used. If that would be true, it would make things a little bit clearer to me.
Sorry for the four questions in one post, but it all tangled together somehow. Basically it is question 3 that haunts me the most.

FakeItEasy in C# on a servicereference

I have a servicereference with a method I need to use in a test.
The servicereference class is defined as:
public class MyServiceReference : Clientbase<IMyServiceReference>, IMyServiceReference
{
public MyServiceReference()
{
}
..... methods is then defined
}
From my testmethod I have tried both
private MyServiceReference myServiceReferenceFake = A.Fake<MyServiceReference>();
// And
private MyServiceReference myServiceReference = new MyServiceReference();
For both of these is crashes in the constructor with the message:
System.InvalidOperationException: Could not find default endpoint element that references contract.
All I need is to have a callto definition from a method in that class.
How can this be solved?
I've no experience with Clientbase, which I assume to be a System.ServiceModel.ClientBase<TChannel>,but I can make some general comments.
Since you tried first to fake a MyServiceReference, I'll assume that you're not testing that class, and you want to use it as a collaborator for the system under test. In that case, your best bet is to try faking IMyServiceReference. interfaces are very easy to fake, since they don't bring along any behaviour or baggage like faking a class does.
If you feel you really need to fake a MyServiceReference, then we have to contend with the fact that FakeItEasy will eventually call MyServiceReference(), which will call ClientBase<IMyServiceReference>(), whose documentation says
Initializes a new instance of the ClientBase<TChannel> class using the default target endpoint from the application configuration file.
Based on the error you reported, I assume that the application configuration file is not found or does not include the configuration required to create a MyServiceReference. The fact that you get the same error when you just try to instantiate a MyServiceReference directly strengthens my belief.
So I think your paths forward are either to try faking IMyServiceReference or to provide the configuration that ClientBase<IMyServiceReference> needs.

Spock- Capture method arguments in private method call of class under test

I am trying to test my Service class below
#Service
#RequiredArgsConstructor(onConstructor = #__(#Autowired))
public class TaskTemplateService {
#NonNull
TaskTemplateRepository taskTemplateRepository;
public void doStuff() {
List<MyObject> list;
doOtherStuff(list)
}
private void doOtherStuff(List <MyObject>) {
//do stuff
}
}
When I am testing the real TaskTemplate, how can I capture what is passed to doOtherStuff?
You cannot and why would you?
Good testing means to specify the behaviour of a unit's public interface. Private methods ought to be covered via testing this way indirectly. If this is not possible then either you have dead, unreachable code or a design problem and should refactor.
BTW, the technical reason that you cannot mock/stub private methods is that most mocking tools, also the built-in feature of Spock, use dynamic proxies (DP) in order to implement mocking. DP technically are subclasses, but private methods can never be extended or even seen by subclasses or being called by them or from other classes, hence the term "private". Consequently, a mock subclass cannot check interactions with private methods.
How exactly you ought to redesign your class in order to make it testable really depends on why you want to "capture" the method argument, as you say. Do you need to replace it by a mock? Do you need to modify or verify the content of the original object?
If the object has a central meaning and you need to replace or verify it, why not make it injectable instead of creating it as a local variable, hermetically sealing it off from the outside world and making it untestable?
Or maybe in your case you could make the private method protected or package-scoped in order to make it testable. Then at least a mock could be created for it and you could capture the argument or stub the result.
I am mostly speculating here because the answer really depends on what is behind //do stuff, i.e. the very information you are hiding in your sample code.

Connecting the dots with DDD

I have read Evans, Nilsson and McCarthy, amongst others, and understand the concepts and reasoning behind a domain driven design; however, I'm finding it difficult to put all of these together in a real-world application. The lack of complete examples has left me scratching my head. I've found a lot of frameworks and simple examples but nothing so far that really demonstrates how to build a real business application following a DDD.
Using the typical order management system as an example, take the case of order cancellation. In my design I can see an OrderCancellationService with a CancelOrder method which accepts the order # and a reason as parameters. It then has to perform the following 'steps':
Verify that the current user has the necessary permission to cancel an Order
Retrieve the Order entity with the specified order # from the OrderRepository
Verify that the Order may be canceled (should the service interrogate the state of the Order to evaluate the rules or should the Order have a CanCancel property that encapsulates the rules?)
Update the state of the Order entity by calling Order.Cancel(reason)
Persist the updated Order to the data store
Contact the CreditCardService to revert any credit card charges that have already been processed
Add an audit entry for the operation
Of course, all of this should happen in a transaction and none of the operations should be allowed to occur independently. What I mean is, I must revert the credit card transaction if I cancel the order, I cannot cancel and not perform this step. This, imo, suggests better encapsulation but I don't want to have a dependency on the CreditCardService in my domain object (Order), so it seems like this is the responsibility of the domain service.
I am looking for someone to show me code examples how this could/should be "assembled". The thought-process behind the code would be helpful in getting me to connect all of the dots for myself. Thx!
Your domain service may look like this. Note that we want to keep as much logic as possible in the entities, keeping the domain service thin. Also note that there is no direct dependency on credit card or auditor implementation (DIP). We only depend on interfaces that are defined in our domain code. The implementation can later be injected in the application layer. Application layer would also be responsible for finding Order by number and, more importantly, for wrapping 'Cancel' call in a transaction (rolling back on exceptions).
class OrderCancellationService {
private readonly ICreditCardGateway _creditCardGateway;
private readonly IAuditor _auditor;
public OrderCancellationService(
ICreditCardGateway creditCardGateway,
IAuditor auditor) {
if (creditCardGateway == null) {
throw new ArgumentNullException("creditCardGateway");
}
if (auditor == null) {
throw new ArgumentNullException("auditor");
}
_creditCardGateway = creditCardGateway;
_auditor = auditor;
}
public void Cancel(Order order) {
if (order == null) {
throw new ArgumentNullException("order");
}
// get current user through Ambient Context:
// http://blogs.msdn.com/b/ploeh/archive/2007/07/23/ambientcontext.aspx
if (!CurrentUser.CanCancelOrders()) {
throw new InvalidOperationException(
"Not enough permissions to cancel order. Use 'CanCancelOrders' to check.");
}
// try to keep as much domain logic in entities as possible
if(!order.CanBeCancelled()) {
throw new ArgumentException(
"Order can not be cancelled. Use 'CanBeCancelled' to check.");
}
order.Cancel();
// this can throw GatewayException that would be caught by the
// 'Cancel' caller and rollback the transaction
_creditCardGateway.RevertChargesFor(order);
_auditor.AuditCancellationFor(order);
}
}
A slightly different take on it:
//UI
public class OrderController
{
private readonly IApplicationService _applicationService;
[HttpPost]
public ActionResult CancelOrder(CancelOrderViewModel viewModel)
{
_applicationService.CancelOrder(new CancelOrderCommand
{
OrderId = viewModel.OrderId,
UserChangedTheirMind = viewModel.UserChangedTheirMind,
UserFoundItemCheaperElsewhere = viewModel.UserFoundItemCheaperElsewhere
});
return RedirectToAction("CancelledSucessfully");
}
}
//App Service
public class ApplicationService : IApplicationService
{
private readonly IOrderRepository _orderRepository;
private readonly IPaymentGateway _paymentGateway;
//provided by DI
public ApplicationService(IOrderRepository orderRepository, IPaymentGateway paymentGateway)
{
_orderRepository = orderRepository;
_paymentGateway = paymentGateway;
}
[RequiredPermission(PermissionNames.CancelOrder)]
public void CancelOrder(CancelOrderCommand command)
{
using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
{
Order order = _orderRepository.GetById(command.OrderId);
if (!order.CanBeCancelled())
throw new InvalidOperationException("The order cannot be cancelled");
if (command.UserChangedTheirMind)
order.Cancel(CancellationReason.UserChangeTheirMind);
if (command.UserFoundItemCheaperElsewhere)
order.Cancel(CancellationReason.UserFoundItemCheaperElsewhere);
_orderRepository.Save(order);
_paymentGateway.RevertCharges(order.PaymentAuthorisationCode, order.Amount);
}
}
}
Notes:
In general I only see the need for a domain service when a command/use case involves the state change of more than one aggregate. For example, if I needed to invoke methods on the Customer aggregate as well as Order, then I'd create the domain service OrderCancellationService that invoked the methods on both aggregates.
The application layer orchestrates between infrastructure (payment gateways) and the domain. Like domain objects, domain services should only be concerned with domain logic, and ignorant of infrastructure such as payment gateways; even if you've abstracted it using your own adapter.
With regards to permissions, I would use aspect oriented programming to extract this away from the logic itself. As you see in my example, I've added an attribute to the CancelOrder method. You can use an intercepter on that method to see if the current user (which I would set on Thread.CurrentPrincipal) has that permission.
With regards to auditing, you simply said 'audit for the operation'. If you just mean auditing in general, (i.e. for all app service calls), again I would use interceptors on the method, logging the user, which method was called, and with what parameters. If however you meant auditing specifically for the cancellation of orders/payments then do something similar to Dmitry's example.

NInject and thread-safety

I am having problems with the following class in a multi-threaded environment:
public class Foo
{
[Inject]
public IBar InjectedBar { get; set; }
public bool NonInjectedProp { get; set; }
public void DoSomething()
{
/* The following line is causing a null-reference exception */
InjectedBar.DoSomething();
}
public Foo(bool nonInjectedProp)
{
/* This line should inject the InjectedBar property */
KernelContainer.Inject(this);
NonInjectedProp = nonInjectedProp;
}
}
This is a legacy class which is why I am using property rather than constructor injection.
Sometime when the DoSomething() is called the InjectedBar property is null. In a single-threaded application, everything runs fine.
How can this be occuring and how can I prevent it?
I am using NInject 2.0 without any extensions, although I have copied the KernelContainer from the NInject.Web project.
I have noticed a similar problem occurring in my web services. This problem is extremely intermittent and difficult to replicate.
First of all, let me say that this is wrong on so many levels; the KernelContainer was an infrastructure class kept specifically to work around certain limitations in the ASP.NET WebForms page lifecycle. It was never meant to be used in application code. Using the Ninject kernel (or any DI container) as a service locator is an anti-pattern.
That being said, Ninject itself is definitely thread-safe because it's used to service parallel requests in ASP.NET all the time. Wherever this NullReferenceException is coming from, it's got little if anything to do with Ninject.
I can think of two possibilities:
You have to initialize KernelContainer.Kernel somewhere, and that code might have a race condition. If something tries to use the KernelContainer before the kernel is fully initialized (possible if you use the IKernel.Bind methods instead of loading modules as per the guidance), you'll get errors like this. Or:
It's your IBar implementation itself that has problems, and the NullReferenceException is happening somewhere inside the DoSomething method. You don't actually specify that InjectedBar is null when you get the exception, so that's a legitimate possibility here.
Just to narrow the field of possibilities, I'd eliminate the KernelContainer first. If you absolutely must use Ninject as a service locator due to a poorly-designed legacy architecture, then at least allow it to create the dependencies instead of relying on Inject(this). That is to say, whichever class or classes need to create your Foo, have that class call kernel.Get<Foo>(), and set up your kernel to Bind<Foo>().ToSelf().

Resources