Spring Boot Security

Posted vicky-project

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot Security相关的知识,希望对你有一定的参考价值。

Spring Boot Security

Spring Boot includes an additional set of tools that can make the application development time a little more faster by reducing its restart time.


Security

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-security.html

If Spring Security is on the classpath, then web applications are secured by default. Spring Boot relies on Spring Security’s content-negotiation strategy to determine whether to use httpBasic orformLogin. To add method-level security to a web application, you can also add@EnableGlobalMethodSecurity with your desired settings.

The default UserDetailsService has a single user. The user name is user, and the password is random and is printed at INFO level when the application starts:

Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35

Note: org.springframework.boot.autoconfigure.security category is set to log INFO-level. You can change the username and password by providing a spring.security.user.name and spring.security.user.password.

The basic features you get by default in a web application are:

  • UserDetailsService (or ReactiveUserDetailsService in case of a WebFlux application) bean with in-memory store and a single user with a generated password (see SecurityProperties.User for the properties of the user).
  • Form-based login or HTTP Basic security (depending on Content-Type) for the entire application (including actuator endpoints if actuator is on the classpath).
  • DefaultAuthenticationEventPublisher for publishing authentication events.

You can provide a different AuthenticationEventPublisher by adding a bean for it.

MVC Security

The default security configuration is implemented in SecurityAutoConfiguration andUserDetailsServiceAutoConfigurationSecurityAutoConfigurationimportsSpringBootWebSecurityConfiguration for web security and UserDetailsServiceAutoConfiguration configures authentication, which is also relevant in non-web applications. To switch off the default web application security configuration completely, you can add a bean of typeWebSecurityConfigurerAdapter (doing so does not disable the UserDetailsService configuration or Actuator’s security).

To also switch off the UserDetailsService configuration, you can add a bean of typeUserDetailsServiceAuthenticationProvider, or AuthenticationManager. There are several secure applications in the Spring Boot samples to get you started with common use cases.

Access rules can be overridden by adding a custom WebSecurityConfigurerAdapter. Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources. EndpointRequest can be used to create a RequestMatcher that is based on themanagement.endpoints.web.base-path property. PathRequest can be used to create a RequestMatcher for resources in commonly used locations.

WebFlux Security

Similar to Spring MVC applications, you can secure your WebFlux applications by adding the spring-boot-starter-security dependency. The default security configuration is implemented inReactiveSecurityAutoConfiguration and UserDetailsServiceAutoConfiguration.ReactiveSecurityAutoConfigurationimports WebFluxSecurityConfiguration for web security andUserDetailsServiceAutoConfiguration configures authentication, which is also relevant in non-web applications. To switch off the default web application security configuration completely, you can add a bean of type WebFilterChainProxy (doing so does not disable the UserDetailsService configuration or Actuator’s security).

To also switch off the UserDetailsService configuration, you can add a bean of typeReactiveUserDetailsService or ReactiveAuthenticationManager.

Access rules can be configured by adding a custom SecurityWebFilterChain. Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources. EndpointRequest can be used to create a ServerWebExchangeMatcher that is based on themanagement.endpoints.web.base-path property.

PathRequest can be used to create a ServerWebExchangeMatcher for resources in commonly used locations.

For example, you can customize your security configuration by adding something like:

[email protected]_
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
return http
	.authorizeExchange()
		.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
		.pathMatchers("/foo", "/bar")
			.authenticated().and()
		.formLogin().and()
	.build();
}

EnableGlobalMethodSecurity

We can enable annotation-based security using the @EnableGlobalMethodSecurity annotation on any@Configuration instance. For example, the following would enable Spring Security’s @Securedannotation.

@EnableGlobalMethodSecurity(securedEnabled = true)_
public class MethodSecurityConfig {
// ...
}

Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. Spring Security’s native annotation support defines a set of attributes for the method. These will be passed to the AccessDecisionManager for it to make the actual decision:

