Spring Boot Startup Analysis Tool - java

I am trying to use this tool on github to analyze my spring boot app's startup time. Here's my main class:
#Configuration
#EnableAutoConfiguration
#ComponentScan(lazyInit = true, value = {"com.test.app","com.github.lwaddicor.springstartupanalysis"})
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ApiApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
My application starts up fine but when I try to navigate to: http://localhost:8080/spring-startup/ I get the following message:
{"status":401,"message":"Authentication failed","errorCode":10,"timestamp":1519416149986}
I tried editing the security filters like so:
#EnableWebSecurity
#EnableWebMvc
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(,
"/configuration/ui",
"/configuration/security",,
"/spring-startup",
"/webjars/**");
}
}
But that didn't work. Any ideas what I'm doing wrong?

I think antMatchers() alone is not sufficient since you just tell the system which resources are affected but you do not specify how to deal with them. Append .permitAll() and it should work.
I am using something like this:
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers(HttpMethod.HEAD, "/**").permitAll()
.antMatchers("/v2/api-docs", "/configuration/ui", ...)
.permitAll()
.antMatchers(basePath + "/**").authenticated()
...
basePath is the path to the rest api which should be secured.

I got this to work by commenting out the overriden configure method. Not optimal but I only need to run this locally once so not a big deal to turn security off either.

Related

InvalidTokenException for "unsecured" routes in Spring Security

