Class SecurityRealm

All Implemented Interfaces:
ExtensionPoint, Describable<SecurityRealm>
Direct Known Subclasses:
AbstractPasswordBasedSecurityRealm, LegacySecurityRealm

public abstract class SecurityRealm extends AbstractDescribableImpl<SecurityRealm> implements ExtensionPoint
Pluggable security realm that connects external user database to Hudson.

If additional views/URLs need to be exposed, an active SecurityRealm is bound to CONTEXT_ROOT/securityRealm/ through Jenkins.getSecurityRealm(), so you can define additional pages and operations on your SecurityRealm.

How do I implement this class?

For compatibility reasons, there are two somewhat different ways to implement a custom SecurityRealm.

One is to override the createSecurityComponents() and create key Spring Security components that control the authentication process. The default createFilter(FilterConfig) implementation then assembles them into a chain of Filters. All the incoming requests to Hudson go through this filter chain, and when the filter chain is done, SecurityContext.getAuthentication() would tell us who the current user is.

If your SecurityRealm needs to touch the default Filter chain configuration (e.g., adding new ones), then you can also override createFilter(FilterConfig) to do so.

This model is expected to fit most SecurityRealm implementations.

The other way of doing this is to ignore createSecurityComponents() completely (by returning SecurityRealm.SecurityComponents created by the default constructor) and just concentrate on createFilter(FilterConfig). As long as the resulting filter chain properly sets up Authentication object at the end of the processing, Jenkins doesn't really need you to fit the standard Spring Security models like AuthenticationManager and UserDetailsService.

This model is for those "weird" implementations.

Views

