5

I would like to configure Spring Security for Hawt.io with embedded tomcat. After custom login with (user and password) Hawt.io login is asking to authenticate.But Hawt.io authentication is disabled in code and in config. If I remove MvcConfig and WebSecurityConfig with security.basic.enable= false then without any authentication which works.But

I want to authenticate with custom username and password which is working after that Hawt.io is also asking the credentials though that part is disabled.

Please help me to resolve this.

application.properties

hawtio.authenticationEnabled = false
management.security.enabled=false
security.basic.enable= true
security.ignored= /**

login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example </title>
    </head>
    <body>
        <div th:if="${param.error}">
            Invalid username and password.
        </div>
        <div th:if="${param.logout}">
            You have been logged out.
        </div>
        <form th:action="@{/login}" method="post">
            <div><label> User Name : <input type="text" name="username"/> </label></div>
            <div><label> Password: <input type="password" name="password"/> </label></div>
            <div><input type="submit" value="Sign In"/></div>
        </form>
    </body>
</html>

MvcConfig.java

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }
}

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/","/hawtio").permitAll().anyRequest().authenticated().and()
                .formLogin().loginPage("/login")
                .permitAll().and().logout().permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    }
}

Application.java

@SpringBootApplication
@EnableHawtio
public class Application {
    public static void main(String[] args) {
        System.setProperty(AuthenticationFilter.HAWTIO_AUTHENTICATION_ENABLED, "false");
        SpringApplication.run(Application.class, args);
    }
}

pom.xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>io.hawt</groupId>
            <artifactId>hawtio-springboot</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>io.hawt</groupId>
            <artifactId>hawtio-core</artifactId>
            <version>1.5.6</version>
        </dependency>
    </dependencies>

Update: Connect to dummy camel app like below login for again comes on giving credentials going to 404 error page.

enter image description here

sunleo
  • 10,589
  • 35
  • 116
  • 196

1 Answers1

2

The following changes are required to make hawtio work with Spring Security and Spring Boot. You can find a working example here. However, I wasn't able to update the username in hawtio menubar.

Configure Spring Security

Configure Spring security for application in a standard way except for a few changes specfic to hawtio:

  • Disable hawtio authentication,

    @SpringBootApplication
    @EnableHawtio
    @ComponentScan(basePackages = {"com.basaki"})
    public class Application {
    
        public static void main(String[] args) { 
            System.setProperty(AuthenticationFilter.
                HAWTIO_AUTHENTICATION_ENABLED,"false");
            SpringApplication.run(Application.class, args);
        }
    }
    
  • Disable Cross-Site Request Forgery (CSRF) in your application.

  • Make sure the logout request URL matches the /hawtio/auth/logout/*. This is the URL used by hawtio to invalidate a session.

    @Configuration
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
        ...
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/").permitAll()
            .anyRequest().authenticated()
            .and().formLogin().loginPage("/login")
            .failureUrl("/login?error")
            .permitAll()
            .and().logout().logoutRequestMatcher(
            new AntPathRequestMatcher(
                    "/hawtio/auth/logout/*"))
            .logoutSuccessUrl("/login?logout")
            .and().csrf().disable();
        }
        ...
    }
    

Login Page

  • Since you are using a form login, you will be needing a custom login page. In this example, a login.html is used.

  • Configure the /login request to match view login.html

    @Configuration
    public class SpringMvcConfiguration extends WebMvcConfigurerAdapter {
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/login").setViewName("login");
        }
    
        ...
    }
    

Updating hawtio's login.html

Once you log out from the hawtio page, it takes you to its own login page. Since it's a single page application with AngularJS, you need to replace this partial page with your own custom AngularJS based login page.

  • In this example, a login-hawtio.html page is used.

    <div ng-controller="LoginPlugin.LoginController">
        <h1 style="color: #78ab46;">Sign in</h1>
    
        <form action="/login" method="post">
            <div>
                <label style="font-weight: 700; padding-right: 15px;
                    padding-left: 15px;">Username:
                    <input id="username" type="text" name="username"
                         placeholder="Username"/>
                </label>
            </div>
            <div>
                <label style="font-weight: 700; padding-right: 15px;
                    padding-left: 15px;">Password:
                    <input id="password" type="password" 
                        name="password" required
                        placeholder="Password"/>
                </label>
            </div>
            <div>
                <button type="submit" class="btn btn-default">Sign In</button>
            </div>
        </form>
    </div>
    
  • A controller to replace the existing hawtio login page.

    @Controller
    public class HawtioController {
    
        private ResourceLoader loader;
    
        @Autowired
        public HawtioController(ResourceLoader loader) {
            this.loader = loader;
        }
    
        @RequestMapping(value = "/hawtio/app/core/html/login.html", method = RequestMethod.GET,
            produces = "text/html;charset=UTF-8")
        public void getHawtioLoginHtml(HttpServletResponse response) {
            String location = "classpath:/templates/login-hawtio.html";
            try {
                String body = getResource(location);
                response.setStatus(HttpStatus.OK.value());
                response.getWriter().write(body);
                response.getWriter().flush();
                response.getWriter().close();
            } catch (IOException e) {
                response.setStatus(HttpStatus.NOT_FOUND.value());
            }
        }
        ...
    }
    

hawtio Login Plugin

  • A custom hawtio plugin is needed to have your own AngularJS login controller, LoginPlugin.LoginController. It's used for redirecting to hawtio's home page after you are logged in from hawto's login page.

    @Configuration
    public class HawtioConfiguration {
    
        @Bean
        public HawtPlugin samplePlugin() {
            return new HawtPlugin("login-plugin",
                "/hawtio/plugins",
                "",
                new String[]{"plugin/js/login-plugin.js"});
        }
    }
    
  • The login-plugin.js is located under resources/app/webapp/plugin/js folder.

    var LoginPlugin = (function(LoginPlugin) {
    
        LoginPlugin.pluginName = 'login-plugin';
        LoginPlugin.log = Logger.get('LoginPlugin');
    
        LoginPlugin.module = angular.module('login-plugin', ['hawtioCore'])
            .config(function($routeProvider) {
                $routeProvider.
                when('/home', {
                    templateUrl: '/hawtio/index.html'
                });
             });
    
        LoginPlugin.module.run(function(workspace, viewRegistry, layoutFull) {
    
            LoginPlugin.log.info(LoginPlugin.pluginName, " loaded");
            viewRegistry["login-plugin"] = layoutFull;
            workspace.topLevelTabs.push({
                id: "LoginPlugin",
                content: "Login Plugin",
                title: "Login plugin loaded dynamically",
                isValid: function(workspace) { return true; },
                href: function() { return "#/login-plugin"; },
                isActive: function(workspace) {
                    return workspace.isLinkActive("login-plugin"); }
    
            });
        });
    
        LoginPlugin.LoginController = function($scope, $rootScope, $http) {
            var fullUrl = "/hawtio/index.html";
            $http({method: 'GET', url: fullUrl});
        };
    
        return LoginPlugin;
    
    })(LoginPlugin || {});
    
    hawtioPluginLoader.addModule(LoginPlugin.pluginName);
    
Indra Basak
  • 7,124
  • 1
  • 26
  • 45
  • This is not working, when I try to connect to using (Connect to Remote server) though already session is established again it is asking credentials.If we give credentials then it is getting redirected to http://localhost:8080/ and getting 404 error.This error is same as above posted one. – sunleo Dec 11 '17 at 05:13
  • Is it possible for you check your project in GitHub? I will be able to help you to debug. – Indra Basak Dec 11 '17 at 06:17
  • Thanks for reply, You can use same project u provided here https://github.com/indrabasak/spring-security-hawtio-example, Just u create one dummy camel project with jolokia in some other port no and try to connect from your hawtio it gives the error.Pls ping me if you need anything. – sunleo Dec 11 '17 at 06:37
  • I will take a look and let you know. – Indra Basak Dec 11 '17 at 06:50
  • With any camel keep below dependencies for jolokia functionality org.jolokia jolokia-core org.jolokia jolokia-client-java 1.3.3 org.jolokia jolokia-spring plugin 1.1.0 – sunleo Dec 11 '17 at 07:14
  • Please check the project on GitHub now. – Indra Basak Dec 13 '17 at 19:15
  • It is also not working same authentication issue is there I will provide one project with same set up in Git.Thanks – sunleo Dec 14 '17 at 08:19
  • I followed your solution in your github link. Will it be possible to set custom context path? – dvk317960 Aug 23 '18 at 04:18