简体   繁体   中英

Eclipse Scout - Clean Database authentication

I'm trying to implement a database authentication with Eclipse Scout.

For that I created a class DataSourceCredentialVerifier in the client module, which implements the ICredentialVerifier interface. Then I adapted the init method of the UiServletFilter class to use my verifier.

public class DataSourceCredentialVerifier implements ICredentialVerifier {

private static final Logger LOG = LoggerFactory.getLogger(DataSourceCredentialVerifier.class);

@Override
public int verify(String username, char[] password) throws IOException {
    Object queryResult[][] = BEANS.get(IMySqlAuthService.class).load();


    return AUTH_OK;
}

I haven't implemented any authentication logic yet. My task now is to establish a clean database connection.

For that I created the following interface in the shared module:

public interface IMySqlAuthService extends IService {

    Object[][] load();
}

The implementation is in the server module:

   public class MySqlAuthService implements IMySqlAuthService {

        @Override
        public Object[][] load() {
            String sql = "select username, password from users ";
            Object[][] queryResult = SQL.select(sql, null, null);       
            return queryResult;
        }
   }

First I want to see, if there is at least something in the query, but I get an AssertionException here:

 Object queryResult[][] = BEANS.get(IMySqlAuthService.class).load();

org.eclipse.scout.rt.platform.util.Assertions$AssertionException: Assertion error: no instance found for query: interface org.eclipse.scout.app.shared.services.IMySqlAuthService
at org.eclipse.scout.rt.platform.util.Assertions.fail(Assertions.java:580)
at org.eclipse.scout.rt.platform.util.Assertions.assertNotNull(Assertions.java:87)
at org.eclipse.scout.rt.platform.BEANS.get(BEANS.java:41)

I don't get an instance of my MySqlAuthService implementation. I assume that the BeanManager should have created an instance for me. MySqlAuthService should be registered as a Bean, since my IMySqlAuthService interface extends from IService which has the @ApplicationScoped annotation.

Adding the @Bean annotation to MySqlAuthService results in the same exception.

Here some information about the BeanManager and annotations: https://eclipsescout.github.io/6.0/technical-guide.html#sec-bean.manager

Here is another different approach so tried, but it doesn't feel correct: https://www.eclipse.org/forums/index.php/t/1079741/

How can I get my example to work with my service?

Here is the working solution with important explanations of Eclipse Scout principles.

The source is summarized information of the Eclipse-Scout-Technical-Guide.

In Scout there is a built in annotation: @TunnelToServer . Interfaces marked with this annotation are called on the server. The server itself ignores this annotation. To achieve that a bean is registered on client side, this annotation is required. The platform cannot (!) directly create an instance for these beans, a specific producer is registered which creates a proxy that delegates the call to the server.

My first clear mistake was that I hadn't annotated the IMySqlAuthService with @TunnelToServer .

After this addition I got rid of the no instance AssertionError .

After that my code ran into the HTTP status-code: 403 access forbidden.

This occured because my code didn't run in the correct Thread. That is the current RunContext . I had to use this lines of code in my verify method of the DataSourceCredentialVerifier :

     Subject subject = new Subject();
     subject.getPrincipals().add(new SimplePrincipal("system"));
     subject.setReadOnly();
     RunContext runContext = RunContexts.copyCurrent().withSubject(subject);

Now one can use the runContext's call() or run() method, depending whether the code returns a result. The action is run in the current thread, meaning that the caller is blocked until completion.

Concrete example solution:

Object[][] result = runContext.call(new Callable<Object[][]>() {

   @Override
   public Object[][] call() throws Exception {
      return BEANS.get(IMySqlAuthService.class).load();
   }

});

//TODO implement authentication logic.

For more information about the RunContext see here: https://eclipsescout.github.io/6.0/technical-guide.html#runcontext

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM