Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Scout » How REST call token can be injected in the RunContext as Principal(How REST call token can be injected in the RunContext as Principal)
How REST call token can be injected in the RunContext as Principal [message #1841320] Wed, 12 May 2021 07:21 Go to next message
Seydou Zakou is currently offline Seydou ZakouFriend
Messages: 44
Registered: May 2020
Member
Hi all,

We need to provide some REST api for our Scout application. We are using a token based authentication. Token is got by first authenticating the user (login, password) and then generated a token to be used in the next calls. So getting detail of a user API method is as follow:
@GET
@Path("get/{id}")
@Produces(MediaType.APPLICATION_JSON)
public UserEntityDo getUserDetail(@HeaderParam("token") String token, @PathParam("id") String id) {
  // Check token validity and return corresponding user name if any
  String username = checkToken(token); 
  if (username == null) {
    Response.status(Response.Status.FORBIDDEN).build();
  }
  Subject subject = new Subject();
  subject.getPrincipals().add(new SimplePrincipal(username));
  subject.setReadOnly();
  RunContext runContext = RunContexts.empty().withSubject(subject);
  Map<String, Object> data = runContext.call(new Callable<Map<String, Object>>() {
    @Override
    public Map<String, Object> call() throws Exception {
      return BEANS.get(IUserService.class).getData(UUID.fromString(id));
    }
  });
  // Build user entity data
  UserEntityDo user = BEANS.get(UserEntityDo.class).withLogin((String) data.get("login"))
      .withLastLoginDate((Date) data.get("lastLoginDate").withFirstName((String) data.get("firstName").withLastName((String) data.get("lastName"));
  return user;
}


The code work perfectly but we have to use the portion of code from //Check... till //Build... in all our method.

I'am thinking about putting this code within a ServletFilter that will inject the user principal in the RunContext based on the header token, but have no idea how to implement it.

Does anyone have an idea ?

Thanks in advance.

[Updated on: Wed, 12 May 2021 07:46]

Report message to a moderator

Re: How REST call token can be injected in the RunContext as Principal [message #1841325 is a reply to message #1841320] Wed, 12 May 2021 09:49 Go to previous messageGo to next message
Beat Schwarzentrub is currently offline Beat SchwarzentrubFriend
Messages: 210
Registered: November 2010
Senior Member
Seydou Zakou wrote on Wed, 12 May 2021 07:21
I'am thinking about putting this code within a ServletFilter that will inject the user principal in the RunContext based on the header token, but have no idea how to implement it.


Yes, I think that's the correct approach. The only downside is that in a ServletFilter you don't get the nice @HeaderParam convenience from JAX-RS. Instead you have to extract it yourself from the HTTP request. Something like this (untested):

import java.io.IOException;

import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.scout.rt.platform.context.RunContexts;
import org.eclipse.scout.rt.platform.security.SimplePrincipal;

public class TokenFilter implements Filter {

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;

    String token = getToken(req);
    String username = checkToken(token);
    if (username == null) {
      resp.sendError(HttpServletResponse.SC_FORBIDDEN);
    } else {
      Subject subject = createSubject(username);
      RunContexts.copyCurrent(true)
          .withSubject(subject)
          .run(() -> chain.doFilter(request, response));
    }
  }

  protected String getToken(HttpServletRequest req) {
    // Extract token from HTTP request
    return req.getHeader("token");
  }

  protected String checkToken(String token) {
    // Convert token to username
    return ...;
  }
  
  protected Subject createSubject(String username) {
    // Create subject from username
    Subject subject = new Subject();
    subject.getPrincipals().add(new SimplePrincipal(username));
    subject.setReadOnly();
    return subject;
  }

  @Override
  public void destroy() {
  }
}


Regards,
Beat
Re: How REST call token can be injected in the RunContext as Principal [message #1841386 is a reply to message #1841325] Thu, 13 May 2021 23:51 Go to previous message
Seydou Zakou is currently offline Seydou ZakouFriend
Messages: 44
Registered: May 2020
Member
Hello Beat,

Thank you for your response. I implemented you suggestion and it works.

Note that I had to exclude /api/* from UiServlet's AuthFilter in web.xml to get rid of 403 error response.
Previous Topic:Is it posssible to set the outline to top
Next Topic:Selecting buttons in a RadioButtonGroup
Goto Forum:
  


Current Time: Sat Jul 20 07:54:47 GMT 2024

Powered by FUDForum. Page generated in 0.04301 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top