Spring boot authentication in 2022 - java

I have trouble with figuring out Spring Boot authentication. I am new to Spring Security and recently WebSecurityConfigurerAdapter got deprecated. Is there a source where basic authentication is explained and has some implementations of it?
I wasn't able to find something that would satisfy my request. New sources that I found, provided general view on it. The old ones were point at WebSecurityConfigurerAdapter

In Spring Security 5.7, You need to provide SecurityFilterChain bean.
#Configuration
public class SecurityConfiguration {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults())
.authenticationManager(new CustomAuthenticationManager());
return http.build();
}
}
Reference: https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

Related

Configuring cors in spring boot application. Bean CorsConfigurationSource doesnt work

So i cant configure cors. My angular app cant send api request because of error.
I can do requests by soapUI and they are working fine. But from browser there is:
Access to XMLHttpRequest at 'http://localhost:8080/backend/api/public' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I was looking for answers and they look like my class.
Im using spring boot web security.
#EnableWebSecurity
#Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
#Value(value = "${auth0.apiAudience}")
private String apiAudience;
#Value(value = "${auth0.issuer}")
private String issuer;
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
configuration.setAllowCredentials(true);
configuration.addAllowedHeader("Authorization");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",configuration);
return source;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
JwtWebSecurityConfigurer
.forRS256(apiAudience, issuer)
.configure(http)
.authorizeRequests()
.antMatchers(HttpMethod.GET,"/api/public").permitAll()
.antMatchers(HttpMethod.GET, "/api/private").authenticated()
.antMatchers(HttpMethod.GET, "/api/private-scoped").hasAnyAuthority("read:posts");
}
}
This bean should add this cors header but it doesnt. Maybe you know any better idea of doing this?
What is difference beetwen WebSecurityConfigurerAdapter and WebMvcConfigurerAdapter?
According to this you should add .cors().and() in your configure() method as well.
There are also other possible solutions, for example by setting the CORS-configuration specific to each endpoint as seen here.
If you want to enable CORS for your whole application though, the first way is much prettier.
The difference between WebSecurityConfigurerAdapter and WebMvcConfigurerAdapter is, that WebSecurityConfigurerAdapter is used to configure anything related to the security of your webapp, like authentication and authorization. With the WebMvcConfigurerAdapter you can customize the Java-based configuration for Spring MVC.
I had the same issue and I could not make the CorsConfigurationSource bean work. So I tried a different approach. I didnt use the CorsConfigurationSource bean configuration. Instead, I used the cors registry alternative or Global CORS Configuration.
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowCredentials(true);
}
}
Remove the CorsConfigurationSource configuration bean from your AuthConfig class.
I got this snipped code from https://www.baeldung.com/spring-cors

How to get all actuator endpoints programatically using spring boot 2?

In spring boot 1.x it was possible to resolve all actuator endpoints programatically. I have a bean that exposes all actuator endpoints paths
#Component
public class MyProjectActuatorEndpoints {
#Autowired
private MvcEndpoints endpoints;
public String[] getActuatorEndpointPaths() {
return endpoints.getEndpoints().stream()
.map(MvcEndpoint::getPath)
.map(path -> path + "/**")
.toArray(String[]::new);
}
}
Unfortunately in spring boot actuator 2.0.5.RELEASE there is no such class MvcEndpoints. Is there any replacement for this class in the new spring version?
Everything you need is in the org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints bean. This should set you on the right path, if you'll pardon the pun:
#Slf4j
#Component
public class ActuatorLogger {
public ActuatorLogger(#Autowired PathMappedEndpoints pme) {
log.info("Actuator base path: {}", pme.getBasePath());
pme.getAllPaths().forEach(p -> log.info("Path: {}", p));
}
}
org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest is available to help you set spring security rules for actuator endpoints when you need to do it from code. For example, in your WebSecurityConfigurerAdapter implementation, this fragment could be merged in to your existing rules:
http.authorizeRequests()
.requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))
.hasAnyAuthority("ROLE_ADMIN", "ROLE_SUPPORT")
#Autowired
private HealthEndpoint healthEndpoint;
public Health getAlive() {
return healthEndpoint.health();
}
Spring Boot Actuator 2.x exposes /actuator endpoints as configurable environment variables.
Enabling Acutator Endpoints
You can enable these actuator endpoints in your application.properties
management.endpoints.web.exposure.include=info, health
or (with extreme caution) enable them all. Keep in mind that many of these are sensitive in nature.
management.endpoints.web.exposure.include=*
Securing Actuator Endpoints (reference)
The documentation specifies this as a strategy to secure all endpoints. The EndpointRequest itself would be the closest alternative to what you were looking for (MvcEndpoints)
#Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
.anyRequest().hasRole("ENDPOINT_ADMIN")
.and()
.httpBasic();
}
}
You may also set up a particular antmatcher in case you have a different strategy or role that you would like to assign just to these endpoints
httpRequest.authorizeRequests().antMatcher("/actuator/*").hasRole("ENDPOINT_ADMIN")

