Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 146 Vote(s) - 3.65 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Difference between registerGlobal(), configure(), configureGlobal(),configureGlobalSecurity in Spring security

#1
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?

1. registerGlobal
2. configure
3. configureGlobal
4. 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");
}
Reply

#2
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"][1] from the "Hello Spring Security Java Config" guide.*

<br>
`protected void configure(AuthenticationManagerBuilder auth)` is a method that is likely provided by [`WebSecurityConfigurer`][2] (and its interface `WebSecurityConfigurer`) - I would say that is just a more type save approach, but does not differ in its result.


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#3
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][1], [@EnableWebMvcSecurity][2], [@EnableGlobalMethodSecurity][3], or [@EnableGlobalAuthentication][4]
- (and of course the method have an argument of type [`AuthenticationManagerBuilder `][5])

(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`][6] (or any @Configuration class implementing [`WebSecurityConfigurer`][7]) but it have the same effect as the other option.

<br>
### 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][7] 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`][8]. 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

<br>
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");
}
}

<br>
**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");
}
}

[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

[4]:

[To see links please register here]

[5]:

[To see links please register here]

[6]:

[To see links please register here]

[7]:

[To see links please register here]

[8]:

[To see links please register here]

Reply

#4
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`.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through