Last updated Sep 4, 2024

Control access with SAL

By now, you're well-acquainted with the environment your plugin runs in. In this section, you'll add SAL (Secure Access Layer) modules to your plugin and update the subsequent dependencies in your pom.xml. This section includes the following concepts and instructions:

Learn more about SAL

SAL is a component library of the Atlassian development platform. SAL supplies core plugin services shared between all Atlassian applications. Since your plugin is compatible with all Atlassian applications, SAL is an apt API to use in development.

Step 1. Check that SAL modules have been added

The atlas-create-refapp-plugin command has already generated com.atlassian.sal as a dependency. In pom.xml, look for the following dependency:

1
2
<dependency>
    <groupId>com.atlassian.sal</groupId>
    <artifactId>sal-api</artifactId>
    <scope>provided</scope>
</dependency>

Step 2. Update MyPluginServlet.java

Now that you've added additional APIs to your project you'll update the import statements as well as the body of the class.

  1. Open MyPluginServlet.java in Eclipse.

  2. Replace your class with the following: 

    1
    2
    package com.atlassian.plugins.tutorial.refapp;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import javax.servlet.*;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.net.URI;
    import com.atlassian.annotations.security.AdminOnly;
    import com.atlassian.sal.api.auth.LoginUriProvider;
    import com.atlassian.sal.api.user.UserManager;
    import com.atlassian.sal.api.user.UserProfile;
    import com.atlassian.sal.api.websudo.WebSudoManager;
    import com.atlassian.sal.api.websudo.WebSudoSessionException;
    import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
    import javax.inject.Inject;
    
    import static java.util.Objects.requireNonNull;
    
    public class MyPluginServlet extends HttpServlet {
        private static final Logger log = LoggerFactory.getLogger(MyPluginServlet.class);
        @ComponentImport
        private final UserManager userManager;
        @ComponentImport
        private final LoginUriProvider loginUriProvider;
        @ComponentImport
        private final WebSudoManager webSudoManager;
    
        @Inject
        public MyPluginServlet(final UserManager userManager,
                               final LoginUriProvider loginUriProvider,
                               final WebSudoManager webSudoManager) {
            this.userManager = requireNonNull(userManager, "userManager");
            this.loginUriProvider = requireNonNull(loginUriProvider, "loginUriProvider");
            this.webSudoManager = requireNonNull(webSudoManager, "webSudoManager");
        }
    
        @AdminOnly
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
            UserProfile user = userManager.getRemoteUser(request);
            Boolean isUserAdmin = false;
        
            if (user != null) {
                isUserAdmin = userManager.isSystemAdmin(user.getUserKey());
                if (isUserAdmin) {
                    try {
                        // all admin pages and actions require websudo
                        webSudoManager.willExecuteWebSudoRequest(request);
    
                        response.setContentType("text/html");
                        response.getWriter().write("<html><body>Hi again! Looking good.</body></html>");
                        return;
                    } catch(WebSudoSessionException exception) {
                        webSudoManager.enforceWebSudoProtection(request, response);
                        return;
                    }
                } else {
                    // should respond with an access denied as appropriate
                }
            }
            
            redirectToLogin(request, response);
        }
    
        private void redirectToLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.sendRedirect(loginUriProvider.getLoginUri(getUri(request)).toASCIIString());
        }
    
        private URI getUri(HttpServletRequest request) {
            StringBuffer builder = request.getRequestURL();
            if (request.getQueryString() != null) {
                builder.append("?");
                builder.append(request.getQueryString());
            }
            return URI.create(builder.toString());
        }
    }
    

    The new contents of MyPluginServlet add import statements for UserManager and LoginUriProvider. The class now checks to see if the user is logged in (if their username isn't null). If users aren't logged in, sendRedirect will prompt the user to log in.

    In this example with admin only view, we've added WebSudo (required for all admin view and actions) and @AdminOnly (security annotations are required for all servlets, servlet filters, and REST resources)

    You haven't yet added anything in MyPluginServlet.java  corresponding to TemplateRenderer or PluginSettingsFactory. You'll add dependencies in future steps.

  3. Save your changes and close MyPluginServlet.

Step 3. Run QuickReload to Update Changes

In order to load the changes in JIRA and verify that your UserManager and LoginUriProvider services are working with your plugin, instead of taking down the JIRA instance and restarting using atlas-run, it is quicker and easier to use QuickReload to reload the plugin.

  1. Run atlas-mvn package in the project root adminUI to reload the plugin.
  2. Navigate to your running instance of JIRA in your browser.
    JIRA is usually accessible at localhost:2990/jira/secure/Dashboard.jspa.
  3. Navigate to your plugin at localhost:2990/jira/plugins/servlet/test.
    If already logged in, you should see the "Hi again! Looking good" message.
    If you're not logged in, you'll be prompted to log in with your credentials (admin/admin):
    When you click Login, you'll be redirect to the plugin as depicted earlier.

Next Steps

You've added SAL services to your plugin and verified that your dependencies are correctly configured. Now, create a GUI using Atlassian User Interface (AUI) resources and templates.

Rate this page: