This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 9ee99f441af1ecb5698d0f8993e0e031f8de088f
Author: Alex Heneveld <[email protected]>
AuthorDate: Thu Dec 13 16:05:15 2018 +0000

    switching to security provider filter from login module
    
    fragmented partial commit with lots of potentially useful snippets
---
 .../brooklyn/launcher/BrooklynWebServer.java       |   4 +-
 .../apache/brooklyn/rest/BrooklynWebConfig.java    |   5 +
 .../filter/BrooklynSecurityProviderFilter.java     | 222 +++++++++++++
 .../rest/filter/EntitlementContextFilter.java      |   2 +-
 .../brooklyn/rest/filter/GoogleOauthFilter.java    | 349 +++++++++++----------
 .../rest/security/jaas/BrooklynLoginModule.java    | 277 +++++++++-------
 .../rest/security/jaas/GoogleOauthLoginModule.java |   6 +-
 .../security/provider/AnyoneSecurityProvider.java  |   7 +-
 .../provider/BlackholeSecurityProvider.java        |   8 +-
 ...klynUserWithRandomPasswordSecurityProvider.java |   5 +
 .../provider/DelegatingSecurityProvider.java       |  41 ++-
 .../provider/ExplicitUsersSecurityProvider.java    |   5 +
 .../provider/GoogleOauthSecurityProvider.java      | 269 +++++++++++++++-
 .../security/provider/LdapSecurityProvider.java    |   5 +
 .../rest/security/provider/SecurityProvider.java   |  11 +-
 .../main/resources/OSGI-INF/blueprint/service.xml  |  10 +-
 rest/rest-resources/src/main/resources/jaas.conf   |  21 --
 .../filter/BrooklynPropertiesSecurityFilter.java   |   2 +-
 .../AuthenticateAnyoneSecurityProvider.java        |   5 +
 .../security/provider/TestSecurityProvider.java    |   5 +
 20 files changed, 913 insertions(+), 346 deletions(-)

diff --git 
a/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java 
b/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
index cd0cb00..ad50454 100644
--- a/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
+++ b/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
@@ -199,7 +199,7 @@ public class BrooklynWebServer {
      * {@link BrooklynLoginModule} used by default.
      */
     @Deprecated
-    private 
Class<org.apache.brooklyn.rest.filter.BrooklynPropertiesSecurityFilter> 
securityFilterClazz;
+    private 
Class<org.apache.brooklyn.rest.filter.BrooklynSecurityProviderFilter> 
securityFilterClazz;
     
     @SetFromFlag
     private boolean skipSecurity = false;
@@ -236,7 +236,7 @@ public class BrooklynWebServer {
 
     /** @deprecated since 0.9.0, use {@link #skipSecurity} or {@link 
BrooklynLoginModule} */
     @Deprecated
-    public void 
setSecurityFilter(Class<org.apache.brooklyn.rest.filter.BrooklynPropertiesSecurityFilter>
 filterClazz) {
+    public void 
setSecurityFilter(Class<org.apache.brooklyn.rest.filter.BrooklynSecurityProviderFilter>
 filterClazz) {
         this.securityFilterClazz = filterClazz;
     }
 
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
index 79ca0bf..f731c79 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
@@ -48,6 +48,11 @@ public class BrooklynWebConfig {
             ExplicitUsersSecurityProvider.class.getCanonicalName());
     public final static ConfigKey<SecurityProvider> SECURITY_PROVIDER_INSTANCE 
= ConfigKeys.newConfigKey(SecurityProvider.class,
             SECURITY_PROVIDER_CLASSNAME.getName()+".internal.instance", 
"instance of a pre-configured security provider");
+    // TODO document
+    public final static ConfigKey<String> SECURITY_PROVIDER_BUNDLE = 
ConfigKeys.newStringConfigKey(
+        SECURITY_PROVIDER_CLASSNAME.getName()+".bundle.symbolicName", "bundle 
containing the Brooklyn SecurityProvider");
+    public final static ConfigKey<String> SECURITY_PROVIDER_BUNDLE_VERSION = 
ConfigKeys.newStringConfigKey(
+        SECURITY_PROVIDER_CLASSNAME.getName()+".bundle.version", "bundle 
containing the Brooklyn SecurityProvider");
     
     /**
      * Explicitly set the users/passwords, e.g. in brooklyn.properties:
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/BrooklynSecurityProviderFilter.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/BrooklynSecurityProviderFilter.java
new file mode 100644
index 0000000..264a575
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/BrooklynSecurityProviderFilter.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.filter;
+
+import java.io.IOException;
+
+import javax.annotation.Priority;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.rest.BrooklynWebConfig;
+import org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule;
+import org.apache.brooklyn.rest.security.provider.SecurityProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides a filter that performs authentication with the {@link 
SecurityProvider}
+ * as configured according to {@link 
BrooklynWebConfig#SECURITY_PROVIDER_CLASSNAME}.
+ * 
+ * This replaces the JAAS {@link BrooklynLoginModule} because that login 
module requires
+ * Basic auth, which is not flexible enough to support redirect-based 
solutions like Oauth. 
+ */
+@Provider
+@Priority(100)
+public class BrooklynSecurityProviderFilter implements ContainerRequestFilter, 
ContainerResponseFilter {
+    
+    @Context
+    HttpServletRequest webRequest;
+    
+    HttpServletResponse webResponse;
+    
+    @Context
+    private ContextResolver<ManagementContext> mgmtC;
+    
+    private ManagementContext mgmt() {
+        return mgmtC.getContext(ManagementContext.class);
+    }
+    
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws 
IOException {
+        SecurityProvider provider = getProvider();
+        HttpSession session = webRequest.getSession(false);
+        
+        if (provider.isAuthenticated(session)) {
+            return;
+        }
+        
+        String user=null, pass=null;
+        webResponse.setHeader("WWW-Authenticate", "Basic realm=\"brooklyn\"");
+        webResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+        throw new RuntimeException("Authentication required.");
+//        if (provider.requiresUserPass()) {
+//            // TODO get basic auth
+//            
+//        }
+//        
+//        if (provider.authenticate(session, user, pass)) {
+//            
+//        } else {
+//            throw new RuntimeException("Authentication failed.");
+//        }
+    }
+    
+    @Override
+    public void filter(ContainerRequestContext requestContext, 
ContainerResponseContext responseContext) throws IOException {
+        // nothing needs done on the response
+    }
+    
+    protected SecurityProvider getProvider() {
+        // TODO
+        return null;
+    }
+
+    /**
+     * The session attribute set for authenticated users; for reference
+     * (but should not be relied up to confirm authentication, as
+     * the providers may impose additional criteria such as timeouts,
+     * or a null user (no login) may be permitted)
+     */
+    public static final String AUTHENTICATED_USER_SESSION_ATTRIBUTE = 
BrooklynLoginModule.AUTHENTICATED_USER_SESSION_ATTRIBUTE;
+
+    private static final Logger log = 
LoggerFactory.getLogger(BrooklynSecurityProviderFilter.class);
+
+//    private static ThreadLocal<String> originalRequest = new 
ThreadLocal<String>();
+//
+//    @Override
+//    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
+//        HttpServletRequest httpRequest = (HttpServletRequest) request;
+//        HttpServletResponse httpResponse = (HttpServletResponse) response;
+//        String uri = httpRequest.getRequestURI();
+//
+//        if (provider == null) {
+//            log.warn("No security provider available: disallowing web access 
to brooklyn");
+//            
httpResponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+//            return;
+//        }
+//
+//        if (originalRequest.get() != null) {
+//            // clear the entitlement context before setting to avoid warnings
+//            Entitlements.clearEntitlementContext();
+//        } else {
+//            originalRequest.set(uri);
+//        }
+//
+//        boolean authenticated = 
provider.isAuthenticated(httpRequest.getSession());
+//        if ("/logout".equals(uri) || "/v1/logout".equals(uri)) {
+//            httpResponse.setHeader("WWW-Authenticate", "Basic 
realm=\"brooklyn\"");
+//            if (authenticated && 
httpRequest.getSession().getAttributeNames().hasMoreElements()) {
+//                logout(httpRequest);
+//                httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+//            } else {
+//                RequestDispatcher dispatcher = 
httpRequest.getRequestDispatcher("/");
+//                log.debug("Not authenticated, forwarding request for {} to 
{}", uri, dispatcher);
+//                dispatcher.forward(httpRequest, httpResponse);
+//            }
+//            return;
+//        }
+//
+//        if (!(httpRequest.getSession().getAttributeNames().hasMoreElements() 
&& provider.isAuthenticated(httpRequest.getSession())) ||
+//                "/logout".equals(originalRequest.get())) {
+//            authenticated = authenticate(httpRequest);
+//        }
+//
+//        if (!authenticated) {
+//            httpResponse.setHeader("WWW-Authenticate", "Basic 
realm=\"brooklyn\"");
+//            httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+//            return;
+//        }
+//
+//        // Note that the attribute AUTHENTICATED_USER_SESSION_ATTRIBUTE is 
only set in the call to authenticate(httpRequest),
+//        // so must not try to get the user until that is done.
+//        String uid = RequestTaggingFilter.getTag();
+//        String user = 
Strings.toString(httpRequest.getSession().getAttribute(AUTHENTICATED_USER_SESSION_ATTRIBUTE));
+//        try {
+//            WebEntitlementContext entitlementContext = new 
WebEntitlementContext(user, httpRequest.getRemoteAddr(), uri, uid);
+//            Entitlements.setEntitlementContext(entitlementContext);
+//
+//            chain.doFilter(request, response);
+//        } catch (Throwable e) {
+//            if (!response.isCommitted()) {
+//                
httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+//            }
+//        } finally {
+//            originalRequest.remove();
+//            Entitlements.clearEntitlementContext();
+//        }
+//    }
+//
+//    protected boolean authenticate(HttpServletRequest request) {
+//        HttpSession session = request.getSession();
+//        if (provider.isAuthenticated(session)) {
+//            return true;
+//        }
+//        
session.setAttribute(BrooklynWebConfig.REMOTE_ADDRESS_SESSION_ATTRIBUTE, 
request.getRemoteAddr());
+//        String user = null, pass = null;
+//        String authorization = request.getHeader("Authorization");
+//        if (authorization != null) {
+//            String userpass = new 
String(Base64.decodeBase64(authorization.substring(6)));
+//            int idxColon = userpass.indexOf(":");
+//            if (idxColon >= 0) {
+//                user = userpass.substring(0, idxColon);
+//                pass = userpass.substring(idxColon + 1);
+//            } else {
+//                return false;
+//            }
+//        }
+//        if (provider.authenticate(session, user, pass)) {
+//            if (user != null) {
+//                session.setAttribute(AUTHENTICATED_USER_SESSION_ATTRIBUTE, 
user);
+//            }
+//            return true;
+//        }
+//
+//        return false;
+//    }
+//
+//    @Override
+//    public void init(FilterConfig config) throws ServletException {
+//        ManagementContext mgmt = 
OsgiCompat.getManagementContext(config.getServletContext());
+//        provider = new DelegatingSecurityProvider(mgmt);
+//    }
+//
+//    @Override
+//    public void destroy() {
+//    }
+//
+//    protected void logout(HttpServletRequest request) {
+//        log.info("REST logging {} out of session {}",
+//                
request.getSession().getAttribute(AUTHENTICATED_USER_SESSION_ATTRIBUTE), 
request.getSession().getId());
+//        provider.logout(request.getSession());
+//        
request.getSession().removeAttribute(AUTHENTICATED_USER_SESSION_ATTRIBUTE);
+//        
request.getSession().removeAttribute(BrooklynWebConfig.REMOTE_ADDRESS_SESSION_ATTRIBUTE);
+//        request.getSession().invalidate();
+//    }
+
+}
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
index a039b57..c7a9a5c 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/EntitlementContextFilter.java
@@ -39,7 +39,7 @@ import 
org.apache.brooklyn.core.mgmt.entitlement.WebEntitlementContext;
 public class EntitlementContextFilter implements ContainerRequestFilter, 
