Spring Boot Management security works differently with port set - spring

I'm trying to configure a Spring Boot application (1.2.3, but this also fails with the 1.2.4.BUILD-SNAPSHOT version) with Actuator support. I want to use the Actuator security config for controlling access to the management endpoints, and our own authentication for the rest of the application.
Here is my security config:
#Configuration
#EnableWebSecurity
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
#Autowired
private CustomAuthenticationProvider customAuthProvider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(customAuthProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.regexMatchers(API_DOC_REGEX).permitAll()
.regexMatchers(String.format(PATH_REGEX, PUBLIC_ACCESS)).permitAll()
.regexMatchers(String.format(PATH_REGEX, INTERNAL_ACCESS)).access("isAuthenticated() && authentication.hasOrigin('INTERNAL')")
.regexMatchers(String.format(PATH_REGEX, EXTERNAL_AUTHENTICATED_ACCESS)).authenticated()
.antMatchers("/**").denyAll()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.addFilterAfter(customAuthProcessingFilter(), BasicAuthenticationFilter.class)
.csrf().disable();
}
}
This works correctly when I don't set a management port, but when I set the management port, the management URLs return 401 responses. If I comment out the line .antMatchers("/**").denyAll(), then everything goes through without requiring authentication at all. So it looks like it is using my application's security config for the Actuator endpoints when I set a custom port, but I'm not sure why.
How do I get it to use it's own security when running on a custom port?

Expanding on the comment from #M. Deinum, adding another adapter for the Management stuff (even though it already has one) seems to have fixed it. This is the class I ended up with:
#Order(0)
#Configuration
public class ManagementSecurityConfig extends WebSecurityConfigurerAdapter
{
#Autowired
ManagementServerProperties managementProperties;
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.requestMatchers()
.requestMatchers(new RequestMatcher()
{
#Override
public boolean matches(HttpServletRequest request)
{
return managementProperties.getContextPath().equals(request.getContextPath());
}
})
.and()
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}

Related

Spring Boot Security Authentication: Application having 2 different domain URL and need to authenticate with Spring Security

I need help with one of the issue that I am facing with Spring Boot Security. I have application which has 2 different Urls.(Infoblock CNAME)
domain1.com
domain2.com
both Url are point to the same application.
Due to business reason we need 2 different Url and we are planning to land on diff page based on the URL entered in browser. Issue is with Spring Security AntMatcher.
With AntMatcher we can only provide path but how we can address the domain with it.
Could you please guide me.
Thanks in Advance.
Instead of AntMatcher you can use
http.requestMatcher(new RequestHeaderRequestMatcher("Host", "127.0.0.1:8080"))
with any other matcher from org.springframework.security.web.util.matcher package.
Here is an example:
#EnableWebSecurity
#Configuration
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Configuration
#Order(1)
public static class SecConfig1 extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new RequestHeaderRequestMatcher("Host", "127.0.0.1:8080"))
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin();
}
}
#Configuration
#Order(2)
public static class SecConfig2 extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new RequestHeaderRequestMatcher("Host", "127.0.0.2:8080"))
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
#Override
protected void configure(HttpSecurity http) throws Exception {
//default deny all
http.authorizeRequests().anyRequest().denyAll();
}
}

Spring boot multiple authentication

I've done a spring boot application with spring security integration and a custom Authentication Provider. Now I want that some link are going to use custom Authent provider and some other an inmemory authentication. How can I do that?
You're right. Here is my SecurityConfig class. Now i want protect path like '/api/**' with a basic authentication.
#Autowired
private CustomAuthenticationProvider authProvider;
#Autowired
DataSource dataSource;
#Autowired
CustomLogoutSuccessHandler customLogoutSuccessHandler;
#Autowired
CustomAuthenticationSuccessHandler customAutheincationSuccessHandler;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/list/**").hasAnyAuthority("Administrator","Operator")
.antMatchers("/api/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/authenticateTheUser")
.successHandler(customAutheincationSuccessHandler)
.and().logout()
.logoutUrl("/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.logoutSuccessUrl("/login").and().exceptionHandling().accessDeniedPage("/accessDenied")
.and()
.csrf().disable();
}
You can create two spring security configurations with different paths. In first configuration u can exclude /api/**. But second configuration will be able to check it.

Spring Boot: Authenticating both a Stateless REST API and a Stateful "Login" Web Controller in the same project?

So I have an application that contains a REST API which is used by a custom java application on an IOT device with no user interaction.And I also have a web app which needs a stateful session for maintaining user login.
Is it possible to use Spring Security to authenticate requests to my API and web controller differently?What form of authentication should I be using for the REST API?
One way to achieve what you are looking for is to have 2 configurations in your spring security. E.g.
Pay attention to antMatcher (matcher not matchers). The antMatcher will control on what set of url your entire config applies i.e. FormLoginWebSecurityConfigurerAdapter in below example will apply only to uri matching /api/test/**. Of course, you can define the antMatcher only in one of the configs say config1 and the other config in that case will be a catch all (i.e catch everything that does not match config1)
#EnableWebSecurity
#Configuration
public class SecurityConfig {
#Configuration
#Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
public void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
}
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
http
.antMatcher("/api/v1/**")
.authorizeRequests()
.antMatchers("/api/v1/**").authenticated()
.and()
.httpBasic();
}
}
#Configuration
#Order(2)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
public void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("user").roles("USER");
auth.inMemoryAuthentication().withUser("admin1").password("admin").roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED); // CONFIGURE TYPE OF SESSION POLICY
http
.antMatcher("/api/test/**")
.authorizeRequests()
.antMatchers("/api/test/**").authenticated()
.and()
.formLogin();
}
}
}

LDAP authentication with Spring Boot 1.4.1

I am using Spring boot and developing REST services and want to integrate with LDAP authentication security mechanism.
I googled a lot but did not get a concrete solution as such. I am looking for a complete example.
Also I am using POSTMAN client and want to know how to use it to test the LDAP authentication.
Thanks in advance..!!
Here is an example using ActiveDirectoryLdapAuthenticationProvider
This was actually surprisingly simple. Thank you, Boot.
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/yourstuff/**").permitAll()
.antMatchers("/your/protectedstuff/**").authenticated()
.and()
.httpBasic()
.permitAll();
}
#Configuration
protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new ActiveDirectoryLdapAuthenticationProvider("DOMAINNAME","LDAP SERVER URI"));
}
}
}

Controlling access to Spring Security OAuth2 endpoints

I'm trying to control what clients can generate access tokens in Spring Security OAuth2.0.
I'd like to allow only one client to be able to generate access tokens (access /oauth/authorize, /oauth/token) and all the other ones to validate them.
The documentation says that I should use the standard Spring Security WebSecurityConfigurer to achieve such an access granularity. However, all the configuration I do does not affect access to the end-points.
I tried the following configuration to allow only client mgmt to generate tokens:
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("mgmt")
.secret("pass")
.authorities("ROLE_WRITE")
.and()
.withClient("resource")
.secret("pass")
.authorities("ROLE_READ");
}
}
#Configuration
public class EndpointAuthorizationConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/oauth/token")
.and()
.authorizeRequests()
.antMatchers("/oauth/token")
.hasAuthority("ROLE_WRITE")
.and()
.httpBasic();
}
}
I also tried to define users one more time in the EndpointAuthorizationConfig class, but that did not help. Client resource still can access those endpoints.
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("mgmt")
.password("pass")
.roles("WRITE");
}

Resources