loginLink.jelly
This view renders the login link on the top right corner of every page, when the user is anonymous. For SecurityRealms that support user sign-up, this is a good place to show a "sign up" link. See HudsonPrivateSecurityRealm implementation for an example of this.
config.jelly
This view is used to render the configuration page in the system config screen.
Since:
1.160
Author:
Kohsuke Kawaguchi
See Also:
  • Field Details

    • NO_AUTHENTICATION

      public static final SecurityRealm NO_AUTHENTICATION
      Singleton constant that represents "no authentication."
    • LIST

      @Deprecated public static final DescriptorList<SecurityRealm> LIST
      Deprecated.
      as of 1.286 Use all() for read access, and use Extension for registration.
      All registered SecurityRealm implementations.
    • AUTHENTICATED_AUTHORITY2

      public static final org.springframework.security.core.GrantedAuthority AUTHENTICATED_AUTHORITY2
      GrantedAuthority that represents the built-in "authenticated" role, which is granted to anyone non-anonymous.
      Since:
      2.266
    • AUTHENTICATED_AUTHORITY

      @Deprecated public static final GrantedAuthority AUTHENTICATED_AUTHORITY
      Deprecated.
  • Constructor Details

    • SecurityRealm

      public SecurityRealm()
  • Method Details

    • createSecurityComponents

      public abstract SecurityRealm.SecurityComponents createSecurityComponents()
      Creates fully-configured AuthenticationManager that performs authentication against the user realm. The implementation hides how such authentication manager is configured.

      AuthenticationManager instantiation often depends on the user-specified parameters (for example, if the authentication is based on LDAP, the user needs to specify the host name of the LDAP server.) Such configuration is expected to be presented to the user via config.jelly and then captured as instance variables inside the SecurityRealm implementation.

      Your SecurityRealm may also wants to alter Filter set up by overriding createFilter(FilterConfig).

    • getUserIdStrategy

      public IdStrategy getUserIdStrategy()
      Returns the IdStrategy that should be used for turning UserDetails.getUsername() into an ID. Mostly this should be IdStrategy.CaseInsensitive but there may be occasions when either IdStrategy.CaseSensitive or IdStrategy.CaseSensitiveEmailAddress are the correct approach.
      Returns:
      the IdStrategy that should be used for turning UserDetails.getUsername() into an ID.
      Since:
      1.566
    • getGroupIdStrategy

      public IdStrategy getGroupIdStrategy()
      Returns the IdStrategy that should be used for turning GroupDetails.getName() into an ID. Note: Mostly this should be the same as getUserIdStrategy() but some security realms may have legitimate reasons for a different strategy.
      Returns:
      the IdStrategy that should be used for turning GroupDetails.getName() into an ID.
      Since:
      1.566
    • createCliAuthenticator

      @Deprecated public CliAuthenticator createCliAuthenticator(CLICommand command)
      Deprecated.
      No longer used.
    • getDescriptor

      public Descriptor<SecurityRealm> getDescriptor()
      By default looks for a nested class (conventionally named DescriptorImpl) implementing Descriptor and marked with Extension.

      Gets the descriptor for this instance.

      Descriptor is a singleton for every concrete Describable implementation, so if a.getClass() == b.getClass() then by default a.getDescriptor() == b.getDescriptor() as well. (In rare cases a single implementation class may be used for instances with distinct descriptors.)

      SecurityRealm is a singleton resource in Hudson, and therefore it's always configured through config.jelly and never with global.jelly.

      Specified by:
      getDescriptor in interface Describable<SecurityRealm>
      Overrides:
      getDescriptor in class AbstractDescribableImpl<SecurityRealm>
    • getAuthenticationGatewayUrl

      public String getAuthenticationGatewayUrl()
      Returns the URL to submit a form for the authentication. There's no need to override this, except for LegacySecurityRealm.
      See Also:
    • getLoginUrl

      public String getLoginUrl()
      Gets the target URL of the "login" link. There's no need to override this, except for LegacySecurityRealm. On legacy implementation this should point to loginEntry, which is protected by web.xml, so that the user can be eventually authenticated by the container.

      Path is relative from the context root of the Hudson application. The URL returned by this method will get the "from" query parameter indicating the page that the user was at.

    • canLogOut

      public boolean canLogOut()
      Returns true if this SecurityRealm supports explicit logout operation.

      If the method returns false, "logout" link will not be displayed. This is useful when authentication doesn't require an explicit login activity (such as NTLM authentication or Kerberos authentication, where Hudson has no ability to log off the current user.)

      By default, this method returns true.

      Since:
      1.307
    • getPostLogOutUrl2

      protected String getPostLogOutUrl2(org.kohsuke.stapler.StaplerRequest2 req, org.springframework.security.core.Authentication auth)
      Controls where the user is sent to after a logout. By default, it's the top page of Hudson, but you can return arbitrary URL.
      Parameters:
      req - StaplerRequest2 that represents the current request. Primarily so that you can get the context path. By the time this method is called, the session is already invalidated. Never null.
      auth - The Authentication object that represents the user that was logging in. This parameter allows you to redirect people to different pages depending on who they are.
      Returns:
      never null.
      Since:
      2.475
      See Also:
    • getPostLogOutUrl2

      @Deprecated protected String getPostLogOutUrl2(org.kohsuke.stapler.StaplerRequest req, org.springframework.security.core.Authentication auth)
      Since:
      2.266
    • getPostLogOutUrl

      @Deprecated protected String getPostLogOutUrl(org.kohsuke.stapler.StaplerRequest req, Authentication auth)
      Since:
      1.314
    • getCaptchaSupport

      public CaptchaSupport getCaptchaSupport()
    • setCaptchaSupport

      public void setCaptchaSupport(CaptchaSupport captchaSupport)
    • getCaptchaSupportDescriptors

      public List<Descriptor<CaptchaSupport>> getCaptchaSupportDescriptors()
    • doLogout

      public void doLogout(org.kohsuke.stapler.StaplerRequest2 req, org.kohsuke.stapler.StaplerResponse2 rsp) throws IOException, jakarta.servlet.ServletException
      Handles the logout processing.

      The default implementation erases the session and do a few other clean up, then redirect the user to the URL specified by getPostLogOutUrl2(StaplerRequest2, Authentication).

      Throws:
      IOException
      jakarta.servlet.ServletException
      Since:
      2.475
    • doLogout

      @Deprecated @StaplerNotDispatchable public void doLogout(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      Throws:
      IOException
      javax.servlet.ServletException
      Since:
      1.314
    • allowsSignup

      public boolean allowsSignup()
      Returns true if this SecurityRealm allows online sign-up. This creates a hyperlink that redirects users to CONTEXT_ROOT/signUp, which will be served by the signup.jelly view of this class.

      If the implementation needs to redirect the user to a different URL for signing up, use the following jelly script as signup.jelly

      <xmp>
       <st:redirect url="http://www.sun.com/" xmlns:st="jelly:stapler"/>
       </xmp>
    • loadUserByUsername2

      public org.springframework.security.core.userdetails.UserDetails loadUserByUsername2(String username) throws org.springframework.security.core.userdetails.UsernameNotFoundException
      Shortcut for UserDetailsService.loadUserByUsername(String).
      Returns:
      never null.
      Throws:
      UserMayOrMayNotExistException2 - If the security realm cannot even tell if the user exists or not.
      org.springframework.security.core.userdetails.UsernameNotFoundException
      Since:
      2.266
    • loadUserByUsername

      @Deprecated public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException
      Throws:
      UsernameNotFoundException
      DataAccessException
    • loadGroupByGroupname2

      public GroupDetails loadGroupByGroupname2(String groupname, boolean fetchMembers) throws org.springframework.security.core.userdetails.UsernameNotFoundException
      If this SecurityRealm supports a look up of GroupDetails by their names, override this method to provide the look up.

      This information, when available, can be used by AuthorizationStrategys to improve the UI and error diagnostics for the user.

      Parameters:
      groupname - the name of the group to fetch
      fetchMembers - if true then try and fetch the members of the group if it exists. Trying does not imply that the members will be fetched and GroupDetails.getMembers() may still return null
      Throws:
      UserMayOrMayNotExistException2 - if no conclusive result could be determined regarding the group existence.
      org.springframework.security.core.userdetails.UsernameNotFoundException - if the group does not exist.
      Since:
      2.266
    • loadGroupByGroupname

      @Deprecated public GroupDetails loadGroupByGroupname(String groupname) throws UsernameNotFoundException, DataAccessException
      Throws:
      UsernameNotFoundException
      DataAccessException
    • loadGroupByGroupname

      @Deprecated public GroupDetails loadGroupByGroupname(String groupname, boolean fetchMembers) throws UsernameNotFoundException, DataAccessException
      Throws:
      UsernameNotFoundException
      DataAccessException
      Since:
      1.549
    • commenceSignup

      public org.kohsuke.stapler.HttpResponse commenceSignup(FederatedLoginService.FederatedIdentity identity)
      Starts the user registration process for a new user that has the given verified identity.

      If the user logs in through a FederatedLoginService, verified that the current user owns an identity, but no existing user account has claimed that identity, then this method is invoked.

      The expected behaviour is to confirm that the user would like to create a new account, and associate this federated identity to the newly created account (via FederatedLoginService.FederatedIdentity.addToCurrentUser().

      Throws:
      UnsupportedOperationException - If this implementation doesn't support the signup through this mechanism. This is the default implementation.
      Since:
      1.394
    • doCaptcha

      public final void doCaptcha(org.kohsuke.stapler.StaplerRequest2 req, org.kohsuke.stapler.StaplerResponse2 rsp) throws IOException
      Generates a captcha image.
      Throws:
      IOException
    • validateCaptcha

      protected final boolean validateCaptcha(String text)
      Validates the captcha.
    • getSecurityComponents

      public SecurityRealm.SecurityComponents getSecurityComponents()
      Use this function to get the security components, without necessarily recreating them.
    • createFilter

      public jakarta.servlet.Filter createFilter(jakarta.servlet.FilterConfig filterConfig)
      Creates Filter that all the incoming HTTP requests will go through for authentication.

      The default implementation uses getSecurityComponents() and builds a standard filter chain. But subclasses can override this to completely change the filter sequence.

      For other plugins that want to contribute Filter, see PluginServletFilter.

      Since:
      2.475
    • createFilter

      @Deprecated public javax.servlet.Filter createFilter(javax.servlet.FilterConfig filterConfig)
      Since:
      1.271
    • commonFilters

      protected final List<jakarta.servlet.Filter> commonFilters()
    • getFrom

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public static String getFrom()
      Perform a calculation where we should go back after successful login
      Returns:
      Encoded URI where we should go back after successful login or "/" if no way back or an issue occurred
      Since:
      2.4
    • all

      Returns all the registered SecurityRealm descriptors.