J'essaie d'ajouter la sécurité Web au printemps, mais je ne veux pas que le filtre s'applique à certaines choses. Comment cela se fait-il en Java?
Et il y a peut-être une meilleure façon de le faire parce que j'ai créé un filtre personnalisé, mais c'est la seule façon dont je peux penser pour l'instancier en raison de ses dépendances.
Dans l'ensemble, ce que je veux faire est le suivant:
/resources/**
NE DEVRAIT PAS passer par le filtre, /login
(POST) NE DEVRAIT PAS passer par le filtre, tout le reste DEVRAIT passer par le filtre
Grâce à divers exemples que j'ai trouvés au printemps, j'ai pu trouver cela comme pour commencer, mais cela ne fonctionne évidemment pas:
@Configuration
@EnableWebSecurity
@Import(MyAppConfig.class)
public class MySecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
public void configure(WebSecurity webSecurity) throws Exception
{
webSecurity.ignoring().antMatchers("/resources/**");
}
@Override
public void configure(HttpSecurity httpSecurity) throws Exception
{
httpSecurity
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/login").permitAll();
httpSecurity.httpBasic();
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
@Autowired
public TokenFilterSecurityInterceptor<TokenInfo> tokenInfoTokenFilterSecurityInterceptor(MyTokenUserInfoCache userInfoCache, ServerStatusService serverStatusService, HttpSecurity httpSecurity) throws Exception
{
TokenService<TokenInfo> tokenService = new TokenServiceImpl(userInfoCache);
TokenFilterSecurityInterceptor<TokenInfo> tokenFilter = new TokenFilterSecurityInterceptor<TokenInfo>(tokenService, serverStatusService, "RUN_ROLE");
httpSecurity.addFilter(tokenFilter);
return tokenFilter;
}
}
Êtes-vous intéressé à ce que Spring Security ignore tous les URL ou souhaitez-vous uniquement que ce filtre spécifique ignore la demande? Si vous souhaitez que Spring Security ignore la demande, vous pouvez le faire en utilisant les éléments suivants:
@Configuration
@EnableWebSecurity
@Import(MyAppConfig.class)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyTokenUserInfoCache userInfoCache;
@Autowired
private ServerStatusService serverStatusService;
@Override
public void configure(WebSecurity webSecurity) throws Exception
{
webSecurity
.ignoring()
// All of Spring Security will ignore the requests
.antMatchers("/resources/**")
.antMatchers(HttpMethod.POST, "/login");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.addFilter(tokenInfoTokenFilterSecurityInterceptor())
.authorizeRequests()
// this will grant access to GET /login too do you really want that?
.antMatchers("/login").permitAll()
.and()
.httpBasic().and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public TokenFilterSecurityInterceptor<TokenInfo> tokenInfoTokenFilterSecurityInterceptor() throws Exception
{
TokenService<TokenInfo> tokenService = new TokenServiceImpl(userInfoCache);
return new TokenFilterSecurityInterceptor<TokenInfo>(tokenService, serverStatusService, "RUN_ROLE");
}
}
Si vous souhaitez que seul ce filtre spécifique ignore les demandes particulières, vous pouvez faire quelque chose comme ceci:
@Configuration
@EnableWebSecurity
@Import(MyAppConfig.class)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyTokenUserInfoCache userInfoCache;
@Autowired
private ServerStatusService serverStatusService;
@Override
public void configure(WebSecurity webSecurity) throws Exception
{
webSecurity
.ignoring()
// ... whatever is here is ignored by All of Spring Security
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.addFilter(tokenInfoTokenFilterSecurityInterceptor())
.authorizeRequests()
// this will grant access to GET /login too do you really want that?
.antMatchers("/login").permitAll()
.and()
.httpBasic().and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public TokenFilterSecurityInterceptor<TokenInfo> tokenInfoTokenFilterSecurityInterceptor() throws Exception
{
TokenService<TokenInfo> tokenService = new TokenServiceImpl(userInfoCache);
TokenFilterSecurityInterceptor tokenFilter new TokenFilterSecurityInterceptor<TokenInfo>(tokenService, serverStatusService, "RUN_ROLE");
RequestMatcher resourcesMatcher = new AntPathRequestMatcher("/resources/**");
RequestMatcher posLoginMatcher = new AntPathRequestMatcher("/login", "POST");
RequestMatcher ignored = new OrRequestMatcher(resourcesMatcher, postLoginMatcher);
return new DelegateRequestMatchingFilter(ignored, tokenService);
}
}
public class DelegateRequestMatchingFilter implements Filter {
private Filter delegate;
private RequestMatcher ignoredRequests;
public DelegateRequestMatchingFilter(RequestMatcher matcher, Filter delegate) {
this.ignoredRequests = matcher;
this.delegate = delegate;
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
if(ignoredRequests.matches(request)) {
chain.doFilter(req,resp,chain);
} else {
delegate.doFilter(req,resp,chain);
}
}
}
1 Dans la configuration xml de spring-security que j'utilise
<http pattern="/resources/**" security="none"/>
<http use-expressions="true">
<intercept-url pattern="/login" access="permitAll"/>
</http>
pour le récupérer du contrôle de sécurité.
2 Après cela, ajoutez mvc:resource
tag dans votre configuration de ressort
<mvc:resources mapping="/resource/**" location="/resource/"/>
Important: cette configuration ne fonctionnera que si l'url est gérée par le servlet du répartiteur. Cela signifie que dans web.xml, vous devez avoir
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>