1 Reply Latest reply on Jan 12, 2016 12:46 AM by Sony Abraham

    wildfly http header based identity assertion

    Sony Abraham Newbie

      Hi,

       

      Is there any way i can achieve http header based identity assertion in wildfly ?

      My scenario goes like this -

      • User authentication happens outside our application (access manager) which passes the user id as a http header in the request.
      • I have to check whether this token is present, and if present i will consider the request as authenticated.
      • But, for our application to work, we need to create a security context for that user in our server.
      • For this I need to invoke our login module with this user id ( no password) and In my custom login module i just check whether such a user is present in our user store, if present i will return true in my login module.
        • 1. Re: wildfly http header based identity assertion
          Sony Abraham Newbie

          I finally got this done as below. Not sure whether this the the correct approach or a better one is available.

           

          1. ServletExtention where custom SSOHandler and custom identityAssertion authentication mechanism are registered.

           

          public class IdentityAssertionHandlerExtension implements ServletExtension{

           

            @Override

            public void handleDeployment(DeploymentInfo deploymentInfo,ServletContext servletContext) {

                // Case where header token bases SSO need to be implemented

                  deploymentInfo.addInnerHandlerChainWrapper(new HandlerWrapper() {

                      @Override

                      public HttpHandler wrap(HttpHandler handler) {

                          return Handlers.predicate(new HeaderTokenPredicate(IdentityAsserterLoginModule.SSO_TOKEN_TYPE), new SSOHandler(handler), handler);

                      }

                  });          

                  // For SOAP services which relies on header for authentication

                  deploymentInfo.addAuthenticationMechanism("IDTY-ASSERT",

                  new IdentityAssertionAuthenticationMechanismFactory(deploymentInfo.getIdentityManager()));

              }

          }

           

          2. IdentityAssertionAuthenticationMechanism for normal HTTP requests which will be come after authentication in external system like access manager

           

          public class IdentityAssertionAuthenticationMechanismFactory implements  AuthenticationMechanismFactory{

            private final IdentityManager identityManager;

              public IdentityAssertionAuthenticationMechanismFactory(IdentityManager identityManager) {

                  this.identityManager = identityManager;

              }

            @Override

            public AuthenticationMechanism create(String mechanismName, FormParserFactory formParserFactory,

            Map<String, String> properties) {

            // TODO Auto-generated method stub

            return new IdentityAssertionAuthenticationMechanism(mechanismName,identityManager,properties);

            }

          }

           

          public class IdentityAssertionAuthenticationMechanism implements AuthenticationMechanism {

           

            public final static String TOKEN_PREFIX = "icSessionId:";

            protected TrivialLog log = TrivialLog.getInstance();

            private String name;

              private IdentityManager identityManager;

              Map<String, String> properties = new HashMap<String,String>();

           

            public IdentityAssertionAuthenticationMechanism(String name, IdentityManager identityManager,

            Map<String, String> properties) {

                this.name = name;

                this.identityManager = identityManager;

                this.properties = properties;

            }

           

            @Override

            public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {

            AuthenticationMechanismOutcome outcome = AuthenticationMechanismOutcome.NOT_ATTEMPTED;

            if(exchange.getRequestHeaders()!=null){

            String token = null;

            for(String header : IdentityAsserterLoginModule.TOKEN_TYPE){

            token = exchange.getRequestHeaders().getFirst(header);

            if(token!=null && !token.isEmpty()){

            outcome =  attemptIdtyAssertion(exchange,securityContext,token);

            if(AuthenticationMechanismOutcome.AUTHENTICATED.equals(outcome)){

            break;

            }

            }

            }

            }

            return outcome;

            }

           

            private AuthenticationMechanismOutcome attemptIdtyAssertion(HttpServerExchange exchange, SecurityContext securityContext,String token){

            String decodedToken = null;

            String userName = null;

            try {

            byte[] decodedTokenBytes = Base64Encoder.decode(token);

            decodedToken = new String(decodedTokenBytes);

            if (!(decodedToken.startsWith(TOKEN_PREFIX))) {

            String error = "IcargoIdentityAsserter received unknown token string \""

            + decodedToken + "\"." + " Expected " + TOKEN_PREFIX + "sessionId";

            log.log(error);

            return AuthenticationMechanismOutcome.NOT_ATTEMPTED;

            }

            // extract the username from the token

            userName = decodedToken.substring(TOKEN_PREFIX.length());

           

           

            } catch (EncryptionFailedException e) {

            String error = "Could not Decode token string agaist "+IdentityAsserterLoginModule.TOKEN_TYPE+ "for token "+ token;

            log.log(error);

            return AuthenticationMechanismOutcome.NOT_ATTEMPTED;

            }

            //exchange.putAttachment(ExternalAuthenticationMechanism.EXTERNAL_PRINCIPAL, userName);

            Account account = null;

            SecurityContextThreadLocal.getInstance().setHandleType(SecurityContextThreadLocal.IDTY_ASSERTION_HANDLE_TYPE);

            try{

            account = identityManager.verify(userName, ExternalCredential.INSTANCE);

            }finally{

            SecurityContextThreadLocal.getInstance().removeHandleType();

            }

            if(account!=null){

            securityContext.authenticationComplete(account, name  , false);

                  return AuthenticationMechanismOutcome.AUTHENTICATED;

            }

            return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;

           

            }

           

            @Override

            public ChallengeResult sendChallenge(HttpServerExchange exchange, SecurityContext securityContext) {

            return new ChallengeResult(false);

            }

           

          }

           

          3. SSO Handler for SOAP services

          public class SSOHandler  implements HttpHandler{

           

            private HttpHandler handler;

           

            public SSOHandler(HttpHandler handler){

            this.handler=handler;

            }

           

            @Override

            public void handleRequest(HttpServerExchange exchange) throws Exception {

           

            if(exchange.getRequestHeaders()!=null){

            String token = null;

            for(String header : IdentityAsserterLoginModule.SSO_TOKEN_TYPE){

            token = exchange.getRequestHeaders().getFirst(header);

            if(token!=null && !token.isEmpty()){

            doExternalLogin(exchange,token);

            break;

            }

            }

            }

            try{

            this.handler.handleRequest(exchange);

            }finally{

            SecurityContextThreadLocal.getInstance().removeHandleType();

            }

            }

           

            private void doExternalLogin(HttpServerExchange exchange,String token) throws ServletException{

            if(exchange.getSecurityContext().getAuthenticatedAccount()==null){

            SecurityContextThreadLocal.getInstance().setHandleType(SecurityContextThreadLocal.SSO_HANDLE_TYPE);

            exchange.getSecurityContext().login(token, "");

            }

            }

          }

           

          4. Then i have my login module where i check my custom checks on the tokens supplied and authenticate the requests.