2

Short story: How can I pass the username that is used in ssh connector of CRaSH shell to the customized Java method?

Not-so-short story: I created a set of custom shell commands for Spring. The authentication was done via ssh connector, where an username and a password was entered, like this ssh foobarUsername@localhost -p 2000. It went into the authentication policy in Spring and got passed or denied accordingly.

Now after being authorized and got into the shell, I need to get the usename to run some functions. In this case, I need to find out how to pass foobarUsername into the java methods I created, which is annotated with @Command and extended with BaseCommand.

My Java implementation, which is later extended by a groovy script for CRaSH:

    public class FooCommand extends BaseCommand {  
        @Command
        public void main(@Usage("do something")
                         @Required @Option(names = {"o", "option"}) String option) {
            doSomething(option, username/* the username in ssh request*/);
        }    
    }

The ssh connector is like this: ssh foobarUsername@localhost -p 2000

Update: By default, the authentication of my shell command was done by Spring's own AuthenticationManager. At the time I sent a request via SSH, authentication was in Spring's session. Then it got into the shell and I tried any one of my commands. By putting a breakpoint in main() of FooCommand, I found that the context that should have had the authentication request that had been sent earlier was gone. Apparently, the Spring session of receiving, processing and returning authentication was ended before I enter my command.

Jerry Yeh
  • 61
  • 1
  • 3

1 Answers1

1

First of all you have to implement CRaSH authentication plugin as described in documentation. In plugin you have access to context's attributes and username. Just save username to attributes

getContext().getAttributes().put("username", username);

Attributes are shared between all users. It is theoretically possible to override username before you put it to session

Next you have to create login.groovy (even if you have Java project) file in src/main/resources/commands/crash, documentation.

login.groovy:

welcome = { ->
    def hostName;
    try {
        hostName = java.net.InetAddress.getLocalHost().getHostName();
    } catch (java.net.UnknownHostException ignore) {
        hostName = 'localhost';
    }

    String banner =     Application.getResourceAsStream('/banner.txt').text
    String username =     this.binding.variables.crash.context.attributes.username
    this.binding.variables.shell.context.session.username = username


    return """
${banner}
Logged into $hostName @ ${new Date()}
"""
}

prompt = { ->
    return "> ";
}

Where Application is my application class and banner is my banner.txt. You can copy login.groovy from spring boot and add two lines with username variable.

Now we have username in shell session. You can use it in you command

String username = context.getSession().get("username").toString();

improvement on jira

Mateusz
  • 690
  • 1
  • 6
  • 21