5

Ho seguito i seguenti collegamenti per provare e testare OAuth2 @PreAuthorise (hasAnyRole ('ADMIN', 'TEST') ad esempio, ma non riesco a testare o anche a autenticare nessuno dei test.SpringSecurity WithSecurityContext MockMvc OAuth2 sempre non autorizzato

Quando provo ad accedere al punto finale con admin (o qualsiasi ruolo) non si autentica mai correttamente Mi manca qualcosa di ovvio, sembra che abbia tutto esattamente come negli esempi.Ho anche provato un'altra alternativa al WithSecurityContext fabbrica con OAuth di autenticazione specifico e ancora senza fortuna. Qualsiasi aiuto sarebbe apprezzato.

https://stackoverflow.com/a/31679649/2594130 e 0.123.516,410617 millionshttp://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#test

mio controller sto testando

@RestController 
@RequestMapping("/bookmark/") 
public class GroupBookmarkController { 

    @Autowired 
    BookmarkService bookmarkService; 

    /** 
    * Get list of all bookmarks 
    */ 
    @RequestMapping(value = "{groupId}", method = RequestMethod.GET) 
    @PreAuthorize("hasAnyRole(['ADMIN', 'USER'])") 
    public ResponseEntity<List<Bookmark>> listAllGroupBookmarks(@PathVariable("groupId") String groupId) throws BookmarkNotFoundException { 
     List<Bookmark> bookmarks = bookmarkService.findAllBookmarksByGroupId(groupId); 
     return new ResponseEntity<>(bookmarks, HttpStatus.OK); 
    } 
    ... 
} 

La mia classe di prova

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = BookmarkServiceApplication.class) 
@WebAppConfiguration 
public class BookmarkServiceApplicationTests { 

    private MockMvc mockMvc; 

    @Autowired 
    private WebApplicationContext webApplicationContext; 

    @Before 
    public void loadData() { 
     this.mockMvc = MockMvcBuilders 
       .webAppContextSetup(webApplicationContext) 
       .apply(springSecurity()) 
       .alwaysDo(print()) 
       .build(); 
    } 

    @Test 
    @WithMockCustomUser(username = "test") 
    public void getBookmarkAuthorised() throws Exception { 
     mockMvc.perform(get("/bookmark/nvjdbngkjlsdfngkjlfdsnlkgsd")) 
       .andExpect(status().is(HttpStatus.SC_OK)); 
     // always 401 here 
    } 
} 

mio BookmarkServiceApplication

@SpringBootApplication 
@EnableResourceServer 
public class BookmarkServiceApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(BookmarkServiceApplication.class, args); 
    } 
} 

mio WithSecurityContextFactory

public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockCustomUser> { 
    @Override 
    public SecurityContext createSecurityContext(WithMockCustomUser customUser) { 
     SecurityContext context = SecurityContextHolder.createEmptyContext(); 

     List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); 
     grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); 

     UserDetails principal = new User(customUser.username(), "password", true, true, true, true, grantedAuthorities); 


     Authentication authentication = new UsernamePasswordAuthenticationToken(
       principal, principal.getPassword(), principal.getAuthorities()); 
     context.setAuthentication(authentication); 

     return context; 
    } 
} 

mio WithSecurityContext annotazione

@Retention(RetentionPolicy.RUNTIME) 
@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class) 
public @interface WithMockCustomUser { 

    String username() default "user"; 

    String name() default "Test User"; 
} 

Come per la risposta @RobWinch s'

Hi @RobWinch Ho provato il suggerimento con la bandiera stateless, questo ci ha aiutato con una parte della risposta. Tuttavia nella risposta a questa domanda [Primavera OAuth e Boot Integration Test] (https://stackoverflow.com/a/31679649/2594130) si menzionano

Non è più necessario preoccuparsi di esecuzione in modalità senza stato o no

Perché è che ho è necessario aggiungere ancora lo stateless false, si tratta di un bug o lo stiamo usando in modo leggermente diverso?

L'altra cosa che dovevo fare per ottenere questo al lavoro stava aggiungendo OAuth2Request e OAuth2Authentication al WithSecurityContextFactory come si può vedere nella seguente

public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockOAuthUser> { 

    @Override 
    public SecurityContext createSecurityContext(WithMockOAuthUser withClient) { 
     // Get the username 
     String username = withClient.username(); 
     if (username == null) { 
      throw new IllegalArgumentException("Username cannot be null"); 
     } 

     // Get the user roles 
     List<GrantedAuthority> authorities = new ArrayList<>(); 
     for (String role : withClient.roles()) { 
      if (role.startsWith("ROLE_")) { 
       throw new IllegalArgumentException("roles cannot start with ROLE_ Got " + role); 
      } 
      authorities.add(new SimpleGrantedAuthority("ROLE_" + role)); 
     } 

     // Get the client id 
     String clientId = withClient.clientId(); 
     // get the oauth scopes 
     String[] scopes = withClient.scope(); 
     Set<String> scopeCollection = Sets.newSet(scopes); 

     // Create the UsernamePasswordAuthenticationToken 
     User principal = new User(username, withClient.password(), true, true, true, true, authorities); 
     Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), 
       principal.getAuthorities()); 


     // Create the authorization request and OAuth2Authentication object 
     OAuth2Request authRequest = new OAuth2Request(null, clientId, null, true, scopeCollection, null, null, null, 
       null); 
     OAuth2Authentication oAuth = new OAuth2Authentication(authRequest, authentication); 

     // Add the OAuth2Authentication object to the security context 
     SecurityContext context = SecurityContextHolder.createEmptyContext(); 
     context.setAuthentication(oAuth); 
     return context; 
    } 

} 
+0

Dove si trova il codice per WithMockOAuthUser ed è correlato a WithSecurityContextFactory? –

+0

@RobWinch Mi dispiace che si tratti di un errore di battitura, in realtà WithMockCustomUser è un errore di battitura con me, lo stesso problema esiste.Avevo un'altra interfaccia che creava un'autenticazione OAuth invece di UsernamePasswordAuthentication – revilo

+0

Che aspetto ha la tua configurazione di sicurezza? In particolare, come appare la configurazione di sicurezza del Web e del metodo? –

risposta

2

Il problema è che OAuth2AuthenticationProcessingFilter sarà chiaro il SecurityContext se è contrassegnato come apolide. Per risolvere questo problema configurarlo per consentire lo stato di essere popolato esternamente (vale a dire stateless = false).

+0

Ciao @RobWinch Ho provato il tuo suggerimento con la bandiera senza stato, questo ha aiutato con parte della risposta. Tuttavia nella risposta a questa domanda [Spring OAuth e Boot Integration Test] (http://stackoverflow.com/a/31679649/2594130) si cita _ "Non è più necessario preoccuparsi di eseguire in modalità stateless o no" _ Perché è che è necessario ho bisogno di questo, è un bug o lo stiamo usando in modo leggermente diverso. Ho aggiornato la risposta in quanto ho esaurito i caratteri qui – revilo

+0

Spring Security OAuth gestisce gli apolidi in modo diverso rispetto a Spring Security e pertanto questa istruzione non è applicabile a OAuth (sfortunatamente). –

+0

Esattamente come si imposta that = false nell'esempio sopra? – PaulNUK

1

per aggiungere un po maggiori informazioni su come impostare apolidi su false:

nel vostro ResourceServerConfigurerAdapter procedere come segue:

@Override 
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 
     resources.stateless(false); 
    } 

che ha lavorato per me.