spring-attic / spring-security-oauth

Support for adding OAuth1(a) and OAuth2 features (consumer and provider) for Spring web applications.
http://github.com/spring-projects/spring-security-oauth
Apache License 2.0
4.69k stars 4.04k forks source link

Continue to support Security Context mocked using Spring Security Test #385

Open aisven opened 9 years ago

aisven commented 9 years ago

The change in #360 breaks a test in my project where I am using SecurityMockMvcRequestPostProcessors from Spring Security Test 4.0.0.M2 by Rob Winch to mock the Security Context in Tests of a REST API based on MockMvc.

see http://spring.io/blog/2014/05/23/preview-spring-security-test-web-security#populating-a-test-user-with-a-requestpostprocessor

The mocked Security Context is naturally not based on an OAuth2 Access Token and the Authorization Header is not present in the request. Rather the Security Context it is just installed within the test runtime using the new MockMvc with(user(...)) and with(authentication(...)) patterns.

Therefore the code introduced by c5d6f1f... and 3e015a9... clears any non-anonymous Security Context populated via Spring Security Test and leads to a 401.

I think setting stateless to false is not a good way to solve this in tests.

aisven commented 9 years ago

Options just for consideration, I am trying to find some ideas how to handle this:

Some of these options could be difficult and/or introduce unwanted security risks.

Perhaps there is already a way to go, please let me know.

dsyer commented 9 years ago

Isn't the best option simply to set the "stateless" flag to false (either for the whole app or just for the tests)? The reason it's configurable is so you can choose the behaviour you want.

ghost commented 9 years ago

Hi, I'm referring code on https://github.com/spring-projects/spring-security-oauth, I see there is a problem in RestOperation API when trying to attempt to make request to Facebook where causing an exception.. Could you please check at your end too and try to fixed it ASAP?

aisven commented 9 years ago

What would be the easiest way to configure stateless = false in a test (not for the whole app)?

I mean, normally you do not configure OAuth2AuthenticationProcessingFilter yourself, the configuration is done within the framework via ResourceServerConfigurerAdapter. The flag also does not seem to be a Spring Boot environment parameter out of the box etc.

Using Spring Security Test seems mainstream or at least intended to become mainstream, so there should be an easy documented way to do this, without security compromise of course and yet without too much custom glue code.

dsyer commented 9 years ago

In a test you can just add a ResourceServerSecurityConfigurer to your application context and set the flag to false. I don't know if that's the best solution (cc @rwinch) but it certainly should work.

It's good that you have Spring Boot in mind, but remember this project does not depend on Spring Boot (and Spring Boot doesn't yet have any OAuth integration).

aisven commented 9 years ago

I ended up doing the following.

In my existing production @Configuration class that is a ResourceServerConfigurerAdapter I added:

    @Autowired(required = false)
    @Qualifier("oauth2StatelessSecurityContext")
    private Boolean stateless = Boolean.TRUE;

This Boolean member variable is used to set the flag via the configurer in the same file:

    public void configure(ResourceServerSecurityConfigurer resources) {
        resources
                .stateless(stateless)
// ...

In the test sources I added a configuration with the following Bean (which could also be restricted to a particular Spring Profile if necessary):

    @Bean
    @Primary
    public Boolean oauth2StatelessSecurityContext() {
        return Boolean.FALSE;
    }

This works for me and is an acceptable change in the production code while allowing the IntegrationTest classes based on MockMvc to test with the production OAuth2 configuration while using Spring Security Test in some of the tests (which is a mixture that I admit is not necessarily mainstream, but in my case desired).

rwinch commented 9 years ago

I'm not sure I have a better way around it at the moment. Dave and I will need to look into adding testing support for Spring Security OAuth in the future.

ghost commented 9 years ago

Just to be more clear on my earlier query - Spring OAuth2 is not working properly as Client (don't any working find code) in order to connect to the Social Networks (like Google, Facebook, Linkedin etc,) or Cloud API's (like Misfit etc..) as follow proper OAuth2 mechanism, But on other hand, I see Apache Oltu (earlier Apache Amber) is useful enough to work as a OAuth2 client and its working fine in my sample example. Why such implementation can't be developed using Spring OAuth2 or please someone look at this following code which is causing problem?

ObjectNode result = facebookRestTemplate .getForObject("https://graph.facebook.com/me/friends", ObjectNode.class); ArrayNode data = (ArrayNode) result.get("data");

dsyer commented 9 years ago

@pashtika if you have a specific problem please open a separate issue (this one is about something different). Please look at the existing samples (there are plenty on the client side, and one that definitely uses Facebook successfully), and be very specific about what the problem is. And please don't duplicate posts.

ghost commented 9 years ago

OK. Could you please provide client links (if you're aware) ? As I can't find anything working OAuth2 client example? I appreciate your help on this. Multiple post was by mistakenly happened due to network issue at my end. I've deleted those in order to remove duplicates.Thanks.

kopax commented 7 years ago

Hi, I encounter issue testing with @WithMockUser and spring security/security-oauth2. Using @sourcekick snippet, I suddently swap my 401 error to a 403 error. The endpoint I am trying to access is a endpoints not protected by the OAuth filter but only security. i see few information about people testing both framework together, I don't really understand what is the snippet for. Can this help ?

charchar commented 5 years ago

The recommendation provided at https://github.com/spring-projects/spring-security-oauth/issues/385#issuecomment-73051286 does work, but a better way to do this without modifying any production code is the following:

  1. Create a new ResourceServerConfigurerAdapter for your tests.
public class AuthStatefulSecurityConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.stateless(false);
    }
}
  1. Include this in your tests with either of the following a. explicitly in your test class with @Import(AuthStatefulSecurityConfig.class) b. dynamically by including in spring.factories:
    org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc=\
    com.broadleafcommerce.auth.AuthStatefulSecurityConfig