public interface BankService {

@Secured("IS_AUTHENTICATED_ANONYMOUSLY")_
public Account readAccount(Long id);

@Secured("IS_AUTHENTICATED_ANONYMOUSLY")_
public Account[] findAccounts();

@Secured("ROLE_TELLER")_
public Account post(Account account, double amount);
}

Support for JSR-250 annotations can be enabled using

@EnableGlobalMethodSecurity(jsr250Enabled = true)_
public class MethodSecurityConfig {
// ...
}

These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security’s native annotations. To use the new expression-based syntax, you would use

@EnableGlobalMethodSecurity(prePostEnabled = true)_
public class MethodSecurityConfig {
// ...
}

and the equivalent Java code would be

public interface BankService {

@PreAuthorize("isAnonymous()")_
public Account readAccount(Long id);

@PreAuthorize("isAnonymous()")_
public Account[] findAccounts();

@PreAuthorize("hasAuthority(‘ROLE_TELLER‘)")_
public Account post(Account account, double amount);
}

GlobalMethodSecurityConfiguration

Sometimes you may need to perform operations that are more complicated than are possible with the @EnableGlobalMethodSecurity annotation allow. For these instances, you can extend theGlobalMethodSecurityConfiguration ensuring that the @EnableGlobalMethodSecurity annotation is present on your subclass. For example, if you wanted to provide a custom MethodSecurityExpressionHandler, you could use the following configuration:

@EnableGlobalMethodSecurity(prePostEnabled = true) public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityExpressionHandler createExpressionHandler() { // … create and return custom MethodSecurityExpressionHandler … return expressionHandler; } }

For additional information about methods that can be overridden, refer to theGlobalMethodSecurityConfiguration Javadoc.

EnableReactiveMethodSecurity

Spring Security supports method security using Reactor’s Context which is setup usingReactiveSecurityContextHolder. For example, this demonstrates how to retrieve the currently logged in user’s message.

For this to work the return type of the method must be a org.reactivestreams.Publisher (i.e.Mono/Flux). This is necessary to integrate with Reactor’s Context.

Authentication authentication = new TestingAuthenticationToken(“user”, “password”, “ROLE_USER”);

Mono messageByUsername = ReactiveSecurityContextHolder.getContext() .map(SecurityContext::getAuthentication) .map(Authentication::getName) .flatMap(this::findMessageByUsername) // In a WebFlux application the `subscriberContext` is automatically setup using `ReactorContextWebFilter` .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));

StepVerifier.create(messageByUsername) .expectNext(“Hi user”) .verifyComplete();

with this::findMessageByUsername defined as:

Mono findMessageByUsername(String username) { return Mono.just("Hi " + username); }

Below is a minimal method security configuration when using method security in reactive applications.

@EnableReactiveMethodSecurity public class SecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsService() { User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); UserDetails rob = userBuilder.username(“rob”).password(“rob”).roles(“USER”).build(); UserDetails admin = userBuilder.username(“admin”).password(“admin”).roles(“USER”,”ADMIN”).build(); return new MapReactiveUserDetailsService(rob, admin); } }

Consider the following class:

@Component public class HelloWorldMessageService { @PreAuthorize(“hasRole(‘ADMIN’)”) public Mono findMessage() { return Mono.just("Hello World!"); } }

Combined with our configuration above, @PreAuthorize("hasRole(‘ADMIN‘)") will ensure thatfindByMessage is only invoked by a user with the role ADMIN. It is important to note that any of the expressions in standard method security work for @EnableReactiveMethodSecurity. However, at this time we only support return type of Boolean or boolean of the expression. This means that the expression must not block.

When integrating with Section 5.6, “WebFlux Security”, the Reactor Context is automatically established by Spring Security according to the authenticated user.

@EnableWebFluxSecurity @EnableReactiveMethodSecurity public class SecurityConfig {

[email protected]_
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception {
	return http
		// Demonstrate that method security works
		// Best practice to use both for defense in depth
		.authorizeExchange()
			.anyExchange().permitAll()
			.and()
		.httpBasic().and()
		.build();
}

[email protected]_
MapReactiveUserDetailsService userDetailsService() {
	User.UserBuilder userBuilder = User.withDefaultPasswordEncoder();
	UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build();
	UserDetails admin = userBuilder.username("admin").password("admin").roles("USER","ADMIN").build();
	return new MapReactiveUserDetailsService(rob, admin);
} }