Disable security on springboot2 [duplicate]

I want to use Spring Security for JWT authentication. But it comes with default authentication. I am trying to disable it, but the old approach of doing this - disabling it through application.properties - is deprecated in 2.0.
This is what I tried:
#Configuration
public class StackWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable();
// http.authorizeRequests().anyRequest().permitAll(); // Also doesn't work.
}
}
How can I simply disable basic security?
UPDATE
It might be nice to know that I am not using web mvc but web flux.
Screenshot:
According to the new updates in Spring 2.0, if Spring Security is on the classpath, Spring Boot will add #EnableWebSecurity.So adding entries to the application.properties ain't gonna work (i.e it is no longer customizable that way). For more information visit the official website Security changes in Spring Boot 2.0
Albeit not sure about your requirement exactly, I could think of one workaround like the following:-
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests().antMatchers("/").permitAll();
}
}
Hope this helps.
From Spring Boot 2.1 on, if you include spring-boot-actuator, it does not suffice anymore to only exclude SecurityAutoconfiguration, you also need to exclude ManagementWebSecurityAutoConfiguration, like so:
#SpringBootApplication(exclude = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })
According to the reference documentation, the Security configuration for allowing all requests with WebFlux should look like this:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
#Configuration
public class SecurityConfig {
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange().anyExchange().permitAll();
return http.build();
}
}
This worked for me:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().permitAll();
}
}
You can add/modify the following to your Application class:
#SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class MyApplication {
}
Adding some fresh answer, I assume all use actuator, if not I'd bet one class exclusion should be sufficient, I managed to disable through properties:
spring:
autoconfigure:
exclude: ${spring.autoconfigure.sac}, ${spring.autoconfigure.mwsas}
sac: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
mwsas: org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
I've referenced two auto-config classes through property to keep the length intact (note that IntelliJ Ultimate will cry if you reference it like that as it has no clue what are these placeholder values and if they are actually legit classes, so inline if that annoys you).
Application however does not fail to start as claimed by:
https://www.baeldung.com/spring-boot-security-autoconfiguration
if you just disable SecurityAutoConfiguration
If it did work, you will stop seeing auto generated password and it is a little bit less confusing than the accepted answer, as dev reading the log won't get confused by generated password for basic auth while security allows all.
Why just disabling main auto config class isn't enough is because of this fella:
#Configuration
class ManagementWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.requestMatchers(
EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class))
.permitAll().anyRequest().authenticated().and().formLogin().and()
.httpBasic();
}
}
There was tons of work made to split actuator and security config which confused us all, now its more straightforward but artifacts like these still exist. Spring devs will correct me if I am wrong :-).
I have leveraged #ConditionalOnProperty to load the following SecurityConfig.java class if I set spring.security.enabled property to false in my application.yml to disable spring security and it works like a charm.
#ConditionalOnProperty(name = "spring.security.enabled", havingValue = "false")
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/").permitAll();
}
}
If anyone is struggling with this in a WebFlux based application, or a Spring Cloud Gateway application, the below worked for me:
#EnableWebFluxSecurity
public class InsecurityConfiguration {
// #formatter:off
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange().permitAll();
return http.build();
}
}
To disable default security for Spring Boot Reactive Web applications, use the following excludes when you have actuator also in the classpath.
#SpringBootApplication(exclude = {ReactiveSecurityAutoConfiguration.class, ReactiveManagementWebSecurityAutoConfiguration.class })
I think what you are looking for is to override the default authentication entry point which is set to BasicAuthenticationEntryPoint.
This entrypoint adds the
"WWW-Authenticate": "Basic realm=..."
header that tells your browser to use Basic Auth.
If you're extending WebSecurityConfigurerAdapter, you can pass in true to the super constructor to disable the defaults.
You may need to provide other beans if you do this.
/**
* Creates an instance which allows specifying if the default configuration should be
* enabled. Disabling the default configuration should be considered more advanced
* usage as it requires more understanding of how the framework is implemented.
*
* #param disableDefaults true if the default configuration should be disabled, else
* false
*/
protected WebSecurityConfigurerAdapter(boolean disableDefaults) {
this.disableDefaults = disableDefaults;
}
If you want to disable it just for testing purposes -
Rather than completely disabling the auto-configuration, I create an "InsecurityConfiguration" in addition to "SecurityConfiguration", and activate it with either a Spring Profile or Property value.
Technically security is still configured, but wide open.
#Configuration
#ConditionalOnProperty(prefix = "security", value = "disabled", havingValue = "true")
public class InsecurityConfiguration extends WebSecurityConfigurerAdapter {
private final static Logger log = LoggerFactory.getLogger(InsecurityConfiguration.class);
#Override
protected void configure(HttpSecurity http) throws Exception {
log.warn("configuring insecure HttpSecurity");
http.authorizeRequests().anyRequest().permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
log.warn("configuring insecure WebSecurity");
web.ignoring().antMatchers("/**");
}
}
Note This is for mvc, not webflux. For Webflux you should create a SecurityWebFilterChain like Bryan mentioned.
This is how I generally disable basic auth in webflux, when using JWT -
#Bean
public SecurityWebFilterChain configure(ServerHttpSecurity http) {
http
.authorizeExchange().anyExchange().authenticated().and()
.httpBasic().disable()
.formLogin().disable()
.logout().disable()
.oauth2ResourceServer()
.jwt()
.and()
.and().exceptionHandling().accessDeniedHandler(problemSupport);
return http.build();
}
Only properties - works for me (sb2 - 2022):
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
- org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
Simple solution for Spring Boot 2.6
#SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class})
In Spring boot 2, there is no way to disable basic authentication by application.properties file. But the only thing is use annotation
#EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class})
in the main class.
It works
The problem is with org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter
it has private ServerAuthenticationEntryPoint authenticationEntryPoint = new HttpBasicServerAuthenticationEntryPoint();
so to fix it during ServerHttpSecurity initialization add:
http.exceptionHandling().authenticationEntryPoint(HttpStatusServerEntryPoint(HttpStatus.FORBIDDEN))
Looks like vanilla (servlet) spring uses org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer#createDefaultEntryPoint
private AuthenticationEntryPoint createDefaultEntryPoint(H http) {
if (this.defaultEntryPointMappings.isEmpty()) {
return new Http403ForbiddenEntryPoint();
}
if (this.defaultEntryPointMappings.size() == 1) {
return this.defaultEntryPointMappings.values().iterator().next();
}
DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(
this.defaultEntryPointMappings);
entryPoint.setDefaultEntryPoint(this.defaultEntryPointMappings.values().iterator()
.next());
return entryPoint;
}
Side note: mutable fields in builder style beans (like ExceptionTranslationWebFilter) make spring code hard to debug (too magic configuration as well)
You should add #EnableWebSecurity to enable a custom security configuration.
After that simply disable the form login
#Configuration
#EnableWebSecurity
public class StackWebSecurityConfigurerAdapter extends
WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().disable();
}
}
This worked for me
#SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
class SpringApplication{
...
}

