Skip to content

Latest commit

 

History

History
78 lines (55 loc) · 4.06 KB

5-access-control.asciidoc

File metadata and controls

78 lines (55 loc) · 4.06 KB

Order Service - Access-Control

Now, we will create the authorization for our application. We will learn how to create permission and groups as well as how to apply permisions to business logic.

Authentication

The basic configuration has already been created for you from the application template. You can find it in the class BaseWebSecurityConfig (and BaseUserDetailsService).

As you can see in a first file there are some users configured already.

Authorization

First we need to configure the available permissions of our application and group them for better administration. Next we extend our use-cases with authorization so they can only be executed by users with the required permission.

AccessControlConfig

We open the class ApplicationAccessControlConfig and have a look. Here we define permissions as constants following devon4j naming conventions. For our entities Item and Order we create according permissions as constants here:

  • FindItem

  • SaveItem

  • DeleteItem

  • FindOrder

  • SaveOrder

  • DeleteOrder

Also we add this group (yes, ommit prefix for simplicity so the waiter account defined in ApplicationAccessControlConfig matches):

  public static final String GROUP_WAITER = "waiter";

Additionally, we add a new user in BaseWebSecurityConfig.configureGlobal:

  auth.inMemoryAuthentication() ...
    .and().withUser("waiter").password(this.passwordEncoder.encode("waiter")).roles("waiter");

Note: This entire login-mechanism with hardcoded accounts including passwords is obviously entirely inacceptable for a real application. In a real project you would here integrate with an Identity- und Access-Management (IAM). However, to start fast, easy and agile, the devon4j application template intentionally ships with this as a starting point to be then replaced. The real IAM integration will differ between projects and add an additional application with quite some complexity. Typically, this will happen via JWT authentication.

ATTENTION: Further, there is also the issue devon4j#385: currently the roles (in the above code example roles("waiter")) are ignored and in reality the login is automatically used as the only role of the user.

Next, we go to the ApplicationAccessControlConfig constructor and add the new Find* permissions to the group readMasterData. Then, we create the waiter group that inherits from readMasterData and extends it with the other new permissions:

  group(GROUP_WAITER, readMasterData, PERMISSION_SAVE_ITEM, PERMISSION_DELETE_ITEM, PERMISSION_SAVE_ORDER, PERMISSION_DELETE_ORDER);

Test

Test your authorization by creating a new JUnit test:

  • Use TestUtil to mock the login in your test methods (e.g. TestUtil.login("testuser", ApplicationAccessControlConfig.PERMISSION_SAVE_ITEM)). Then call the authorized use-case method to test.

  • Override doTearDown() and add TestUtil.logout() to revert the login after each test method and prevent side-effects on other tests.

  • Ensure you write both positive tests that work if the mocked user has appropriate permissions as well as negative tests that fail because the required permission is not granted to the user. For negative tests you may use assertThrows method.

Integration-Test (optional)

If you have some time left, you can create an integration test based on RestServiceTest and Service-Client (see also exercise 4 services) including permission checks (positive and negative test).