You can find a complete sample in hellowebflux-method

OAuth2

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-security.html

Client

If you have spring-security-oauth2-client on your classpath, you can take advantage of some auto-configuration to make it easy to set up an OAuth2 Client. This configuration makes use of the properties under OAuth2ClientProperties.

You can register multiple OAuth2 clients and providers under the ` spring.security.oauth2.client` prefix, as shown in the following example:

spring.security.oauth2.client.registration.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.my-client-1.client-	secret=password
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=http://my-auth-	server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=http://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=http://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=http://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name

By default, Spring Security’s OAuth2LoginAuthenticationFilter only processes URLs matching/login/oauth2/code/*. If you want to customize the redirect-uri-template to use a different pattern, you need to provide configuration to process that custom pattern. For example, you can add your own WebSecurityConfigurerAdapter that resembles the following:

public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {

@Override_
protected void configure(HttpSecurity http) throws Exception {
	http
		.authorizeRequests()
			.anyRequest().authenticated()
			.and()
		.oauth2Login()
			.redirectionEndpoint()
				.baseUri("/custom-callback");
}
}

For common OAuth2 and OpenID providers, including Google, Github, Facebook, and Okta, we provide a set of provider defaults (googlegithubfacebook, and okta, respectively).

If you do not need to customize these providers, you can set the provider attribute to the one for which you need to infer defaults. Also, if the ID of your client matches the default supported provider, Spring Boot infers that as well.

In other words, the two configurations in the following example use the Google provider:

spring.security.oauth2.client.registration.my-client.client-id=abcd
spring.security.oauth2.client.registration.my-client.client-secret=password
spring.security.oauth2.client.registration.my-client.provider=google

spring.security.oauth2.client.registration.google.client-id=abcd
spring.security.oauth2.client.registration.google.client-secret=password

Server

Currently, Spring Security does not provide support for implementing an OAuth 2.0 Authorization Server or Resource Server. However, this functionality is available from the Spring Security OAuthproject, which will eventually be superseded by Spring Security completely. Until then, you can use the spring-security-oauth2-autoconfigure module to easily set up an OAuth 2.0 server; see its documentation for instructions.

Actuator Security

For security purposes, all actuators other than /health and /info are disabled by default. Themanagement.endpoints.web.exposure.include property can be used to enable the actuators.

If Spring Security is on the classpath and no other WebSecurityConfigurerAdapter is present, the actuators are secured by Spring Boot auto-config. If you define a custom WebSecurityConfigurerAdapter, Spring Boot auto-config will back off and you will be in full control of actuator access rules.

Before setting the management.endpoints.web.exposure.include, ensure that the exposed actuators do not contain sensitive information and/or are secured by placing them behind a firewall or by something like Spring Security.

Cross Site Request Forgery Protection

Since Spring Boot relies on Spring Security’s defaults, CSRF protection is turned on by default. This means that the actuator endpoints that require a POST (shutdown and loggers endpoints), PUT or DELETE will get a 403 forbidden error when the default security configuration is in use.

Additional information about CSRF protection can be found in the Spring Security Reference Guide.


Disable Spring Boot security configuration

https://stackoverflow.com/questions/40228036/how-to-turn-off-spring-security-in-spring-boot-application

https://stackoverflow.com/questions/49258766/spring-boot-2-0-x-disable-security-for-certain-profile

 

 

 

 


Footnotes

以上是关于Spring Boot Security的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 应用程序中包含 Spring Security

没有 Spring Boot 的 Spring Security SAML 身份元数据

Spring Boot + Spring Security Restful 登录

spring boot + spring security + jwt + React 不工作

防止 Spring Boot 注册 Spring Security 过滤器之一

Spring Boot - Spring Security CSRF 保护未在登录页面中注入令牌