0 Replies Latest reply on Feb 12, 2014 6:38 PM by robatsu

    Valve authentication & EJBContext/SessionContext principal propagation

    robatsu

      I have a very straightforward problem that I haven't been able to answer.  We use a valve with our own custom authenticator class to authenticate the HttpRequest, and set a principal there.  This principal is not then automatically available in the EJB context via EJBContext.getCallerPrincipal - we continue to just get anonymous there.  I need to know how to propagate the principle we generate to the ejb context.  We are on AS 7.1.1.

       

      Here is some of our config and code:

       

      The valve is configured on our RestEasy endpoints.  In jboss-web.xml, we have:

       

      <?xml version="1.0" encoding="UTF-8"?>

      <jboss-web>

          <context-root>rest/${rest.version.api}</context-root>

          <security-domain>sp</security-domain>

          <valve>

              <class-name>com.sheerid.authenticator.OAuthSPRedirectFormAuthenticator</class-name>

          </valve>

      </jboss-web>

       

      In OAuthSPRedirectFormAuthenticator.java:

       

      public class OAuthSPRedirectFormAuthenticator extends ServiceProviderAuthenticator {

       

          private static final String HEADER_AUTHORIZATION = "Authorization";

          private static final Pattern PATTERN_BEARER_TOKEN = Pattern.compile("Bearer (.+)");

       

          private final Logger logger = Logger.getLogger(this.getClass());

       

          @Override

          public boolean authenticate(Request request, HttpServletResponse response, LoginConfig loginConfig) throws IOException {

              String authHeader = getAuthHeader(request);

             

              if (authHeader != null) {

                  Matcher tokenMatcher = PATTERN_BEARER_TOKEN.matcher(authHeader);

                  if (tokenMatcher.matches()) {

                      String token = tokenMatcher.group(1);

                      User user = getUserService().findUserByAccessToken(token);

                      if (user != null) {

                          final String userName = user.getUsername();

                          request.setUserPrincipal(generatePrincipal(request, userName, RoleUtils.generateRoles(user)));

                          ((HttpServletRequest) request).setAttribute(SheerIDConstants.ACCOUNT_ID, user.getAccountId());

                          ((HttpServletRequest) request).setAttribute(SheerIDConstants.USER_ID, user.getId());

                          ((HttpServletRequest) request).setAttribute(SheerIDConstants.ACCESS_TOKEN, token);

                          SecurityClient client;

                          } else {

                              response.sendError(HttpServletResponse.SC_UNAUTHORIZED);

                              return false;

                          }

                  }

              }

             

              return super.authenticate(request, response, loginConfig);

           }

       

      private static Principal generatePrincipal(Request request, String name, Set<UserRole> roles) {
         List<String> userRoles = new ArrayList<String>();
         userRoles.addAll(UserRole.toStringSet(roles));
         return new GenericPrincipal(request.getContext().getRealm(), name, null, userRoles);

          }

       

      And, by the way, even though we create a GenericPrincipal, our SessionContext in the ejb's returns a principal of class SimplePrinciple from sessionContext.getCallerPrincipal() that has a name of "anonymous".  Our beans are typically annotated as:

       

      @Stateless

      @SecurityDomain(value="sp")

      @EJB(name = "java:global/UserServiceBean", beanInterface = UserServiceRemote.class)

      @DeclareRoles({UserRole.ROLE_NAME_ACCOUNT_OWNER,

                     UserRole.ROLE_NAME_STAFF,

                     UserRole.ROLE_NAME_USER,

                     UserRole.ROLE_NAME_USER_ADMIN})

      public class UserServiceBean extends AbstractSessionBean implements UserServiceRemote{

      .......

       

      Again, any help in getting this working would be very much appreciated.  It seems like it should be really simple, but I haven't been able to find the key to this one.