Spring security: manually bring back default configuration

I have a spring boot app that works correctly with OAuth2 (as a resource server). There is no custom configure(HttpSecurity http) method. Only
spring-boot-starter-security
spring-security-oauth2
spring-security-jwt
are added to pom.
I needed to add endpoints that should be unprotected. So I added custom config:
#Configuration
public class Security extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(GET, "/public/**").anonymous()
.anyRequest().authenticated()
}
}
Now /public/** endpoints are correctly open for everyone. But all other endpoints stopped working and in the debug level I see:
p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error="access_denied", error_description="Invalid token does not contain resource id (oauth2-resource)"
So I guess I somehow incorrectly overrode the default OAuth2 config. How to bring it back?
i found the answer. following #dur comments, i needed to set resource id in the resource server configuration (as u can see below). i needed to set it to one of resources passed in token's aud field.
#Configuration
class Security extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("my-resource-name");
}
}
but i have no idea why it works without any security configuration as spring's default id is oauth2-resource. seems like it's ignored when there is no config at all

Cannot disable security in spring boot [duplicate]

This question already has answers here:
disabling spring security in spring boot app [duplicate]
(14 answers)
Closed 6 years ago.
I want to disable spring security in my app and I set the property security.basic.enable=false in the application.yml file.
security:
basic:
enabled: false
And I checked the /env using spring-boot-actuator and find it's loaded correctly:(at line 2)
[classpath:/application.yml]":{"spring.datasource.url":"jdbc:mysql://localhost:3306/toe?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true","spring.datasource.username":"root","spring.datasource.password":"******",
"security.basic.enabled":false,
"server.port":7777,"flyway.enabled":false}}
However,the security configuration is still work, I can't access the ones need authenticated, but I can access those are permitAll.
This is the application class:
#SpringBootApplication
#MapperScan("team.xuli.toe.dao")
public class ToeServerApplication {
public static void main(String[] args) {
SpringApplication.run(ToeServerApplication.class, args);}
}
This is the securityConfigutaion:
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.httpBasic();
http.
authorizeRequests()
.antMatchers("/hello").permitAll()
.anyRequest().authenticated();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
System.out.println("user added in mem!");
auth
.inMemoryAuthentication()
.withUser("xqf").password("123").roles("ADMIN");
}
}
If you define a #Configuration with #EnableWebSecurity anywhere in your application it will switch off the default webapp security settings in Spring Boot.
If you need security as a dependency but don't want Spring Boot to configure it for you, you can use this exclusion:
#EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class
})

Categories

Resources