Je me demande comment filtrer l'accès des utilisateurs à mon application Web par leur adresse IP à l'aide de Spring Security. Devrais-je étendre AbstractAuthenticationProcessingFilter
ou quelque chose du genre et remplacer les méthodes à ma manière? Si oui, pourriez-vous? vous donnez un exemple d'une telle extension et un exemple de description de filtre dans web.xml
? Merci d'avance.
P.S. Dans mon application, j'ai également la prise en charge de Spring Security (à l'aide de org.springframework.web.filter.DelegatingFilterProxy
par défaut), mais je souhaite qu'elle vérifie non seulement les informations d'identification de l'utilisateur, mais également son adresse IP.
Une façon de procéder consiste à utiliser les expressions de sécurité Web de Spring Security. Par exemple:
<http use-expressions="true">
<intercept-url pattern="/admin*"
access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/>
...
</http>
La réponse d'Anshu est une bonne idée d'authentifier un utilisateur par ip, mais cela peut ne pas fonctionner avec l'authentification cas. J'ai une autre résolution, en utilisant un filtre est plus approprié pour cette situation.
public class IPAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService;
private static Set<String> ipWhitelist;
@Autowired
private AppProperty appProperty;
@PostConstruct
public void init() {
ipWhitelist = new HashSet<>(Arrays.asList(appProperty.getIpWhitelist()));
setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException, ServletException {
// do nothing
}
});
}
public IPAuthenticationFilter() {
super("/");
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
String userName = request.getHeader(appProperty.getHeaderCurUser());
Assertion assertion = new AssertionImpl(userName);
CasAssertionAuthenticationToken token = new CasAssertionAuthenticationToken(assertion, "");
UserDetails userDetails = authenticationUserDetailsService.loadUserDetails(token);
CasAuthenticationToken result = new CasAuthenticationToken(
"an-id-for-ip-auth",
userDetails,
request.getRemoteAddr(),
userDetails.getAuthorities(),
userDetails,
assertion
);
return result;
}
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
String userName = request.getHeader(appProperty.getHeaderCurUser());
return ipWhitelist.contains(request.getRemoteAddr()) && !StringUtils.isEmpty(userName);
}
protected void successfulAuthentication(
HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
chain.doFilter(request, response);
}
public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> getAuthenticationUserDetailsService() {
return authenticationUserDetailsService;
}
public void setAuthenticationUserDetailsService(
AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService) {
this.authenticationUserDetailsService = authenticationUserDetailsService;
}
}
Vous pouvez ajouter ce filtre avant comme ceci:
http.addFilterBefore(ipAuthenticationFilter(), CasAuthenticationFilter.class)