Ecco la mia singola configurazione della sicurezza per un'API realizzata con SpringBoot:metodi sicuri MVC controller con @Secured annotazione
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Autowired
private TokenAuthenticationService tokenAuthenticationService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/static/**").permitAll()
.antMatchers(HttpMethod.POST, "/api/user/registration").permitAll()
.antMatchers(HttpMethod.POST, "/api/user/authentication").permitAll()
.anyRequest().authenticated().and()
.addFilterBefore(new TokenLoginFilter("/api/user/authentication", authenticationManagerBean(), tokenAuthenticationService),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new TokenAuthenticationFilter(tokenAuthenticationService),UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
}
}
Tutti gli URL vengono mappati a controller di primavera web MVC e vorrei specificare manualmente i livelli di accesso per i controllori ed i loro metodi come questo:
@RestController
@RequestMapping("/api/resource/")
@Secured("ROLE_ANONYMOUS") //as default role
public class ResourceController {
...
@Secured("ROLE_USER")
some_method...
}
ma quando eseguo un/api/risorse/* richieste come utente anonimo le risposte di applicazione con codice di stato 403, ma mi aspetto che la chiamata al metodo. L'annotazione @Secured non ha alcun effetto sull'autorizzazione e tutti i metodi del controller sono consentiti solo per ROLE_USER.
TokenAuthenticationFilter esegue un'azione solo se il token è presente, quindi suppongo che non abbia alcun effetto.
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) req;
String token = httpServletRequest.getHeader(TokenAuthenticationService.AUTH_HEADER_NAME);
if (token != null) {
try {
SecurityContextHolder.getContext()
.setAuthentication(tokenAuthenticationService.verifyToken(new TokenAuthentication(token)));
} catch (AuthenticationException e) {
((HttpServletResponse) res).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
}
chain.doFilter(req, res);
}
Aggiornamento:
Considerando commenti qui sotto a questa domanda mi sono reso conto che l'annotazione @Secured è la parte del concetto di metodo di sicurezza globale, e non nella parte generale della sicurezza del web. Ora ho folowing compromesso:
Usa @Secured annotazione e ho metodo informazioni livello di accesso si sviluppa su classi controller, che possono portare a situazioni di determinare il livello di accesso metodo diffucult in fufture con API cresciuto.
Mantieni tutte le informazioni sull'accesso al metodo nello stesso punto (config), ma devi supportare l'uguaglianza del valore @RequestMapping con urls in config.
Quale considereresti l'approccio migliore, o dire per favore se ho perso qualcosa?
Questo è ciò che si è specificato nella configurazione ... per tutti gli URL che hai di essere 'authenticated'. –
Quindi, come faccio a dire a Spring Security di guardare un'annotazione per qualsiasi altro metodo di controller della richiesta mappata? – Aeteros
consentire tutti gli accessi e utilizzare la sicurezza del metodo globale. Gli URL e le annotazioni sono per cose diverse. –