Basic Authentication na Google App Engine

Google App Engine (GAE) dla Javy udostępnia jedynie namiastkę implementacji Servlet Security opisanego w rozdziale SRV.12 specyfikacji Java Servlet 2.5. W pliku web.xml (/web-app/security-constraint/auth-constraint/role-namemożemy użyć tylko roli admin lub *. Nie ma możliwości wyboru metody uwierzytelniania (SRV.12.5). W zamian za to mamy możliwość skorzystania z uwierzytelniania przy użyciu konta Google lub przez zewnętrznego dostawcę OpenID oraz użycia Google Users Java API.

Spotkałem się z potrzebą ograniczenia dostępu do całej aplikacji na GAE (włącznie ze stroną główną) tylko do developerów. To co w standardowym kontenerze webowym skończyłoby się na modyfikacji paru wpisów w web.xml tutaj wymagało innego podejścia.Stworzyłem specjalny filtr wymuszający Basic Authentication przed jakimkolwiek dostępem mojej aplikacji na GAE. Dało mi to dodatkowo możliwość testowania zaimplementowanych mechanizmów uwierzytelniania (Facebook, Google, Gadu-Gadu) w takiej konfiguracji w jakiej będą dostępne dla produkcyjnej wersji. Filtr nie wymaga zapisywania uwierzytelnionego użytkownika w sesji ponieważ przeglądarka po odpowiedzi na pierwsze żądanie WWW-Authenticate do każdego requestu będzie dodawała nagłówek Authorization. Zamieszczam kod stworzonego przeze mnie prostego filtru.

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.codec.binary.Base64;
 
/**
 * @author Zacheusz
 */
public class DeveloperBasicAuthServletFilter implements Filter {
 
    private String requestHeaderValue;
    private String responseHeaderValue;
 
    public void init(FilterConfig fc) throws ServletException {
        String user = fc.getInitParameter("user");
        String password = fc.getInitParameter("password");
        String realmName = fc.getInitParameter("realm");
        this.responseHeaderValue = "Basic realm=\"" + realmName + '"';
        String credentials = user + ':' + password;
        try {
            this.requestHeaderValue = "Basic " +
                    new Base64().encodeToString(credentials.getBytes("utf-8"));
        } catch (UnsupportedEncodingException ex) {
           throw new RuntimeException(ex);
        }
    }
 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest )req;
        if(requestHeaderValue.equals(httpRequest.getHeader("Authorization"))){
            fc.doFilter(req, res);
        } else {
            HttpServletResponse httpResponse =(HttpServletResponse)res;
            httpResponse.setHeader("WWW-Authenticate", responseHeaderValue);
            httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
    }
 
    public void destroy() {
    }
}
Zacheusz Siedlecki

Komentarze

Chcesz coś napisać?





*