Since I have updated Spring Boot Version to 2.6.7 I get logs that the way I define unsecured routes is not recommended anymore.
Log message:
You are asking Spring Security to ignore Ant [pattern='/actuator/**']. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.
The way I was describing the config that Spring Security has to ignore these patterns was done by defining a WebSecurityConfiguration and ignoring those routes. What happens in this case is, that the whole security chain is skipped and the above mentioned logs are written. It's okay for me, but not for Spring ;).
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(
"/actuator/**"
);
}
}
When defining these route as part of the httpSecurity as mentioned in the log. The problem occurs that an expired/invalid token cause an error (401 unauthorized) as well for unsecured routes like /actuator/health.
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Getter
private String[] unsecuredPathList;
#PostConstruct
public void postConstruct() {
this.unsecuredPathList = new String[] {
"/actuator/**"};
}
#Bean
public JwtTokenStore jwtTokenStore() {
return new JwtTokenStore(new CustomJwtAccessTokenConverter(true));
}
#Override
public void configure(ResourceServerSecurityConfigurer resourceServer) throws Exception {
resourceServer.tokenStore(jwtTokenStore());
resourceServer.tokenExtractor(new SessionCookieTokenExtractor());
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous()
.authorities("ANONYMOUS")
.and()
.authorizeRequests()
.antMatchers(unsecuredPathList)
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
The goal I want to reach is:
For an unsecure resource the token will not be evaluated/the result is ignored and there is no 401-Unauthorized-Error.
Is there anything I can do in httpSecurity?
Or is there any other recommended way to reach that goal?
Thanks in advance for your help.
There is a group of methods in HttpSecurity class, which allows you to apply defined security rules only to specific paths, and thus create different security filter chains with different rules for different urls.
For example, you can exclude some urls like this:
// convert your String array into a List of RequestMatcher
List<RequestMatcher> excludedPathMatchers = Arrays.stream(unsecuredPathList)
.map(AntPathRequestMatcher::new)
.collect(Collectors.toList());
// configure HttpSecurity to apply filter chain only on paths, that don't match any of the excluded paths
http.requestMatcher(new NegatedRequestMatcher(new OrRequestMatcher(excludedPathMatchers)));
Or you can write something like this, if you have only 1 unsecured endpoint:
http.requestMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/some_url/**")));

Spring 2 security: 403 Forbidden [duplicate]

This question already has answers here:
Spring Security configuration: HTTP 403 error
(8 answers)
Closed 1 year ago.
I have an app that previously was running tests using Spring Boot 1 and which I have updated to 2.0.9.RELEASE.
There are now issues with Spring Security. I know this is the case because if I remove
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<scope>test</scope>
</dependency>
(and any new WebSecurityConfigurerAdapter classes) the tests still succeed. The tests are essentially going to a project controller 'HomeController' and from there going to a service and using a RestTemplate to perform various operations. In reality this is a different app, and if I were writing it from scratch, I would probably do a wiremock but for now and the purposes of this question there is a controller in the test package simulating the required behaviour.
By adding this simple class, I have got past the 403 on the local controller
#TestConfiguration
#EnableWebSecurity
#Order(500)
public class DefaultSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure( HttpSecurity http) throws Exception{
http.authorizeRequests().antMatchers("/").permitAll();
}
}
However, I'm struggling to get past the security on using the RestTemplate. The restTemplate bean is created with basic user and password (simplified a little here)
#Bean
public RestTemplate restTemplate( RestTemplateBuilder restTemplateBuilder ) {
return restTemplateBuilder
.basicAuthorization( "user", "password" )
.build();
}
I can tell by debugging and looking at the interceptors that these are being set.
Now I have added a new configuration class
#TestConfiguration
#EnableWebSecurity
#Order (50)
public class RestTemplateSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure( AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth.inMemoryAuthentication()
.withUser("user")
.password(encoder.encode("password"))
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/otherpath/**")
.authenticated()
.and()
.httpBasic();
}
}
But this seems to have no effect on the RestTemplate calls which are consistently called with basic security of user and password and consistently return 403 Forbidden.
The test class is annotated like this
#AutoConfigureMockMvc
#RunWith( SpringRunner.class )
#SpringBootTest( classes = { DefaultSecurityConfiguration.class, ResttemplateSecurityConfiguration.class }, webEnvironment = DEFINED_PORT )
#TestPropertySource( "classpath:test.properties" )
public class HomeControllerTest {
...
And triggered with a 'standard' mockMvc.perform( ...
With the DefaultSecurityConfiguration class in place these fire without issue it is the later calls in the app code using the restTemplate that fail
Is there anything obvious?
Replace:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/otherpath/**")
.authenticated()
.and()
.httpBasic();
}
By this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/otherpath/**")
.authenticated()
.and()
.httpBasic();
http.csrf().disable();
}

#EnableOAuth2Sso and #EnableResourceServer (client and resource behavior in the same app)

I know that there are some similar topics but they are about implementation difficulties, whereas my question is more architect wise.
And it is generally not springframework related.
Let's say there is an application that implements both client\resource (in terms of OAuth2) behaviors.
Also it supports Basic auth with for testing purposes (ans it has its own set of static\ldap users ).
Auth provider is done as a separate application.
This "three-type" auth is reached by
#Configuration
#Order(Ordered.HIGHEST_PRECEDENCE)
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(request -> {
String auth = request.getHeader("Authorization");
return (auth != null && auth.startsWith("Basic"));
})
.authorizeRequests()
.antMatchers("/", "/login**").permitAll()
.anyRequest().authenticated()
.and().csrf().disable()
.httpBasic()
;
}
....
}
then goes
#Configuration
#EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
private final static Logger logger = LoggerFactory.getLogger(OAuth2ResourceServerConfig.class);
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(request -> {
String auth = request.getHeader("Authorization");
return (auth != null && auth.startsWith("Bearer"));
})
.authorizeRequests()
.anyRequest().authenticated();
}
....
}
and then
#Configuration
#EnableOAuth2Sso
#Order(4)
public class OAuth2SsoConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests()
.antMatchers("/", "/login**").permitAll()
.anyRequest().authenticated()
.and().csrf().disable()
;
}
....
}
all in one package (altogether with UI).
That works pretty well. But.
Is that good at all to have it like that?
Some systems which this app integrates with already have "client" behavior itself (like SalesForce), so UI and #EnableOAuth2Sso configuration seem to be dead weight.
Am I missing something in terms of security vulnerabilities? I was able to see that once one bearer token is accepted by app, it creates session and postman sends cookie back to the app on the next request and app manages this session even if another bearer token(for another user) has been applied to the Authorization header.
Does it make sense to customize this via maven profiles or via splitting it to the separate apps (pure UI&client and Resource API)?
Three options as I see it:
Thanks.

Dynamically Configure LDAP Server using Spring Security

The Spring Security Tutorial has an example of configuring an LDAP Server:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
#Configuration
protected static class AuthenticationConfiguration extends
GlobalAuthenticationConfigurerAdapter {
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource().ldif("classpath:test-server.ldif");
}
}
}
However, I'm looking for a way to initialize the the LDAP server dynamically, not in the configuration file. I can't seem to find any examples. The purpose of this is to implement SSO for a login form.
I found it easier to work with a lower-level directory, ldaptive, to solve this problem.

Spring Web Security logout not working with httpBasic authentication

I'm using basic authentication to secure an initial REST web service that I'm working on. Everything seems to work okay, except the logout path does not seem to work. It redirects to "/login?logout", as documented, but my user does not seem to actually be logged out. (ie. I can still access page X and not page Y as expected).
Application config:
#Configuration
#ComponentScan
#EnableAutoConfiguration(exclude = ManagementSecurityAutoConfiguration.class)
#EnableWebSecurity
#EnableSwagger
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
#Configuration
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and().authorizeRequests().antMatchers("/manage/**").hasRole("ADMIN")
.anyRequest().fullyAuthenticated()
.and().logout().permitAll().logoutRequestMatcher(new AntPathRequestMatcher("/logout", HttpMethod.GET.toString())).invalidateHttpSession(true);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN", "USER").and().withUser("user").password("user").roles("USER");
}
}
}
Please note that security in general looks to be working. I can open a new incognito tab and the authentication / security works as expected.
You cannot logout from basic http authentication with a logout link.
Please check a similar thread here.

Categories

Resources