1

Tomcat のようなスタンドアロンの Java Web アプリケーション サーバーでホットリンクを防止するにはどうすればよいですか?

4

4 に答える 4

3

TuckeyのURLRewriteFilterを使用します(他の人がすでに間接的に言及しているように)。ドキュメントから:

<rule>
    <name>Blocked Inline-Images</name>
    <note>
        Assume we have under http://www.quux-corp.de/~quux/ some pages with inlined GIF graphics. These graphics are
        nice, so others directly incorporate them via hyperlinks to their pages. We don't like this practice because
        it adds useless traffic to our server.

        While we cannot 100% protect the images from inclusion, we can at least restrict the cases where the browser
        sends a HTTP Referer header.

        RewriteCond %{HTTP_REFERER} !^$
        RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
        RewriteRule .*\.gif$ - [F]
    </note>
    <condition name="referer" operator="notequal">^$</condition>
    <condition name="referer" operator="notequal">^http://www.quux-corp.de/~quux/.*$</condition>
    <from>.*\.gif$</from>
    <set type="status">403</set>
    <to>null</to>
</rule>

<rule>
    <name>Blocked Inline-Images example 2</name>
    <note>
        RewriteCond %{HTTP_REFERER} !^$
        RewriteCond %{HTTP_REFERER} !.*/foo-with-gif\.html$
        RewriteRule ^inlined-in-foo\.gif$ - [F]
    </note>
    <condition name="referer" operator="notequal">^$</condition>
    <condition name="referer" operator="notequal">.*/foo-with-gif\.html$</condition>
    <from>^inlined-in-foo\.gif$</from>
    <set type="status">403</set>
    <to>null</to>
</rule>
于 2010-10-29T12:29:06.573 に答える
2

ブルーノが言ったように、適切なリファラーを確認できます。

すべての HTTP 要求には、要求されている現在の URL (または、画像の場合は画像を参照したページ) にリンクされた URL を含むリファラー ヘッダーが含まれています。あなたの場合、あなた自身のサイトに属する適切なリファラー URL が含まれている必要があります。

許可されていないリファラーを検出するには、 http://www.tuckey.org/urlrewrite/のようなフィルターを使用できると思います。自分のサイトから来ていないすべての画像リクエストに一致する単純なルールを構成し、アクセスを禁止するか、その URL をカスタムの「ホットリンクは許可されていません」画像に書き換えることができます。

于 2010-10-29T12:00:23.357 に答える
2

フィルターの実装例を次に示します。

public class HotLinkFilter implements Filter{

    private final Map<Pattern, Pattern> PATTERNS =
        new ConcurrentHashMap<Pattern, Pattern>();

    private void addPatterns(final String targetPattern,
        final String referrerPattern){
        PATTERNS.put(Pattern.compile(targetPattern),
            Pattern.compile(referrerPattern));
    }

    @Override
    public void init(final FilterConfig config) throws ServletException{
        @SuppressWarnings("unchecked")
        final Enumeration<String> parameterNames =
            config.getInitParameterNames();
        while(parameterNames.hasMoreElements()){
            final String nextParam = parameterNames.nextElement();
            if(nextParam.startsWith("pattern")){
                final String[] patterns =
                    config.getInitParameter(nextParam).split("\\s+");
                if(patterns.length == 2){
                    addPatterns(patterns[0], patterns[1]);
                }
            }
        }
    }

    @Override
    public void doFilter(final ServletRequest request,
        final ServletResponse response,
        final FilterChain chain) throws IOException, ServletException{

        if(request instanceof HttpServletRequest){
            final HttpServletRequest hsr = (HttpServletRequest) request;
            final String referrer = hsr.getHeader("Referer");
            boolean valid = true;
            if(referrer != null){
                final String requestUrl = hsr.getRequestURL().toString();
                for(final Entry<Pattern, Pattern> entry : PATTERNS.entrySet()){
                    if(entry.getKey().matcher(requestUrl).matches()
                        && !entry.getValue().matcher(referrer).matches()){
                        valid = false;
                        break;
                    }
                }
            }
            if(valid){
                chain.doFilter(request, response);
            } else{
                // this is probably not the correct thing to do
                throw new ServletException("Hotlinking not allowed");
            }

        }

    }

    @Override
    public void destroy(){
    }

}

正規表現パターンのマップを使用します。リクエストが左側のパターンに一致し、リファラーが存在する場合、リファラーが右側のパターンに一致するかどうかを確認します。これは web.xml で構成できます。

<filter>
    <filter-name>Hotlink-Filter</filter-name>
    <filter-class>com.yourcompany.HotLinkFilter</filter-class>
    <init-param>
        <param-name>pattern1</param-name>
        <param-value>http://.*\.mysite.com/.*\.(jpe?g|gif|png) 
        http://.*\.mysite.com/.*</param-value>
    </init-param>
</filter>
于 2010-10-29T12:02:47.450 に答える
2

既に存在するかどうかはわかりませんが、適切なパターンに一致するヘッダーがあるかどうかを確認するFilterを簡単に作成できます (投稿したリンクで説明されています)。Referer

編集:リンク 先の記事でReferer説明されているのは、 HTTP ヘッダー (リンクが取得されたページを示すためにブラウザーによって送信される) に基づくルールです。.htaccess次のApache Httpdのルールはmod_rewrite多かれ少なかれ意味があります。Refererヘッダーがパターンと一致しない場合はhttp://(www\\.)?yoursite\\.com、にリダイレクトし/images/hotlink.jpegます。

RewriteEngine on 
RewriteCond %{HTTP_REFERER} . 
RewriteCond %{HTTP_REFERER} !^http://(www\\.)?yoursite\\.com [NC] 
RewriteRule \\.(gif|jpe?g)$ /images/hotlink.$1 [L]

フィルターは、処理のためにサーブレットに送信される前に要求を傍受するための Web アプリケーションの標準メカニズムです (必要に応じて、サーブレットにリダイレクトしないことを選択できます)。

フィルターの をオーバーライドし、正しいパターンに一致するdoFilter(ServletRequest request, ServletResponse response, FilterChain chain)かどうかをテストし、一致する場合は を呼び出し、そうでない場合は、おそらく 403 ステータス コードを使用して、他の画像 (「ホットリンク」などと言う) にリダイレクト応答を送信します。request.getHeader("Referer")chain.doFilter(request, response)

于 2010-10-29T11:10:02.490 に答える