ContainerResponseFilter {
     @Context
     private HttpServletRequest request;
-
+    
     @Override
     public void filter(ContainerRequestContext requestContext) throws 
IOException {
         SecurityContext securityContext = requestContext.getSecurityContext();
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/GoogleOauthFilter.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/GoogleOauthFilter.java
index e91733a..ab15f1a 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/GoogleOauthFilter.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/GoogleOauthFilter.java
@@ -34,6 +34,10 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
 import javax.ws.rs.ext.Provider;
 
 import org.apache.brooklyn.util.exceptions.Exceptions;
@@ -56,7 +60,7 @@ import org.slf4j.LoggerFactory;
 
 @Provider
 @Priority(1)
-public class GoogleOauthFilter implements Filter {
+public class GoogleOauthFilter implements ContainerRequestFilter {
 
     private static final Logger log = 
LoggerFactory.getLogger(GoogleOauthFilter.class);
     
@@ -80,178 +84,183 @@ public class GoogleOauthFilter implements Filter {
     private String callbackUri = "http://localhost.io:8081/";;
     private String audience = "audience";
 
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-        initializateParams(filterConfig);
-    }
-
-    private void initializateParams(FilterConfig filterConfig) {
-        Enumeration<String> enums = filterConfig.getInitParameterNames();
-
-        while (enums.hasMoreElements()) {
-            String paramKey = enums.nextElement();
-            String paramValue = filterConfig.getInitParameter(paramKey);
-            System.out.println(paramKey + ":" + paramValue);
-            switch (paramKey) {
-            case PARAM_URI_TOKEN_INFO:
-                uriTokenInfo = paramValue;
-                break;
-            case PARAM_URI_GETTOKEN:
-                uriGetToken = paramValue;
-                break;
-            case PARAM_URI_LOGIN_REDIRECT:
-                uriTokenRedirect = paramValue;
-                break;
-            case PARAM_CLIENT_ID:
-                clientId = paramValue;
-                break;
-            case PARAM_CLIENT_SECRET:
-                clientSecret = paramValue;
-                break;
-            case PARAM_CALLBACK_URI:
-                callbackUri = paramValue;
-                break;
-            case PARAM_AUDIENCE:
-                audience = paramValue;
-                break;
-            default:
-                System.out.println("Ignored param: " + paramKey + ":" + 
paramValue);
-            }
-        }
-    }
-
-    @Override
-    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain 
chain)
-            throws IOException, ServletException {
-        HttpServletRequest request = (HttpServletRequest) req;
-        // Redirection from the authenticator server
-        String code = req.getParameter(SESSION_KEY_CODE);
-
-        // Getting token, if exists, from the current session
-        String token = (String) 
request.getSession().getAttribute(SESSION_KEY_ACCESS_TOKEN);
-
-        boolean continueFilterProcessing;
-        if (code != null && !"".equals(code)) { // in brooklyn, have
-                                                // Strings.isNonBlank(code)
-            continueFilterProcessing = getToken(req, resp, chain);
-        } else if (token == null || "".equals(token)) { // isBlank
-            continueFilterProcessing = redirectLogin(resp);
-        } else {
-            continueFilterProcessing = validateToken(token, resp);
-        }
-        if (continueFilterProcessing) {
-            chain.doFilter(req, resp);
-        }
-    }
-
-    private boolean validateToken(String token, ServletResponse resp) throws 
ClientProtocolException, IOException {
-        // System.out.println("########################### Validating token
-        // ###########################");
-        HashMap<String, String> params = new HashMap<String, String>();
-        params.put(SESSION_KEY_ACCESS_TOKEN, token);
-
-        String body = post(uriTokenInfo, params);
-        // System.out.println(body);
-        Map<?,?> jsonObject = null;
-
-        // get the access token from json and request info from Google
-        try {
-            jsonObject = (Map<?,?>) Yamls.parseAll(body).iterator().next();
-            log.info("Parsed '"+body+"' as "+jsonObject);
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            log.info("Unable to parse: '"+body+"'");
-            throw new RuntimeException("Unable to parse json " + body, e);
-        }
-
-        if (!clientId.equals(jsonObject.get(audience))) {
-            return redirectLogin(resp);
-        }
-        // if (isTokenExpiredOrNearlySo(...) { ... }
-        return true;
-    }
-
-    private boolean getToken(ServletRequest req, ServletResponse resp, 
FilterChain chain)
-            throws ClientProtocolException, IOException, ServletException {
-        String code = req.getParameter(SESSION_KEY_CODE);
-
-        // get the access token by post to Google
-        HashMap<String, String> params = new HashMap<String, String>();
-        params.put(SESSION_KEY_CODE, code);
-        params.put("client_id", clientId);
-        params.put("client_secret", clientSecret);
-        params.put("redirect_uri", callbackUri);
-        params.put("grant_type", "authorization_code");
-
-        String body = post(uriGetToken, params);
-
-        Map<?,?> jsonObject = null;
-
-        // get the access token from json and request info from Google
-        try {
-            jsonObject = (Map<?,?>) Yamls.parseAll(body).iterator().next();
-            log.info("Parsed '"+body+"' as "+jsonObject);
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            log.info("Unable to parse: '"+body+"'");
-            return redirectLogin(resp);
-        }
-
-        // Left token and code in session
-        String accessToken = (String) jsonObject.get(SESSION_KEY_ACCESS_TOKEN);
-        HttpServletRequest request = (HttpServletRequest) req;
-        request.getSession().setAttribute(SESSION_KEY_ACCESS_TOKEN, 
accessToken);
-        request.getSession().setAttribute(SESSION_KEY_CODE, code);
-
-        // resp.getWriter().println(json);
-        return true;
-    }
-
-    // makes a POST request to url with form parameters and returns body as a
-    // string
-    public String post(String url, Map<String, String> formParameters) throws 
ClientProtocolException, IOException {
-        HttpPost request = new HttpPost(url);
-
-        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
-        for (String key : formParameters.keySet()) {
-            nvps.add(new BasicNameValuePair(key, formParameters.get(key)));
-        }
-        request.setEntity(new UrlEncodedFormEntity(nvps));
-
-        return execute(request);
-    }
-
-    // makes a GET request to url and returns body as a string
-    public String get(String url) throws ClientProtocolException, IOException {
-        return execute(new HttpGet(url));
-    }
-
-    // makes request and checks response code for 200
-    private String execute(HttpRequestBase request) throws 
ClientProtocolException, IOException {
-        HttpClient httpClient = new DefaultHttpClient();
-        HttpResponse response = httpClient.execute(request);
-
-        HttpEntity entity = response.getEntity();
-        String body = EntityUtils.toString(entity);
-
-        if (response.getStatusLine().getStatusCode() != 200) {
-            throw new RuntimeException(
-                    "Expected 200 but got " + 
response.getStatusLine().getStatusCode() + ", with body " + body);
-        }
-
-        return body;
-    }
-
-    private boolean redirectLogin(ServletResponse response) throws IOException 
{
-        HttpServletResponse res = (HttpServletResponse) response;
-        res.setContentType(ContentType.APPLICATION_XML.toString());
-        res.sendRedirect(uriTokenRedirect);
-        return false;
-    }
+//    @Override
+//    public void init(FilterConfig filterConfig) throws ServletException {
+//        log.info("GOOGLE FILTER 1");
+//        initializateParams(filterConfig);
+//    }
+//
+//    private void initializateParams(FilterConfig filterConfig) {
+//        Enumeration<String> enums = filterConfig.getInitParameterNames();
+//
+//        while (enums.hasMoreElements()) {
+//            String paramKey = enums.nextElement();
+//            String paramValue = filterConfig.getInitParameter(paramKey);
+//            System.out.println(paramKey + ":" + paramValue);
+//            switch (paramKey) {
+//            case PARAM_URI_TOKEN_INFO:
+//                uriTokenInfo = paramValue;
+//                break;
+//            case PARAM_URI_GETTOKEN:
+//                uriGetToken = paramValue;
+//                break;
+//            case PARAM_URI_LOGIN_REDIRECT:
+//                uriTokenRedirect = paramValue;
+//                break;
+//            case PARAM_CLIENT_ID:
+//                clientId = paramValue;
+//                break;
+//            case PARAM_CLIENT_SECRET:
+//                clientSecret = paramValue;
+//                break;
+//            case PARAM_CALLBACK_URI:
+//                callbackUri = paramValue;
+//                break;
+//            case PARAM_AUDIENCE:
+//                audience = paramValue;
+//                break;
+//            default:
+//                System.out.println("Ignored param: " + paramKey + ":" + 
paramValue);
+//            }
+//        }
+//    }
+//
+//    @Override
+//    public void doFilter(ServletRequest req, ServletResponse resp, 
FilterChain chain)
+//            throws IOException, ServletException {
+//        log.info("GOOGLE FILTER 2");
+//        HttpServletRequest request = (HttpServletRequest) req;
+//        // Redirection from the authenticator server
+//        String code = req.getParameter(SESSION_KEY_CODE);
+//
+//        // Getting token, if exists, from the current session
+//        String token = (String) 
request.getSession().getAttribute(SESSION_KEY_ACCESS_TOKEN);
+//
+//        boolean continueFilterProcessing;
+//        if (code != null && !"".equals(code)) { // in brooklyn, have
+//                                                // Strings.isNonBlank(code)
+//            continueFilterProcessing = getToken(req, resp, chain);
+//        } else if (token == null || "".equals(token)) { // isBlank
+//            continueFilterProcessing = redirectLogin(resp);
+//        } else {
+//            continueFilterProcessing = validateToken(token, resp);
+//        }
+//        if (continueFilterProcessing) {
+//            chain.doFilter(req, resp);
+//        }
+//    }
+//
+//    private boolean validateToken(String token, ServletResponse resp) throws 
ClientProtocolException, IOException {
+//        log.info("GOOGLE FILTER 3");
+//        // System.out.println("########################### Validating token
+//        // ###########################");
+//        HashMap<String, String> params = new HashMap<String, String>();
+//        params.put(SESSION_KEY_ACCESS_TOKEN, token);
+//
+//        String body = post(uriTokenInfo, params);
+//        // System.out.println(body);
+//        Map<?,?> jsonObject = null;
+//
+//        // get the access token from json and request info from Google
+//        try {
+//            jsonObject = (Map<?,?>) Yamls.parseAll(body).iterator().next();
+//            log.info("Parsed '"+body+"' as "+jsonObject);
+//        } catch (Exception e) {
+//            Exceptions.propagateIfFatal(e);
+//            log.info("Unable to parse: '"+body+"'");
+//            throw new RuntimeException("Unable to parse json " + body, e);
+//        }
+//
+//        if (!clientId.equals(jsonObject.get(audience))) {
+//            return redirectLogin(resp);
+//        }
+//        // if (isTokenExpiredOrNearlySo(...) { ... }
+//        return true;
+//    }
+//
+//    private boolean getToken(ServletRequest req, ServletResponse resp, 
FilterChain chain)
+//            throws ClientProtocolException, IOException, ServletException {
+//        String code = req.getParameter(SESSION_KEY_CODE);
+//
+//        // get the access token by post to Google
+//        HashMap<String, String> params = new HashMap<String, String>();
+//        params.put(SESSION_KEY_CODE, code);
+//        params.put("client_id", clientId);
+//        params.put("client_secret", clientSecret);
+//        params.put("redirect_uri", callbackUri);
+//        params.put("grant_type", "authorization_code");
+//
+//        String body = post(uriGetToken, params);
+//
+//        Map<?,?> jsonObject = null;
+//
+//        // get the access token from json and request info from Google
+//        try {
+//            jsonObject = (Map<?,?>) Yamls.parseAll(body).iterator().next();
+//            log.info("Parsed '"+body+"' as "+jsonObject);
+//        } catch (Exception e) {
+//            Exceptions.propagateIfFatal(e);
+//            log.info("Unable to parse: '"+body+"'");
+//            return redirectLogin(resp);
+//        }
+//
+//        // Left token and code in session
+//        String accessToken = (String) 
jsonObject.get(SESSION_KEY_ACCESS_TOKEN);
+//        HttpServletRequest request = (HttpServletRequest) req;
+//        request.getSession().setAttribute(SESSION_KEY_ACCESS_TOKEN, 
accessToken);
+//        request.getSession().setAttribute(SESSION_KEY_CODE, code);
+//
+//        // resp.getWriter().println(json);
+//        return true;
+//    }
+//
+//    // makes a POST request to url with form parameters and returns body as a
+//    // string
+//    public String post(String url, Map<String, String> formParameters) 
throws ClientProtocolException, IOException {
+//        HttpPost request = new HttpPost(url);
+//
+//        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+//        for (String key : formParameters.keySet()) {
+//            nvps.add(new BasicNameValuePair(key, formParameters.get(key)));
+//        }
+//        request.setEntity(new UrlEncodedFormEntity(nvps));
+//
+//        return execute(request);
+//    }
+//
+//    // makes a GET request to url and returns body as a string
+//    public String get(String url) throws ClientProtocolException, 
IOException {
+//        return execute(new HttpGet(url));
+//    }
+//
+//    // makes request and checks response code for 200
+//    private String execute(HttpRequestBase request) throws 
ClientProtocolException, IOException {
+//        HttpClient httpClient = new DefaultHttpClient();
+//        HttpResponse response = httpClient.execute(request);
+//
+//        HttpEntity entity = response.getEntity();
+//        String body = EntityUtils.toString(entity);
+//
+//        if (response.getStatusLine().getStatusCode() != 200) {
+//            throw new RuntimeException(
+//                    "Expected 200 but got " + 
response.getStatusLine().getStatusCode() + ", with body " + body);
+//        }
+//
+//        return body;
+//    }
+//
+//    private boolean redirectLogin(ServletResponse response) throws 
IOException {
+//        HttpServletResponse res = (HttpServletResponse) response;
+//        res.setContentType(ContentType.APPLICATION_XML.toString());
+//        res.sendRedirect(uriTokenRedirect);
+//        return false;
+//    }
 
     @Override
-    public void destroy() {
+    public void filter(ContainerRequestContext requestContext) throws 
IOException {
+        log.info("GOOGLE FILTER 2");
         // TODO Auto-generated method stub
+        
     }
 
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/BrooklynLoginModule.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/BrooklynLoginModule.java
index 9765349..9374fbe 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/BrooklynLoginModule.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/BrooklynLoginModule.java
@@ -60,28 +60,8 @@ import static 
com.google.common.base.Preconditions.checkNotNull;
  * JAAS module delegating authentication to the {@link SecurityProvider} 
implementation
  * configured in {@literal brooklyn.properties}, key {@literal 
brooklyn.webconsole.security.provider}.
  * <p>
- * <p>
- * If used in an OSGi environment only implementations visible from {@literal 
brooklyn-rest-server} are usable by default.
- * To use a custom security provider add the following configuration to the 
its bundle in {@literal 
src/main/resources/OSGI-INF/bundle/security-provider.xml}:
- * <p>
- * <pre>
- * {@code
- * <?xml version="1.0" encoding="UTF-8"?>
- * <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
- *           xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.1.0";
- *           
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0";>
- *
- *    <jaas:config name="karaf" rank="1">
- *        <jaas:module 
className="org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule"
- *                     flags="required">
- *            
brooklyn.webconsole.security.provider.symbolicName=BUNDLE_SYMBOLIC_NAME
- *            brooklyn.webconsole.security.provider.version=BUNDLE_VERSION
- *        </jaas:module>
- *    </jaas:config>
- *
- * </blueprint>
- * }
- * </pre>
+ * We have also supported configuring this as options in OSGi;
+ * this is now deprecated, but see {@link 
#initProviderFromOptions(StringConfigMap)} for more info.
  */
 // Needs an explicit "org.apache.karaf.jaas.config" Import-Package in the 
manifest!
 public class BrooklynLoginModule implements LoginModule {
@@ -171,75 +151,127 @@ public class BrooklynLoginModule implements LoginModule {
 
     @Override
     public void initialize(Subject subject, CallbackHandler callbackHandler, 
Map<String, ?> sharedState, Map<String, ?> options) {
-        this.subject = subject;
-        this.callbackHandler = callbackHandler;
-        this.options = options;
-
-        this.bundleContext = (BundleContext) 
options.get(BundleContext.class.getName());
-
-        loginSuccess = false;
-        commitSuccess = false;
-
-        initProvider();
+        try {
+            this.subject = subject;
+            this.callbackHandler = callbackHandler;
+            this.options = options;
+    
+            this.bundleContext = (BundleContext) 
options.get(BundleContext.class.getName());
+    
+            loginSuccess = false;
+            commitSuccess = false;
+    
+            initProvider();
+            
+        } catch (Exception e) {
+            log.warn("Unable to initialize BrooklynLoginModule: "+e, e);
+            Exceptions.propagateIfFatal(e);
+        }
     }
 
     private void initProvider() {
+        // use existing (shared) provider if there is one, for speed
+        // (note this login module class gets a different instance on each 
request; caching the provider is a big efficiency gain) 
         StringConfigMap brooklynProperties = 
getManagementContext().getConfig();
         provider = 
brooklynProperties.getConfig(BrooklynWebConfig.SECURITY_PROVIDER_INSTANCE);
-        log.info("ALEX BR LOGIN - INIT "+provider);
+        if (provider != null) return;
+        provider = 
getManagementContext().getScratchpad().get(BrooklynWebConfig.SECURITY_PROVIDER_INSTANCE);
+        if (provider != null) return;
+
+        initProviderFromOptions(brooklynProperties);
+        if (provider==null) {
+            // no osgi options set, so use the standard properties-based one 
(usual path)
+            provider = createDefaultSecurityProvider(getManagementContext());
+        }
+
+        log.debug("Using security provider " + provider);
+    }
+
+    /**
+     * We have since switching to OSGi also allowed the provider to be 
specified as an option in the
+     * OSGi blueprint. This has never been used AFAIK in the real world but it 
was the only way to specify a bundle. 
+     * Note that only implementations visible from {@literal 
brooklyn-rest-server} are usable by default.
+     * We now support specifying a bundle for the delegate, but this is being 
left in as deprecated.
+     * To use this <b>deprecated</b> configuration with a custom security 
provider, 
+     * add the following configuration to the its bundle in {@literal 
src/main/resources/OSGI-INF/bundle/security-provider.xml}:
+     * <p>
+     * <pre>
+     * {@code
+     * <?xml version="1.0" encoding="UTF-8"?>
+     * <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
+     *           xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.1.0";
+     *           
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0";>
+     *
+     *    <jaas:config name="karaf" rank="1">
+     *        <jaas:module 
className="org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule" 
flags="required">
+     *            
brooklyn.webconsole.security.provider.symbolicName=BUNDLE_SYMBOLIC_NAME
+     *            brooklyn.webconsole.security.provider.version=BUNDLE_VERSION
+     *        </jaas:module>
+     *    </jaas:config>
+     *
+     * </blueprint>
+     * }
+     * </pre>
+     * @deprecated since 2019-01, use the brooklyn system properties 
+     * {@link BrooklynWebConfig#SECURITY_PROVIDER_CLASSNAME},
+     * {@link BrooklynWebConfig#SECURITY_PROVIDER_BUNDLE}, and
+     * {@link BrooklynWebConfig#SECURITY_PROVIDER_BUNDLE_VERSION},
+     */
+    protected void initProviderFromOptions(StringConfigMap brooklynProperties) 
{
+        // this uses *options* to determine the security provider to load
+        // (not sure this is ever used)
         String symbolicName = (String) 
options.get(PROPERTY_BUNDLE_SYMBOLIC_NAME);
         String version = (String) options.get(PROPERTY_BUNDLE_VERSION);
         String className = (String) 
options.get(BrooklynWebConfig.SECURITY_PROVIDER_CLASSNAME.getName());
         if (className != null && symbolicName == null) {
             throw new IllegalStateException("Missing JAAS module property " + 
PROPERTY_BUNDLE_SYMBOLIC_NAME + " pointing at the bundle where to load the 
security provider from.");
         }
-        if (provider != null) return;
-        provider = 
getManagementContext().getScratchpad().get(BrooklynWebConfig.SECURITY_PROVIDER_INSTANCE);
-        if (provider != null) return;
         if (symbolicName != null) {
             if (className == null) {
                 className = 
brooklynProperties.getConfig(BrooklynWebConfig.SECURITY_PROVIDER_CLASSNAME);
             }
             if (className != null) {
-                try {
-                    Collection<Bundle> bundles = 
getMatchingBundles(symbolicName, version);
-                    if (bundles.isEmpty()) {
-                        throw new IllegalStateException("No bundle " + 
symbolicName + ":" + version + " found");
-                    } else if (bundles.size() > 1) {
-                        log.warn("Found multiple bundles matching symbolicName 
" + symbolicName + " and version " + version +
-                                " while trying to load security provider " + 
className + ". Will use first one that loads the class successfully.");
-                    }
-                    provider = tryLoadClass(className, bundles);
-                    if (provider == null) {
-                        throw new ClassNotFoundException("Unable to load class 
" + className + " from bundle " + symbolicName + ":" + version);
-                    }
-                } catch (Exception e) {
-                    Exceptions.propagateIfFatal(e);
-                    throw new IllegalStateException("Can not load or create 
security provider " + className + " for bundle " + symbolicName + ":" + 
version, e);
-                }
+                provider = loadProviderFromBundle(getManagementContext(), 
bundleContext, symbolicName, version, className);
             }
-        } else {
-            log.debug("Delegating security provider loading to Brooklyn.");
-            provider = createDefaultSecurityProvider(getManagementContext());
         }
+    }
 
-        log.debug("Using security provider " + provider);
+    public static SecurityProvider loadProviderFromBundle(
+            ManagementContext mgmt, BundleContext bundleContext,
+            String symbolicName, String version, String className) {
+        try {
+            Collection<Bundle> bundles = getMatchingBundles(bundleContext, 
symbolicName, version);
+            if (bundles.isEmpty()) {
+                throw new IllegalStateException("No bundle " + symbolicName + 
":" + version + " found");
+            } else if (bundles.size() > 1) {
+                log.warn("Found multiple bundles matching symbolicName " + 
symbolicName + " and version " + version +
+                        " while trying to load security provider " + className 
+ ". Will use first one that loads the class successfully.");
+            }
+            SecurityProvider p = tryLoadClass(mgmt, className, bundles);
+            if (p == null) {
+                throw new ClassNotFoundException("Unable to load class " + 
className + " from bundle " + symbolicName + ":" + version);
+            }
+            return p;
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            throw new IllegalStateException("Can not load or create security 
provider " + className + " for bundle " + symbolicName + ":" + version, e);
+        }
     }
 
-    private SecurityProvider tryLoadClass(String className, Collection<Bundle> 
bundles)
+    private static SecurityProvider tryLoadClass(ManagementContext mgmt, 
String className, Collection<Bundle> bundles)
             throws NoSuchMethodException, InstantiationException, 
IllegalAccessException, InvocationTargetException {
         for (Bundle b : bundles) {
             try {
                 @SuppressWarnings("unchecked")
                 Class<? extends SecurityProvider> securityProviderType = 
(Class<? extends SecurityProvider>) b.loadClass(className);
-                return 
DelegatingSecurityProvider.createSecurityProviderInstance(getManagementContext(),
 securityProviderType);
+                return 
DelegatingSecurityProvider.createSecurityProviderInstance(mgmt, 
securityProviderType);
             } catch (ClassNotFoundException e) {
             }
         }
         return null;
     }
 
-    private Collection<Bundle> getMatchingBundles(final String symbolicName, 
final String version) {
+    private static Collection<Bundle> getMatchingBundles(BundleContext 
bundleContext, final String symbolicName, final String version) {
         Collection<Bundle> bundles = new ArrayList<>();
         for (Bundle b : bundleContext.getBundles()) {
             if (b.getSymbolicName().equals(symbolicName) &&
@@ -252,65 +284,84 @@ public class BrooklynLoginModule implements LoginModule {
 
     @Override
     public boolean login() throws LoginException {
-        if (callbackHandler == null) {
-            log.info("ALEX BR LOGIN - LOGIN 1");
-            loginSuccess = false;
-            throw new FailedLoginException("Username and password not 
available");
-        }
-
-        NameCallback cbName = new NameCallback("Username: ");
-        PasswordCallback cbPassword = new PasswordCallback("Password: ", 
false);
-
-        Callback[] callbacks = {cbName, cbPassword};
-        log.info("ALEX BR LOGIN - LOGIN 2 - "+cbName);
-
         try {
-            callbackHandler.handle(callbacks);
-        } catch (IOException ioe) {
-            throw new LoginException(ioe.getMessage());
-        } catch (UnsupportedCallbackException uce) {
-            throw new LoginException(uce.getMessage() + " not available to 
obtain information from user");
-        }
-        String user = cbName.getName();
-        String password = new String(cbPassword.getPassword());
-
-        providerSession = new SecurityProviderHttpSession();
-
-        Request req = getJettyRequest();
-        if (req != null) {
-            String remoteAddr = req.getRemoteAddr();
-            
providerSession.setAttribute(BrooklynWebConfig.REMOTE_ADDRESS_SESSION_ATTRIBUTE,
 remoteAddr);
-        }
-
-        if (!provider.authenticate(providerSession, user, password)) {
-            loginSuccess = false;
-            throw new FailedLoginException("Incorrect username or password");
-        }
-
-        if (user != null) {
-            providerSession.setAttribute(AUTHENTICATED_USER_SESSION_ATTRIBUTE, 
user);
-        }
-
-        principals = new ArrayList<>(2);
-        principals.add(new UserPrincipal(user));
-        // Could introduce a new interface SecurityRoleAware, implemented by
-        // the SecurityProviders, returning the roles a user has assigned.
-        // For now a static role is good enough.
-        String role = (String) options.get(PROPERTY_ROLE);
-        if (role == null) {
-            role = DEFAULT_ROLE;
-        }
-        if (Strings.isNonEmpty(role)) {
-            principals.add(new RolePrincipal(role));
+            log.info("ALEX BLM login - "+callbackHandler+" "+this+" 
"+provider);
+            String user=null, password=null;
+            
+            if (provider.requiresUserPass()) {
+                if (callbackHandler == null) {
+                    loginSuccess = false;
+                    throw new FailedLoginException("Username and password not 
available");
+                }
+        
+                NameCallback cbName = new NameCallback("Username: ");
+                PasswordCallback cbPassword = new PasswordCallback("Password: 
", false);
+        
+                Callback[] callbacks = {cbName, cbPassword};
+        
+                try {
+                    callbackHandler.handle(callbacks);
+                } catch (IOException ioe) {
+                    throw new LoginException(ioe.getMessage());
+                } catch (UnsupportedCallbackException uce) {
+                    throw new LoginException(uce.getMessage() + " not 
available to obtain information from user");
+                }
+                user = cbName.getName();
+                password = new String(cbPassword.getPassword());
+            }
+    
+    
+            Request req = getJettyRequest();
+            if (req != null) {
+                providerSession = req.getSession(false);
+            }
+            log.info("GOT SESSION - "+providerSession);
+            if (providerSession == null) {
+                providerSession = new SecurityProviderHttpSession();
+            }
+            if (req != null) {
+                String remoteAddr = req.getRemoteAddr();
+                
providerSession.setAttribute(BrooklynWebConfig.REMOTE_ADDRESS_SESSION_ATTRIBUTE,
 remoteAddr);
+            }
+    
+            if (!provider.authenticate(providerSession, user, password)) {
+                loginSuccess = false;
+                throw new FailedLoginException("Incorrect username or 
password");
+            }
+    
+            if (user != null) {
+                
providerSession.setAttribute(AUTHENTICATED_USER_SESSION_ATTRIBUTE, user);
+    
+                principals = new ArrayList<>(2);
+                principals.add(new UserPrincipal(user));
+                // Could introduce a new interface SecurityRoleAware, 
implemented by
+                // the SecurityProviders, returning the roles a user has 
assigned.
+                // For now a static role is good enough.
+                String role = (String) options.get(PROPERTY_ROLE);
+                if (role == null) {
+                    role = DEFAULT_ROLE;
+                }
+                if (Strings.isNonEmpty(role)) {
+                    principals.add(new RolePrincipal(role));
+                }
+            }
+            
+            loginSuccess = true;
+            return true;
+        } catch (LoginException e) {
+            throw e;
+        } catch (Exception e) {
+            log.warn("Unexpected error during login: "+e, e);
+            throw e;
         }
-        loginSuccess = true;
-        return true;
     }
 
     @Override
     public boolean commit() throws LoginException {
-        log.info("ALEX BR LOGIN - COMMIT");
-        if (loginSuccess) {
+        log.info("ALEX BLM BR LOGIN - COMMIT");
+        if (loginSuccess && principals!=null && !principals.isEmpty()) {
+            // for oauth principals aren't set currently; they don't seem to 
be needed
+            
             if (subject.isReadOnly()) {
                 throw new LoginException("Can't commit read-only subject");
             }
@@ -323,6 +374,7 @@ public class BrooklynLoginModule implements LoginModule {
 
     @Override
     public boolean abort() throws LoginException {
+        log.info("ALEX BLM abort");
         if (loginSuccess && commitSuccess) {
             removePrincipal();
         }
@@ -348,6 +400,7 @@ public class BrooklynLoginModule implements LoginModule {
     }
 
     private void removePrincipal() throws LoginException {
+        if (principals==null || principals.isEmpty()) return;
         if (subject.isReadOnly()) {
             throw new LoginException("Read-only subject");
         }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/GoogleOauthLoginModule.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/GoogleOauthLoginModule.java
index 7a770cb..bd1493f 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/GoogleOauthLoginModule.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/jaas/GoogleOauthLoginModule.java
@@ -95,9 +95,9 @@ public class GoogleOauthLoginModule implements LoginModule {
     private String callbackUri = "http://localhost.io:8081/";;
     private String audience = "audience";
 
-    private static final String OAUTH2_TOKEN = 
"org.apache.activemq.jaas.oauth2.token";
-    private static final String OAUTH2_ROLE = 
"org.apache.activemq.jaas.oauth2.role";
-    private static final String OAUTH2_URL = 
"org.apache.activemq.jaas.oauth2.oauth2url";
+//    private static final String OAUTH2_TOKEN = 
"org.apache.activemq.jaas.oauth2.token";
+//    private static final String OAUTH2_ROLE = 
"org.apache.activemq.jaas.oauth2.role";
+//    private static final String OAUTH2_URL = 
"org.apache.activemq.jaas.oauth2.oauth2url";
     private Set<Principal> principals = new HashSet<>();
     private Subject subject;
     private CallbackHandler callbackHandler;
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/AnyoneSecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/AnyoneSecurityProvider.java
index 97b4fe1..7aa9ab3 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/AnyoneSecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/AnyoneSecurityProvider.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.rest.security.provider;
 
 import javax.servlet.http.HttpSession;
 
-/** provider who allows everyone */
+/** provider who allows everyone, but does require a user/pass to be provided 
*/
 public class AnyoneSecurityProvider implements SecurityProvider {
 
     @Override
@@ -29,6 +29,11 @@ public class AnyoneSecurityProvider implements 
SecurityProvider {
     }
 
     @Override
+    public boolean requiresUserPass() {
+        return true;
+    }
+    
+    @Override
     public boolean authenticate(HttpSession session, String user, String 
password) {
         return true;
     }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BlackholeSecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BlackholeSecurityProvider.java
index a976975..5418924 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BlackholeSecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BlackholeSecurityProvider.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.rest.security.provider;
 
 import javax.servlet.http.HttpSession;
 
-/** provider who disallows everyone */
+/** provider who disallows everyone, though it does require a user/pass */
 public class BlackholeSecurityProvider implements SecurityProvider {
 
     @Override
@@ -37,4 +37,10 @@ public class BlackholeSecurityProvider implements 
SecurityProvider {
     public boolean logout(HttpSession session) { 
         return true;
     }
+
+    @Override
+    public boolean requiresUserPass() {
+        return true;
+    }
+    
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java
index 7b8e4a5..3400d0a 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java
@@ -70,4 +70,9 @@ public class BrooklynUserWithRandomPasswordSecurityProvider 
extends AbstractSecu
     public String toString() {
         return JavaClassNames.cleanSimpleClassName(this);
     }
+    
+    @Override
+    public boolean requiresUserPass() {
+        return true;
+    }
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
index 94b7894..d5bb50b 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
@@ -27,9 +27,11 @@ import javax.servlet.http.HttpSession;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.StringConfigMap;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.rest.BrooklynWebConfig;
+import org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule;
 import org.apache.brooklyn.util.core.ClassLoaderUtils;
-import org.apache.brooklyn.util.text.Strings;
+import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -83,24 +85,20 @@ public class DelegatingSecurityProvider implements 
SecurityProvider {
                     this, delegate);
             return delegate;
         }
-        log.info("REST using security provider " + className);
 
         try {
-            ClassLoaderUtils clu = new ClassLoaderUtils(this, mgmt);
-            Class<? extends SecurityProvider> clazz;
-            try {
-                clazz = (Class<? extends SecurityProvider>) 
clu.loadClass(className);
-            } catch (Exception e) {
-                String oldPackage = "brooklyn.web.console.security.";
-                if (className.startsWith(oldPackage)) {
-                    className = Strings.removeFromStart(className, oldPackage);
-                    className = 
DelegatingSecurityProvider.class.getPackage().getName() + "." + className;
-                    clazz = (Class<? extends SecurityProvider>) 
clu.loadClass(className);
-                    log.warn("Deprecated package " + oldPackage + " detected; 
please update security provider to point to " + className);
-                } else throw e;
+            String bundle = 
brooklynProperties.getConfig(BrooklynWebConfig.SECURITY_PROVIDER_BUNDLE);
+            if (bundle!=null) {
+                String bundleVersion = 
brooklynProperties.getConfig(BrooklynWebConfig.SECURITY_PROVIDER_BUNDLE_VERSION);
+                log.info("REST using security provider " + className + " from 
" + bundle+":"+bundleVersion);
+                BundleContext bundleContext = 
((ManagementContextInternal)mgmt).getOsgiManager().get().getFramework().getBundleContext();
+                delegate = BrooklynLoginModule.loadProviderFromBundle(mgmt, 
bundleContext, bundle, bundleVersion, className);
+            } else {
+                log.info("REST using security provider " + className);
+                ClassLoaderUtils clu = new ClassLoaderUtils(this, mgmt);
+                Class<? extends SecurityProvider> clazz = (Class<? extends 
SecurityProvider>) clu.loadClass(className);
+                delegate = createSecurityProviderInstance(mgmt, clazz);
             }
-
-            delegate = createSecurityProviderInstance(mgmt, clazz);
         } catch (Exception e) {
             log.warn("REST unable to instantiate security provider " + 
className + "; all logins are being disallowed", e);
             delegate = new BlackholeSecurityProvider();
@@ -173,4 +171,15 @@ public class DelegatingSecurityProvider implements 
SecurityProvider {
     private String getModificationCountKey() {
         return getClass().getName() + ".ModCount";
     }
+    
+    @Override
+    public boolean requiresUserPass() {
+        return getDelegate().requiresUserPass();
+    }
+
+    @Override
+    public String toString() {
+        return super.toString()+"["+getDelegate()+"]";
+    }
+    
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java
index a0795cb..2d9be55 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java
@@ -114,4 +114,9 @@ public class ExplicitUsersSecurityProvider extends 
AbstractSecurityProvider impl
 
         return false;
     }
+    
+    @Override
+    public boolean requiresUserPass() {
+        return true;
+    }
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/GoogleOauthSecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/GoogleOauthSecurityProvider.java
index 21f022e..89e4844 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/GoogleOauthSecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/GoogleOauthSecurityProvider.java
@@ -18,29 +18,128 @@
  */
 package org.apache.brooklyn.rest.security.provider;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
+
 import org.apache.brooklyn.rest.filter.GoogleOauthFilter;
+import org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.text.Identifiers;
+import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.yaml.Yamls;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.servlet.http.HttpSession;
-
 /** provider who allows everyone */
 public class GoogleOauthSecurityProvider implements SecurityProvider {
 
     public static final Logger LOG = 
LoggerFactory.getLogger(GoogleOauthSecurityProvider.class);
 
+    private static final Logger logger = 
LoggerFactory.getLogger(BrooklynLoginModule.class);
+    private static final String SESSION_KEY_ACCESS_TOKEN = "access_token";
+    private static final String SESSION_KEY_CODE = "code";
+    private static final String FAKE_TOKEN_FOR_DEBUG = "fake_token";
+//    public static final String PARAM_URI_TOKEN_INFO = "uriTokenInfo";
+//    public static final String PARAM_URI_GETTOKEN = "uriGetToken";
+//    public static final String PARAM_URI_LOGIN_REDIRECT = "uriLoginRedirect";
+//    public static final String PARAM_CLIENT_ID = "clientId";
+//    public static final String PARAM_CLIENT_SECRET = "clientSecret";
+//    public static final String PARAM_CALLBACK_URI = "callbackUri";
+//    public static final String PARAM_AUDIENCE = "audience";
+
+    private String uriGetToken = "https://accounts.google.com/o/oauth2/token";;
+    private String uriAuthorize = "https://accounts.google.com/o/oauth2/auth";;
+    private String uriTokenInfo = 
"https://www.googleapis.com/oauth2/v1/tokeninfo";;
+    
+    // or github:
+//    private String uriGetToken = "https://github.com/login/oauth/authorize";;
+//    private String uriAuthorize = "https://github.com/login/oauth/authorize";;
+//    private String uriTokenInfo = 
"https://github.com/login/oauth/access_token";;
+    
+//    private String apiURLBase = "https://api.github.com/";;
+
+//    private String uriTokenRedirect = "/";
+    // google
+    // TODO parameterise
+    private String clientId = 
"789182012565-burd24h3bc0im74g2qemi7lnihvfqd02.apps.googleusercontent.com";
+    private String clientSecret = "X00v-LfU34U4SfsHqPKMWfQl";
+    // github
+//    private String clientId = "7f76b9970d8ac15b30b0";
+//    private String clientSecret = "9e15f8dd651f0b1896a3a582f17fa82f049fc910";
+    
+    // TODO
+    private String audience = "audience";
+
+//    private static final String OAUTH2_TOKEN = 
"org.apache.activemq.jaas.oauth2.token";
+//    private static final String OAUTH2_ROLE = 
"org.apache.activemq.jaas.oauth2.role";
+//    private static final String OAUTH2_URL = 
"org.apache.activemq.jaas.oauth2.oauth2url";
+//    private Set<Principal> principals = new HashSet<>();
+//    private Subject subject;
+//    private CallbackHandler callbackHandler;
+//    private boolean debug;
+//    private String roleName = "webconsole";
+//    private String oauth2URL = uriTokenInfo;
+//    private boolean loginSucceeded;
+//    private String userName;
+//    private boolean commitSuccess;
+    
     @Override
     public boolean isAuthenticated(HttpSession session) {
-        LOG.info("isAuthenticated");
+        LOG.info("isAuthenticated 1 "+session+" ... "+this);
         Object token = 
session.getAttribute(GoogleOauthFilter.SESSION_KEY_ACCESS_TOKEN);
-
+        // TODO is it valid?
         return token!=null;
     }
 
     @Override
     public boolean authenticate(HttpSession session, String user, String 
password) {
-        LOG.info("authenticate");
-        return true;
+        LOG.info("authenticate "+session+" "+user);
+        
+        if (isAuthenticated(session)) {
+            return true;
+        }
+        
+        Request request = getJettyRequest();
+        // Redirection from the authenticator server
+        String code = request.getParameter(SESSION_KEY_CODE);
+        // Getting token, if exists, from the current session
+        String token = (String) 
request.getSession().getAttribute(SESSION_KEY_ACCESS_TOKEN);
+        
+        try {
+            if (Strings.isNonBlank(code)) {
+                return getToken();
+            } else if (Strings.isEmpty(token)) {
+                return redirectLogin();
+            } else {
+                return validateToken(token);
+            }
+        } catch (Exception e) {
+            LOG.warn("Error performing OAuth: "+e, e);
+            throw Exceptions.propagate(e);
+        }
     }
 
     @Override
@@ -49,4 +148,162 @@ public class GoogleOauthSecurityProvider implements 
SecurityProvider {
         session.removeAttribute(GoogleOauthFilter.SESSION_KEY_ACCESS_TOKEN);
         return true;
     }
+    
+    @Override
+    public boolean requiresUserPass() {
+        return false;
+    }
+
+    private boolean getToken() throws ClientProtocolException, IOException, 
ServletException {
+        Request request = getJettyRequest();
+        String code = request.getParameter(SESSION_KEY_CODE);
+        String callbackUri = request.getRequestURL().toString();
+
+        // get the access token by post to Google
+        HashMap<String, String> params = new HashMap<String, String>();
+        params.put(SESSION_KEY_CODE, code);
+        params.put("client_id", clientId);
+        params.put("client_secret", clientSecret);
+        params.put("redirect_uri", callbackUri);
+        params.put("grant_type", "authorization_code");
+
+        String body = post(uriGetToken, params);
+
+        Map<?,?> jsonObject = null;
+
+        // get the access token from json and request info from Google
+        try {
+            jsonObject = (Map<?,?>) Yamls.parseAll(body).iterator().next();
+            logger.info("Parsed '"+body+"' as "+jsonObject);
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            logger.info("Unable to parse: '"+body+"'");
+            // throw new RuntimeException("Unable to parse json " + body);
+            return redirectLogin();
+        }
+
+        // Left token and code in session
+        String accessToken = (String) jsonObject.get(SESSION_KEY_ACCESS_TOKEN);
+        request.getSession().setAttribute(SESSION_KEY_ACCESS_TOKEN, 
accessToken);
+        request.getSession().setAttribute(SESSION_KEY_CODE, code);
+
+        // TODO is it valid?
+        LOG.debug("Got token/code "+accessToken+"/"+code+" from "+jsonObject);
+        // resp.getWriter().println(json);
+        return true;
+    }
+    
+    private boolean validateToken(String token) throws 
ClientProtocolException, IOException {
+        // TODO for debug
+        if(token.equals(FAKE_TOKEN_FOR_DEBUG)){
+            return true;
+        }
+        HashMap<String, String> params = new HashMap<String, String>();
+        params.put(SESSION_KEY_ACCESS_TOKEN, token);
+
+        String body = post(uriTokenInfo, params);
+        // System.out.println(body);
+        Map<?,?> jsonObject = null;
+
+        // get the access token from json and request info from Google
+        try {
+            jsonObject = (Map<?,?>) Yamls.parseAll(body).iterator().next();
+            logger.info("Parsed '"+body+"' as "+jsonObject);
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            logger.info("Unable to parse: '"+body+"'");
+            throw new RuntimeException("Unable to parse json " + body, e);
+        }
+
+        // TODO what's this for?
+        if (!clientId.equals(jsonObject.get(audience))) {
+            return redirectLogin();
+        }
+        // if (isTokenExpiredOrNearlySo(...) { ... }
+        return true;
+    }
+
+    // TODO these http methods need tidying
+    
+    // makes a GET request to url and returns body as a string
+    public String get(String url) throws ClientProtocolException, IOException {
+        return execute(new HttpGet(url));
+    }
+    
+    // makes a POST request to url with form parameters and returns body as a
+    // string
+    public String post(String url, Map<String, String> formParameters) throws 
ClientProtocolException, IOException {
+        HttpPost request = new HttpPost(url);
+
+        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+        for (String key : formParameters.keySet()) {
+            nvps.add(new BasicNameValuePair(key, formParameters.get(key)));
+        }
+        request.setEntity(new UrlEncodedFormEntity(nvps));
+
+        return execute(request);
+    }
+    
+    // makes request and checks response code for 200
+    private String execute(HttpRequestBase request) throws 
ClientProtocolException, IOException {
+        // TODO tidy
+        HttpClient httpClient = new DefaultHttpClient();
+        HttpResponse response = httpClient.execute(request);
+
+        HttpEntity entity = response.getEntity();
+        String body = EntityUtils.toString(entity);
+
+        if (response.getStatusLine().getStatusCode() != 200) {
+            throw new RuntimeException(
+                    "Expected 200 but got " + 
response.getStatusLine().getStatusCode() + ", with body " + body);
+        }
+
+        return body;
+    }
+
+    private boolean redirectLogin() throws IOException {
+        String state=Identifiers.makeRandomId(12); //should be stored in 
session
+        String callbackUri = getJettyRequest().getRequestURL().toString();
+        StringBuilder oauthUrl = new StringBuilder().append(uriAuthorize)
+                .append("?response_type=").append("code")
+                .append("&client_id=").append(clientId) // the client id from 
the api console registration
+                .append("&redirect_uri=").append(callbackUri) // the servlet 
that github redirects to after
+                // authorization
+//                .append("&scope=").append("user public_repo")
+                .append("&scope=openid%20email") // scope is the api 
permissions we
+                .append("&state=").append(state)
+                .append("&access_type=offline") // here we are asking to 
access to user's data while they are not
+                // signed in
+                .append("&approval_prompt=force"); // this requires them to 
verify which account to use, if they are
+        // already signed in
+
+        // just for look inside
+//        Collection<String> originalHeaders = response.getHeaderNames();
+
+        Response response = getJettyResponse();
+        response.reset();
+//        response.addHeader("Origin", "http://localhost.io:8081";);
+//        response.addHeader("Access-Control-Allow-Origin", "*");
+////        response.addHeader("Access-Control-Request-Method", "GET, POST");
+////        response.addHeader("Access-Control-Request-Headers", "origin, 
x-requested-with");
+        LOG.info("OAUTH url redirect is: "+oauthUrl.toString());
+        
+        response.sendRedirect(oauthUrl.toString());
+
+        return false;
+    }
+
+    private Request getJettyRequest() {
+        return Optional.ofNullable(HttpConnection.getCurrentConnection())
+                .map(HttpConnection::getHttpChannel)
+                .map(HttpChannel::getRequest)
+                .orElse(null);
+    }
+
+    private Response getJettyResponse() {
+        return Optional.ofNullable(HttpConnection.getCurrentConnection())
+                .map(HttpConnection::getHttpChannel)
+                .map(HttpChannel::getResponse)
+                .orElse(null);
+    }
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/LdapSecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/LdapSecurityProvider.java
index d3636e9..cc9b013 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/LdapSecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/LdapSecurityProvider.java
@@ -129,4 +129,9 @@ public class LdapSecurityProvider extends 
AbstractSecurityProvider implements Se
             throw Exceptions.propagate(new ClassNotFoundException("Unable to 
load LDAP classes ("+LDAP_CONTEXT_FACTORY+") required for Brooklyn LDAP 
security provider"));
         }
     }
+    
+    @Override
+    public boolean requiresUserPass() {
+        return true;
+    }
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/SecurityProvider.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/SecurityProvider.java
index 57d1400..42575ff 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/SecurityProvider.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/SecurityProvider.java
@@ -28,8 +28,13 @@ import javax.servlet.http.HttpSession;
 public interface SecurityProvider {
 
     public boolean isAuthenticated(HttpSession session);
-    
-    public boolean authenticate(HttpSession session, String user, String 
password);
-    
+    /** whether this provider requires a user/pass; if this returns false, the 
framework can
+     * send null/null as the user/pass to {@link #authenticate(HttpSession, 
String, String)},
+     * and should do that if user/pass info is not immediately available
+     * (ie for things like oauth, the framework should not require basic auth 
if this method returns false)
+     */
+    public boolean requiresUserPass();
+    public boolean authenticate(HttpSession session, String user, String pass);
     public boolean logout(HttpSession session);
+    
 }
diff --git 
a/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml 
b/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml
index e0b6c9f..dc40b44 100644
--- a/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml
+++ b/rest/rest-resources/src/main/resources/OSGI-INF/blueprint/service.xml
@@ -59,11 +59,6 @@ limitations under the License.
     <reference id="localManagementContext"
                
interface="org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal"/>
 
-    <jaas:config name="webconsole">
-        <!-- <jaas:module 
className="org.apache.brooklyn.rest.security.jaas.GoogleOauthLoginModule" 
flags="required"/>  -->
-        <jaas:module 
className="org.apache.brooklyn.rest.security.jaas.BrooklynLoginModule" 
flags="required"/>
-    </jaas:config>
-
     <reference id="shutdownHandler" 
interface="org.apache.brooklyn.core.mgmt.ShutdownHandler"/>
 
     <bean 
class="org.apache.brooklyn.rest.security.jaas.ManagementContextHolder">
@@ -117,10 +112,7 @@ limitations under the License.
             <bean 
class="org.apache.brooklyn.rest.util.DefaultExceptionMapper"/>
             <bean 
class="org.apache.brooklyn.rest.util.json.BrooklynJacksonJsonProvider"/>
             <bean class="org.apache.brooklyn.rest.util.FormMapProvider"/>
-            <bean 
class="org.apache.cxf.jaxrs.security.JAASAuthenticationFilter">
-                <property name="contextName" value="webconsole"/>
-                <property name="realmName" value="webconsole"/>
-            </bean>
+            <bean 
class="org.apache.brooklyn.rest.filter.BrooklynSecurityProviderFilter"/>
             <bean 
class="org.apache.brooklyn.rest.util.ManagementContextProvider">
                 <argument ref="localManagementContext"/>
             </bean>
diff --git a/rest/rest-resources/src/main/resources/jaas.conf 
b/rest/rest-resources/src/main/resources/jaas.conf
deleted file mode 100644
index 45dc90a..0000000
--- a/rest/rest-resources/src/main/resources/jaas.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-webconsole {
-   org.apache.brooklyn.rest.security.jaas.GoogleOauthLoginModule required;
-};
diff --git 
a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
 
b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
index f5089a1..fcdea9d 100644
--- 
a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
+++ 
b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/filter/BrooklynPropertiesSecurityFilter.java
@@ -60,7 +60,7 @@ public class BrooklynPropertiesSecurityFilter implements 
Filter {
      */
     public static final String AUTHENTICATED_USER_SESSION_ATTRIBUTE = 
BrooklynLoginModule.AUTHENTICATED_USER_SESSION_ATTRIBUTE;
 
-    private static final Logger log = 
LoggerFactory.getLogger(BrooklynPropertiesSecurityFilter.class);
+    private static final Logger log = 
LoggerFactory.getLogger(BrooklynSecurityProviderFilter.class);
 
     protected DelegatingSecurityProvider provider;
 
diff --git 
a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/entitlement/AuthenticateAnyoneSecurityProvider.java
 
b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/entitlement/AuthenticateAnyoneSecurityProvider.java
index b7264b2..d231886 100644
--- 
a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/entitlement/AuthenticateAnyoneSecurityProvider.java
+++ 
b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/entitlement/AuthenticateAnyoneSecurityProvider.java
@@ -38,4 +38,9 @@ public class AuthenticateAnyoneSecurityProvider implements 
SecurityProvider {
     public boolean logout(HttpSession session) {
         return false;
     }
+
+    @Override
+    public boolean requiresUserPass() {
+        return true;
+    }
 }
\ No newline at end of file
diff --git 
a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/security/provider/TestSecurityProvider.java
 
b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/security/provider/TestSecurityProvider.java
index cad251f..d6350d0 100644
--- 
a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/security/provider/TestSecurityProvider.java
+++ 
b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/security/provider/TestSecurityProvider.java
@@ -43,4 +43,9 @@ public class TestSecurityProvider implements SecurityProvider 
{
     public boolean logout(HttpSession session) {
         return false;
     }
+    
+    @Override
+    public boolean requiresUserPass() {
+        return true;
+    }
 }

Reply via email to