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;
}
}
Dove si trova il codice per WithMockOAuthUser ed è correlato a WithSecurityContextFactory? –
@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
Che aspetto ha la tua configurazione di sicurezza? In particolare, come appare la configurazione di sicurezza del Web e del metodo? –