I'm trying to do my second app using Spring Boot. I have problems with security config even if I use permittAll method. Here's part of my code with WebSecurityConfig:
#Configuration
#EnableWebSecurity(debug=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
MyUserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/register").permitAll()
.antMatchers("/users").authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Bean
public DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(userDetailsService);
return provider;
}
}
When I use Postman on /register I have 401 Unauthorised, tried to do it many ways but have no idea what to do anymore. Of course, Rest controller handles /register and /users.
Thank you in advance for any help.
Related
So in my Spring boot RESTful API my /logout mapping gets redirected to /login.
I already googled this problem and found a solution, but I do not know how to implement it with my code.
My WebSecurityConfig:
#Configuration
#AllArgsConstructor
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class
WebSecurityConfig extends WebSecurityConfigurerAdapter {//provides security for endpoints
#Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
#Autowired
private UserDetailsService jwtUserDetailsService;
#Autowired
private JwtRequestFilter jwtRequestFilter;
private final AccountService accountService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()//So we can send post requests without being rejected(if we using form based indication we want to enable this)
.authorizeRequests()
.antMatchers("/login", "/authenticate")
.permitAll()//any request that goes trough that end point we want to allow.
.anyRequest()
.authenticated().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login").and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
http.cors();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
#Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider =
new DaoAuthenticationProvider();
provider.setPasswordEncoder(bCryptPasswordEncoder);
provider.setUserDetailsService(jwtUserDetailsService);
return provider;
}
This does not work, so I tried to do it like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()//So we can send post requests without being rejected(if we using form based indication we want to enable this)
.authorizeRequests()
.antMatchers("/login", "/authenticate")
.permitAll()//any request that goes trough that end point we want to allow.
.anyRequest()
.authenticated().and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.and().addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
http.cors();
}
But this also does not work.
I know this piece of code :
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
Should fix my problem but it does not. Can anyone help me?
Thanks!
I have spring boot app with thymeleaf. I am using spring security formLogin method for security and now I need to add JWT for only some APIs.
#EnableWebSecurity
public class SecurityConfigurations {
#Autowired
UserDetailsServiceImpl userDetails;
#Bean
DaoAuthenticationProvider provider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(encoder());
provider.setUserDetailsService(userDetails);
return provider;
}
#Bean
PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
#Configuration
#Order(1)
public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
#Autowired
private JwtRequestFilter jwtRequestFilter;
#Autowired
DaoAuthenticationProvider provider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(provider);
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/api/user/authenticate").permitAll()
.antMatchers("/api/user/**").hasRole("USER")
.and().
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add a filter to validate the tokens with every request
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
#Configuration
public static class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Autowired
DaoAuthenticationProvider provider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(provider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
.anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
.loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
.invalidateHttpSession(false).and().csrf().disable().cors();
}
}
}
by doing this JWT is working fine as just I need but the formlogin has stopped and calling "/signInProcess" now give 404:
NOTE: if I change the order and make formLogin #order(1) it works again but of course will not work.
Also I tried to combine them both like this now it is both works fine but the problem with exception handling if the JWT authentication error will return formlogin thymeleaf error page :
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
.antMatchers("/api/user/authenticate").permitAll()
.antMatchers("/api/user/**").hasRole("USER")
.anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
.loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
.invalidateHttpSession(false).and().csrf().disable().cors();
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
any suggestions to make this work. thank you.
Your WebSecurityConfigurerAdapters will process the incoming requests in order.
Since JWTSecurityConfig is annotated with #Order(1) it will process the requests first.
You have not specified a antMatcher for this Adapter, so it will match all requests.
This means that a request will never reach FormLoginConfigurationAdapter, since JWTSecurityConfig matches them all.
If you want JWTSecurityConfig to only apply to certain requests, you can specify an antMatcher in your security configuration.
Below is an example:
#EnableWebSecurity
public class SecurityConfigurations {
#Configuration
#Order(1)
public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers(matchers -> matchers
.antMatchers("/api/**") // apply JWTSecurityConfig to requests matching "/api/**"
)
.authorizeRequests(authz -> authz
.anyRequest().authenticated()
)
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
#Configuration
public class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authz -> authz
.anyRequest().authenticated()
)
.formLogin();
}
}
}
For more details on multiple WebSecurityConfigurerAdapter, you can see the multiple HttpSecurity section in the Spring Security reference docs.
For more details on the difference between authorizeRequests() and requestMatchers(), you can see this Stack Overflow question.
I am trying to set up multiple WebsecurityConfigurerAdapter for my project where the spring boot actuator APIs are secured using basic auth and all other endpoints are authenticated using JWtAuthentication. I am just not able to make it work together, only the config with the lower order works. I am using Spring Boot 2.1.5.RELEASE
Security Config One with JWT Authenticator
#Order(1)
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_WHITELIST = {
"/docs/**",
"/csrf/**",
"/webjars/**",
"/**swagger**/**",
"/swagger-resources",
"/swagger-resources/**",
"/v2/api-docs"
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(AUTH_WHITELIST).permitAll()
.antMatchers("/abc/**", "/abc/pdf/**").hasAuthority("ABC")
.antMatchers("/ddd/**").hasAuthority("DDD")
.and()
.csrf().disable()
.oauth2ResourceServer().jwt().jwtAuthenticationConverter(new GrantedAuthoritiesExtractor());
}
}
The basic Auth config with username/password
#Order(2)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
/* #Bean
public UserDetailsService userDetailsService(final PasswordEncoder encoder) {
final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(
User
.withUsername("user1")
.password(encoder.encode("password"))
.roles("ADMIN")
.build()
);
return manager;
}
#Bean PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/actuator/**").hasRole("ADMIN")
.and()
.httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("password").authorities("ADMIN");
}
}
I have been trying to make it work for many days but cannot make both of them work together. If i swap the order, only basic auth works and not the JWT Auth Manager.
I have gone through a lot of SOF Questions, like
[https://stackoverflow.com/questions/40743780/spring-boot-security-multiple-websecurityconfigureradapter][1]
[https://stackoverflow.com/questions/52606720/issue-with-having-multiple-websecurityconfigureradapter-in-spring-boot][1]
[https://github.com/spring-projects/spring-security/issues/5593][1]
[https://www.baeldung.com/spring-security-multiple-entry-points][1]
Nothing seems to be working, is this a known issue in Spring?
To use multiple WebsecurityConfigurerAdapter, you need restrict them to specific URL patterns using RequestMatcher.
In your case you can set a higher priority for ActuatorSecurityConfig and limit it only to actuator endpoints:
#Order(-1)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/actuator/**")
.and()
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
I have few views made in Vaadin by #Route and now I want to add Security and some Login. In my SecurityConfiguration class I'm setting antMatchers.permitAll() only for 2 views and for the rest with Role ADMIN. But it is not working as I think it should. It demands login to access every view, and after login I have access to all views no matter what role has the user.
I hoped this tutorial will help me, but in there are no views accessible without login.
Securing Your App With Spring Security
My configuration class:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private UserService userService;
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public SecurityConfiguration(UserService userService) {
this.userService = userService;
}
#Autowired
private void configureAuth(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
auth.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder().encode("user"))
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.anonymous()
.and()
.authorizeRequests()
.antMatchers("/", "/login").permitAll()
.antMatchers("/recipe-manager", "/ingredient-manager").hasAnyRole("ADMIN")
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().logoutSuccessUrl("/")
.and()
.csrf().disable().cors().disable().headers().disable();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/VAADIN/**",
"/favicon.ico",
"/robots.txt",
"/manifest.webmanifest",
"/sw.js",
"/offline-page.html",
"/icons/**",
"/images/**",
"/frontend/**",
"/webjars/**",
"/h2-console/**",
"/frontend-es5/**", "/frontend-es6/**");
}
}
My Views have annotations like:
#Route("recipe-manager")
public class RecipeManagerView extends VerticalLayout
#Route("")
public class RecipeBrowserView extends VerticalLayout
#Route("login")
public class LoginView extends VerticalLayout
#Route("ingredient-manager")
public class IngredientManagerView extends VerticalLayout
I would expect that anyone can have access to RecipeBrowserView and LoginView, but only logged user can have access to RecipeManagerView and IngredientMangerView.
You cannot use path based matching from Spring Security for Vaadin routes. Spring Security does the matching based on request paths whereas navigation from one view to another inside Vaadin is sent as metadata inside an internal request that always goes to the same hardcoded path.
Instead, you can implement your access control logic in an interceptor provided by Vaadin. You can have a look at https://vaadin.com/tutorials/securing-your-app-with-spring-security to find out more about this.
To my understanding antMatchers only accept single arguments. You should change you configuration class like:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private UserService userService;
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public SecurityConfiguration(UserService userService) {
this.userService = userService;
}
#Autowired
private void configureAuth(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
auth.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder().encode("user"))
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.anonymous()
.and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/recipe-manager", "/ingredient-manager").hasAnyRole("ADMIN")
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().logoutSuccessUrl("/")
.and()
.csrf().disable().cors().disable().headers().disable();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/VAADIN/**",
"/favicon.ico",
"/robots.txt",
"/manifest.webmanifest",
"/sw.js",
"/offline-page.html",
"/icons/**",
"/images/**",
"/frontend/**",
"/webjars/**",
"/h2-console/**",
"/frontend-es5/**", "/frontend-es6/**");
}
}
I'm fighting a "bug" similar to one Apple had recently in OS X :) An application authenticates users treating their password field not only as a bcrypt hash but also as a plaintext, so it allows special utility accounts to log in with an empty password.
There are a bunch of user records in the database and almost all of them has their password hashed with bcrypt. There are however a few special utility accounts with password hash field deliberately left empty (to make BcryptPasswordEncoder#matches always reject login attempts for them).
Placing breakpoints all over ProviderManager I can see multiple authentication providers initialized by spring:
a "proper" DaoAuthenticationProvider with bcrypt encoder
AnonymousAuthenticationProvider, which nobody configured, but at least I can guess it came from permitAll() or something alike.
an unwanted DaoAuthenticationProvider with PlaintextPasswordEncoder which spoils all fun
We have another project where we don't use Spring Boot and with almost identical configuration it works as expected (passwords are never treated as plaintext, only as bcrypt hash). So my guess is: this "problem" has something to do with Spring Boot "configuration by convention" and I can't find how to override its behavior.
In this project I use the following configuration:
#Configuration
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
AuthenticationProvider authenticationProvider;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.userDetailsService(userDetailsService)
.authorizeRequests()
.antMatchers("/js/**", "/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/j_spring_security_check").permitAll()
.successHandler(new SuccessHandler())
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll()
.logoutSuccessUrl("/login");
http.csrf().disable();
http.headers().frameOptions().sameOrigin();
}
#Autowired
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider);
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(15);
}
}
Edit: If I get it correct, there's a way to configure global and local AuthenticationManagerBuilders:
// Inject and configure global:
/*
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
*/
// Override method and configure the local one:
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
Doing that, I have now two instances of builder: one - local - has only the correct manager: bcrypt, the other one - global - has other 2 providers: anonymous and plaintext. Authentication behavior persists, application still uses both and lets users login with plaintext passwords. Uncommenting configureGlobal doesn't help too, in that case, global manager contains all three providers.
The configuration is explicitly providing the userDetailsService in multiple places without providing the PasswordEncoder. The easiest solution is to expose the UserDetaisService and PasswordEncoder as a Bean and delete all explicit configuration. This works because if there is no explicit configuration, Spring Security will discover the Beans and create authentication from them.
#Configuration
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http // Don't forget to remove userDetailsService
.authorizeRequests()
.antMatchers("/js/**", "/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/j_spring_security_check").permitAll()
.successHandler(new SuccessHandler())
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll()
.logoutSuccessUrl("/login");
http.csrf().disable();
http.headers().frameOptions().sameOrigin();
}
// UserDetailsService appears to be a Bean somewhere else, but make sure you have one defined as a Bean
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(15);
}
}
The reason it is failing is because there is explicit configuration to use the UserDetailsService twice:
#Autowired
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// below Configures UserDetailsService with no PasswordEncoder
auth.userDetailsService(userDetailsService);
// configures the same UserDetailsService (it was used to create the authenticationProvider) with a PasswordEncoder (it was provided to the authenticationProvider)
auth.authenticationProvider(authenticationProvider);
}
If you want explicit configuration, you could use the following
#Override
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
and delete the authenticationProvider bean along with the #Autowired AuthenticationProvider. Alternatively, you could just use the AuthenticationProvider, but not both.
Generally, the explicit configuration of AuthenticationManagerBuilder is only needed when you have multiple WebSecurityConfigurerAdapter with different authentication mechanisms. If you do not have the need for this, I recommend just exposing the UserDetailsService and (optionally) the PasswordEncoder as a Bean.
Note that if you expose a AuthenticationProvider as a Bean it is used over a UserDetailsService. Similarly, if you expose an AuthenticationManager as a Bean it is used over AuthenticationProvider. Finally, if you explicitly provide AuthenticationManagerBuilder configuration, it is used over any Bean definitions.
It turned out that protected void configure(HttpSecurity http) was triggering the second AuthenticationManagerBuilder creation. So I provided my AuthenticationProvider bean and added it to httpsecurity configuration. Everything seems to work as expected now. It might not be the correct solution though.
New configuration (works for me):
#Configuration
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
AuthenticationProvider authenticationProvider;
#Autowired
PasswordEncoder passwordEncoder;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(authenticationProvider) // <== Important
//.anonymous().disable() // <== This part is OK. If enabled, adds an anonymousprovider; if disabled, it is impossible to login due to "unauthenticated<->authenticate" endless loop.
.httpBasic().disable()
.rememberMe().disable()
.authorizeRequests()
.antMatchers("/js/**", "/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/j_spring_security_check").permitAll()
.successHandler(new SuccessHandler())
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll()
.logoutSuccessUrl("/login");
}
#Bean
public AuthenticationProvider authenticationProvider() {
final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(15);
}
}