Beginner Tutorial - Locale Finder

Introduction

This provider is used as a servlet filter implemented by a plugin. We don't bother to configure the web.xml. There are two interfaces: EmbedRequestFilterProvider and GlobalRequestFilterProvider.

EmbedRequestFilterProvider

When using this, requests towards /decision/* will be intercepted.

package com.fr.decision.fun;

import com.fr.stable.fun.mark.Mutable;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Embedded Servlet Filter.
 */
public interface EmbedRequestFilterProvider extends Mutable {

    String MARK_STRING = "EmbedRequestFilterProvider";

    int CURRENT_LEVEL = 2;

    /**
     * Initialize the filter. Only takes effect after reboot.
     * @param filterConfig the filter config
     */
    void init(FilterConfig filterConfig);

    /**
     * filter method
     * @param req HTTP Request
     * @param res HTTP Response
     */
    void filter(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException;


    /**
     * Destroy the filter.
     */
    void destroy();
}

In order to register this provider, we should write plugin.xml like this:

<extra-decision>
    <EmbedRequestFilterProvider class="com.fr.plugin.request.filter.DemoEmbedRequestFilterProvider"/>
</extra-decision>

GlobalRequestFilterProvider

This one is like the upgraded EmbedRequestFilterProvider. Here is how it looks like:

package com.fr.decision.fun;

import com.fr.stable.fun.mark.Mutable;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * A global request filter. Only takes effect after reboot.
 */
public interface GlobalRequestFilterProvider extends Mutable {

    String MARK_STRING = "GlobalRequestFilterProvider";

    int CURRENT_LEVEL = 1;

    /**
     * the filter name
     *
     * @return filter name
     */
    String filterName();


    /**
     * url patterns
     *
     * @return the array of url patterns
     */
    String[] urlPatterns();

    /**
     * the class name of the external filter
     * The corresponding jar needs to be placed under the classpath of the web server. The path can be /WEB-INF/lib or /WEB-INF/classes.
     * @return class name
     */
    String externalFilterClassName();

    /**
     * Initialize the filter. Only takes effect after reboot.
     * @param filterConfig the filter config
     */
    void init(FilterConfig filterConfig) throws ServletException;

    /**
     * Initial parameters for the filter
     * @return parameter map
     */
    Map<String, String> initializationParameters();

    /**
     * filter method
     * @param req HTTP Request
     * @param res HTTP Response
     * @param filterChain
     */
    void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws IOException, ServletException;

    /**
     * Destroy the filter.
     */
    void destroy();
}

There are two ways to realize a filter. One is to include an external filter class by using externalFilterClassName(), and the other is to implement the doFilter() method. If both are used, only the external one will take effect.

The filter implemented by GlobalRequestFilterProvider is executed before the one implemented by EmbedRequestFilterProvider. If multiple there are multiple filters implemented by GlobalRequestFilterProvider, the execution order is random.

Example

Let's use GlobalRequestFilterProvider to build CAS Single Sign-On.

1) Implement the CAS Filter

public class CasFilter extends AbstractGlobalRequestFilterProvider  {
    @Override
    public String filterName() {
        return "cas";
    }

    @Override
    public String[] urlPatterns() {
        return new String[]{"/*"};
    }

    @Override
    public String externalFilterClassName() {
        // The class name may differ in vairous versions of CAS client.
       return "edu.yale.its.tp.cas.client.filter.CASFilter";
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public Map<String, String> initializationParameters() {
        // Initialize some parameters for the CAS filter. It may also change due to different version of CAS client.
        Map<String,String> para=new HashMap<String,String>();
        para.put("edu.yale.its.tp.cas.client.filter.loginUrl","http://localhost:8080/cas/login");
        para.put("edu.yale.its.tp.cas.client.filter.validateUrl","http://localhost:8080/cas/proxyValidate");
        para.put("edu.yale.its.tp.cas.client.filter.serverName","localhost:8080");
        return para;
    }
}

2) Implement the FR filter

public class FRLoginFilter extends AbstractGlobalRequestFilterProvider {
    @Override
    public String filterName() {
        return "login";
    }

    @Override
    public String[] urlPatterns() {
        return new String[]{"/*"};
    }

    @Override
    public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
       String casUser=getCasUser(req,res);
        if(isNeedLogin(casUser,req,res)){
            if(!LoginFR(casUser,req,res)){//login the FineReport platform
                // do something if login failed
            }
        }
        try {
            filterChain.doFilter(req,res);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }

    private  Boolean isNeedLogin(String casUser, HttpServletRequest req, HttpServletResponse res){
        if(!isLoginedFR(req)){
            return  true;
        }
        String frUser=LoginService.getInstance().getCurrentUserNameFromRequestCookie(req);

        return !ComparatorUtils.equals(casUser,frUser);
    }
    /**
     * get CAS user
     * @param req
     * @param res
     * @return
     */
    private String getCasUser(HttpServletRequest req,HttpServletResponse res){
        String username;
        // Get the username from CAS
        Object object = req.getSession().getAttribute("_const_cas_assertion_");
        if (object != null) {
            Assertion assertion = (Assertion) object;
            username = assertion.getPrincipal().getName();
        } else {
            username = (String) req.getSession().getAttribute("edu.yale.its.tp.cas.client.filter.user");
        }
        return  username;
    }

    /**
     * Decide whether the user has logged in FineReport Platform.
     * @param req
     * @return
     */
    private Boolean isLoginedFR(HttpServletRequest req){
        String token= TokenResource.COOKIE.getToken(req);
        return StringUtils.isNotBlank(token);
    }

    /**
     * Log in FineReport platform
     * @param username
     * @param req
     * @param res
     * @return
     */
    private  Boolean LoginFR(String username,HttpServletRequest req,HttpServletResponse res){
        try{
            User user = UserService.getInstance().getUserByUserName(username);
            if (user == null) {
               return  false;
            }
            String token = LoginService.getInstance().login(req, res, username);
            req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
           return  true;
        }catch (Exception e){
        }
        return  false;
    }
}

Write the plugin.xml to declare both filters:

<extra-decision>
    <GlobalRequestFilterProvider class="com.fr.plugin.request.filter.CasFilter"/>
    <GlobalRequestFilterProvider class="com.fr.plugin.request.filter.FRLoginFilter"/>
</extra-decision>

results matching ""

    No results matching ""