i am using spring security in my spring boot project i want i cant overide configure method
#Configuration
#EnableWebSecurity
class SecConfig extends WebSecurityConfigurer {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
#Override
protected void configure(HttpSecurity http) throws Exception {
}
}
i tried many it time but i cant overide the configure method
you are extending the class with "webSecurityConfigurer" .Try to extend it with
"WebSecurityConfigurerAdapter"
Using Spring Boot 1.5.2.RELEASE and Java 8
I'm trying to understand, what goes in public void configure(HttpSecurity http) method of WebSecurityConfigurerAdapter and of ResourceServerConfigurerAdapter?
With the following code, configure(HttpSecurity http) method of ResourceServerConfigurerAdapter is taking precedence over WebSecurityConfigurerAdapter. All the changes I'm doing in ResourceServerConfiguration is taking effect, it appears that WebSecurityConfigurerAdapteris ignored completely.
When we use these methods (use case)? And, is override of WebSecurityConfigurerAdapter.configure(..) method even required for grant type password
Using security.oauth2.resource.filter-order = 3
Without this property I keep getting 403 Access Denied
The default order of the OAuth2 resource filter has changed from 3 to SecurityProperties.ACCESS_OVERRIDE_ORDER - 1
WebSecurityConfiguration
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/unsecured").permitAll()
.antMatchers("/users").hasRole("USER")
.antMatchers("/api/secured").hasRole("ADMIN")
.antMatchers("/api/admin").authenticated()
.antMatchers("/greeting").authenticated();
}
}
Resource Server
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.anyRequest().permitAll();
}
}
I think you have the answer here, please check out the solution given
Spring Security OAuth2, which decides security?
I am configuring spring security,below is my code-
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(encoder);
}
#Bean(name="encoder")
public BCryptPasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
...
}
As soon as I applied #Autowire on-
#Override
#Autowire
protected void configure(HttpSecurity http) throws Exception {
...
}
This throws exception no bean of type 'HttpSecurity' in container,this is expected.
But when I applied #Autowire on-
#Override
#Autowire
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(encoder);
}
There is no exception?how this AuthenticationManagerBuilder bean is in bean factory?
when I changed my bean registration with private method like this-
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(getPasswordEncoder());
}
#Bean(name="encoder")
private BCryptPasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder();
}
This is throwing exception,method cant be private.Why so?
From the Spring Documentation
Typically, #Bean methods are declared within #Configuration classes. In this case, bean methods may reference other #Bean methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable. Such so-called 'inter-bean references' are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would. These are the semantics known from the original 'Spring JavaConfig' project which require CGLIB subclassing of each such configuration class at runtime. As a consequence, #Configuration classes and their factory methods must not be marked as final or private in this mode
Ref link
I have below three code snippets all doing the same thing: creating in-memory authentication. So how it impacts defining it in different method names?
registerGlobal
configure
configureGlobal
configureGlobalSecurity
First one:
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER","ADMIN");
}
}
Second one:
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
Third one:
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
Fourth:
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");
}
UPDATE 1 :
One more thing I would like to add:
configure() method is present in WebSecurityConfigurerAdapter class while others are not present.
UPDATE 2:
I renamed the method in my sample project to below and to my surprise it is working and authenticating the users.
you name it anything and it works
#Autowired
public void anyMethodName(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");
}
In fact, you only have 2 different options.
Option 1: using annotations only (it cover your example 1, 3 and 4 - note that you didn't include relevant annotations in your samples)
registerGlobal, configureGlobal, configureGlobalSecurity are exact same way of doing things. You can name the method according your tastes. The only constraints are :
annotate the method with #Autowired
the method MUST be in a class annotated with one of the following : #EnableWebSecurity, #EnableWebMvcSecurity, #EnableGlobalMethodSecurity, or #EnableGlobalAuthentication
(and of course the method have an argument of type AuthenticationManagerBuilder)
(as you can see the name of the method is not important, that is why you found so many different method name when googling for code samples)
Here is an example of how it looks like :
#EnableWebSecurity
public class MyConfiguration {
#Autowired
public void whatever(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
...
}
Option 2: using annotations + method overriding (it cover your example 2)
Overriding configure is a convenient approach in a subclass of WebSecurityConfigurerAdapter (or any #Configuration class implementing WebSecurityConfigurer) but it have the same effect as the other option.
How to choose the correct approach?
It's only a question of taste/programming-style because both approachs have the same effect.
The first option make sense when you want/need to keep your configuration in a single class, but your #Configuration class already extends some other class (and you don't want to implement the whole WebSecurityConfigurer interface).
Let's explain my last point in more details. Spring provides many Adapter classes that you can extends to speed up the development of your Spring configuration.
As an example, let's take a commonly used Adapter : WebMvcConfigurerAdapter. You will start with a very simple configuration like this :
#EnableWebMvc
#Configuration
#ComponentScan({ "com.company.mypackage" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
}
What's important here : your class already extends an Adapter class, so you can't extends another one
Now, you need to add security configuration. You have the choice between including it in your existing SpringWebConfig configuration class or create a new security specific configuration class. Here is a sample of both approaches:
1) Single #Configuration class approach
What's important to note here : SpringWebConfig extends WebMvcConfigurerAdapter + #EnableWebSecurity
#EnableWebMvc
#Configuration
#ComponentScan({ "com.company.mypackage" })
#EnableWebSecurity
public class SpringWebConfig extends WebMvcConfigurerAdapter {
#Autowired
public void whatever(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
}
2) Specific security #Configuration class
What's important to note here : MySecurityConfig extends WebSecurityConfigurerAdapter
Keep your SpringWebConfig as it was and create a new #Configuration class :
#Configuration
#EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
#Overide
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
}
For the difference between: registerGlobal(AuthenticationManagerBuilder auth) and configureGlobal(AuthenticationManagerBuilder auth)
The name of the configureGlobal method is not important. However, it is important to only configure AuthenticationManagerBuilder in a class annotated with either #EnableWebSecurity, #EnableWebMvcSecurity, #EnableGlobalMethodSecurity, or #EnableGlobalAuthentication. Doing otherwise has unpredictable results.
Source:
Chapter "Creating your Spring Security configuration" from the "Hello Spring Security Java Config" guide.
protected void configure(AuthenticationManagerBuilder auth) is a method that is likely provided by WebSecurityConfigurer (and its interface WebSecurityConfigurer) - I would say that is just a more type save approach, but does not differ in its result.
Very good answers here. Lemme talk some vanilla spring (no boot) in this regard. When we extend GlobalMethodSecurityConfiguration in our security configurations class, the difference between:
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception{...}
and:
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {...}
is HUGE!
First of all, it's important to realize that the name of the method configureGlobal is meaningless. From the #Autowired JavaDoc we learn:
Config methods may have an arbitrary name and any number of arguments; each of those arguments will be autowired with a matching bean in the Spring container.
What's important in this regard is that configureGlobal does not override any method of the GlobalMethodSecurityConfiguration super class and that it's annotated with #Autowired. If we ask what exactly is auto-wired in this method - the answer would be the AuthenticationManagerBuilder - 'auth' argument.
We could try to declare the method as:
protected void configureGlobal(#Autowired AuthenticationManagerBuilder auth) throws Exception {...}
but again, the #Autowired annotation JavaDocs says:
Although #Autowired can technically be declared on individual method or constructor parameters since Spring Framework 5.0, most parts of the framework ignore such declarations. The only part of the core Spring Framework that actively supports autowired parameters is the JUnit Jupiter support in the spring-test module (see the TestContext framework reference documentation for details).
In essence, we won't get any auto-wiring for the 'auth' argument, so there goes this wrong attempt down the drain.
We're left to declare auto-wiring on the method level, which auto-wires the single argument 'auth'.
(proper) Auto-wiring means that spring is able to find a bean of the type AuthenticationManagerBuilder in the context and inject it into the method argument. A bean of this type must be already instantiated in order for spring to inject it. I won't go into the question who instantiates this particular bean but it must exist. Anyhoo... If auto-wiring worked - it's there!
However, when we use the #Override protected void configure(AuthenticationManagerBuilder auth) and override a super-class method, it becomes responsible for instantiating the AuthenticationManagerBuilder object. Whether the super-class obtained it from the application context or instantiated it using the new operator, is none of our concern in this case.
These are just nuances and they are not so important as the big question - when does all of this happen? This brings me to the most important difference which is lifecycle.
When we override spring configuration class methods, we are unwittingly (or wittingly - depends...) taking an active part in the Hollywood Principal of 'don't call us...'.
The super class is responsible for calling our overridden methods in a predefined order. This goes hand in hand with GoF's Template Design Pattern and their concept of hooks, along with the Builder pattern. Overriding methods of a Spring configuration super-class is just fine-tuning the build process without changing the construction order.
So why is this so important?
Let me show you an example by which we want to configure a Spring Security InMemoryUserDetailsManager without resorting to coding our own bean (which is really not an issue, but not the demonstrated case here). We will need to keep a reference to the InMemoryUserDetailsManager that spring build for us, for a later custom MethodSecurityExpressionHandler. The expression handler augments the expression context with nifty little Pre/Post security expressions that are used, for example in methods such as:
#PreAuthorize("isFamilyMember(#username) or isCatOnMouse(#username)")
public void changePassword(String username) throws AuthenticationException;
Here goes option 2: Overriding method configure
#Configuration
#EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true)
public class ExampleSecurityConfig extends GlobalMethodSecurityConfiguration {
private InMemoryUserDetailsManager inMemoryUserDetailsManager;
#Override #Bean protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Bean public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
inMemoryUserDetailsManager // we want this reference!
= (InMemoryUserDetailsManager) auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder())
.withUser("tom")
.password("password")
.authorities("ROLE_CAT")
.and()
.getUserDetailsService();
}
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
CustomExpressionHandler expressionHandler =
new CustomExpressionHandler(inMemoryUserDetailsManager); //cannot be null!
return expressionHandler;
}
}
On one hand, we want to avoid coding redundant beans - but on the other we need to be able to reference those beans/components/services that Spring builds for us with it's nice fluent (and too complex for my liking) API. But we fail miserably!
The Hollywood Principal bites us in the rear. When we use this configuration, the super-class calls the overridden methods in it's own algorithm and the result in this case is that method createExpressionHandler() is called before method configure(AuthenticationManagerBuilder auth). Naturally, this triggers a null reference to inMemoryUserDetailsManager and obviously we'll see a NullPointerException that will crash the container startup with a BeanInsantiationException or an IllegalState... and a stack trace that will ruin our day. Not a pretty console site!
option 1: Not overriding method configure:
#Configuration
#EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true)
public class ExampleSecurityConfig extends GlobalMethodSecurityConfiguration {
#Autowired DataSource dataSource;
private InMemoryUserDetailsManager inMemoryUserDetailsManager;
#Override #Bean protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Bean public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
protected void configureBlah(AuthenticationManagerBuilder auth) throws Exception {
inMemoryUserDetailsManager // we want this reference!
= (InMemoryUserDetailsManager) auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder())
.withUser("tom").password("password").authorities("ROLE_CAT")
.and()
.getUserDetailsService();
}
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
CustomExpressionHandler expressionHandler =
new CustomExpressionHandler(inMemoryUserDetailsManager); // this arg cannot be null!
return expressionHandler;
}
}
In this case, the method configureBlah(...), call it whatever you want, belongs to to our own ExampleSecurityConfig class, it is #Autowired, so spring will inject the AuthenticationManagerBuilder argument and it will be invoked before any of the super-class methods that are not a #PostConstruct or defined in some XML beans file as an init-method. This time around, we get the desired reference to inMemoryUserDetailsManager and our application works as expected.
It's all about lifecycle.
I am trying to setup a single path (/basic) in my spring-boot spring MVC based application to be basic auth protected. I am just going to configure this using my own custom configuration parameters so the username and password are simply "admin" and "admin".
This currently works for the /basic path (I am prompted and can login correctly). The problem is that logout does not work (and I am not sure why) and also other paths (like /other shown) are being asked for basic auth credentials (before always being denied).
static class MyApplicationSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/open").permitAll();
http.authorizeRequests().antMatchers("/other").denyAll(); // Block it for now
http.authorizeRequests().antMatchers("/basic").authenticated().and().httpBasic().and().logout().logoutUrl("/basic/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
}
}
I expected /other to always be denied but I don't get why basic auth is coming up for it. /open works as expected. I also don't understand why /basic/logout does not log me out (it also does not produce error messages). I do have a simple bit of code as a placeholder for the logout endpoint but if I do not have that then I get a 404. The "home" view is my web app root so I just want to send the user there after logout.
#RequestMapping("/logout")
public ModelAndView logout() {
// should be handled by spring security
return new ModelAndView("home");
}
UPDATE:
Here is the solution that seemed to work in the end (except the logout part, still not working):
#Configuration
#Order(1) // HIGHEST
public static class OAuthSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/oauth").authorizeRequests().anyRequest().denyAll();
}
}
#Configuration
public static class BasicAuthConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/basic").authorizeRequests().anyRequest().authenticated().and().httpBasic();
http.logout().permitAll().logoutUrl("/logout").logoutSuccessUrl("/").invalidateHttpSession(true);
//.and().logout().logoutUrl("/basic/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
}
}
i'm not sure about the logout, but we had a similar problem with having some of our site under basic and some of it not. Our solution was to use a second nested configuration class only for the paths that needed http basic. We gave this config an #Order(1)..but i'm not sure if that was necessary or not.
Updated with code
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
private static final Logger LOG = LoggerFactory.getLogger(SecurityConfig.class);
#Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth, Config appConfig) throws Exception {
auth.inMemoryAuthentication()
.withUser(appConfig.getString(APIConfig.CONFIG_KEY_MANAGEMENT_USER_NAME))
.password(appConfig.getString(APIConfig.CONFIG_KEY_MANAGEMENT_USER_PASS))
.roles(HyperAPIRoles.DEFAULT, HyperAPIRoles.ADMIN);
}
/**
* Following Multiple HttpSecurity approach:
* http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity
*/
#Configuration
#Order(1)
public static class ManagerEndpointsSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/management/**").authorizeRequests().anyRequest().hasRole(HyperAPIRoles.ADMIN).and()
.httpBasic();
}
}
/**
* Following Multiple HttpSecurity approach:
* http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity
*/
#Configuration
public static class ResourceEndpointsSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
//fyi: This adds it to the spring security proxy filter chain
.addFilterBefore(createBBAuthenticationFilter(), BasicAuthenticationFilter.class)
;
}
}
}
this seems to secure the actuator endpoints at /management with basic auth while the others work with a custom auth token header. We do not prompt for credentials (no challenge issued) though for anything..we'd have to register some other stuff to get that going (if we wanted it).
Hope this helps
only one path will be protected
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception
{
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("user"))
.roles("USER");
}
#Configuration
#Order(1)
public static class ManagerEndpointsSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/add/**").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic()
.and().csrf().disable();
}
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}