web-dev-qa-db-ja.com

Spring Securityを使用したIPフィルター

Spring Securityを使用して、自分のWebアプリへのユーザーのアクセスをIPでフィルタリングする方法を知りたい。 AbstractAuthenticationProcessingFilterまたはそのようなものを拡張して、独自の方法でそのメソッドをオーバーライドする必要がありますか?もしそうなら、そのような拡張の例とweb.xmlのフィルターの説明の例を挙げていただけますか?前もって感謝します。

追伸私のアプリでは、Spring Securityのサポート(デフォルトのorg.springframework.web.filter.DelegatingFilterProxyを使用)も行っていますが、ユーザーの認証情報だけでなく、そのIPもチェックしたいと思います。

16

これを行う1つの方法は、Spring Securityの Web Security Expressions を使用することです。例えば:

<http use-expressions="true">
    <intercept-url pattern="/admin*"
        access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/>
    ...
</http>
15
alfredaday

Anshuの回答は、IPでユーザーを認証することをお勧めしますが、cas認証では機能しない場合があります。別の解決策があります。この状況には、フィルターを使用する方が適しています。

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;
    }
}

あなたはこのようなcasの前にこのフィルターを追加することができます:

http.addFilterBefore(ipAuthenticationFilter(), CasAuthenticationFilter.class)
1
Hector