java.lang.Object
org.apache.shiro.realm.CachingRealm
org.apache.shiro.realm.AuthenticatingRealm
de.businesscode.bcdui.subjectsettings.oauth2.OAuthRealm
All Implemented Interfaces:
org.apache.shiro.authc.LogoutAware, org.apache.shiro.cache.CacheManagerAware, org.apache.shiro.lang.util.Initializable, org.apache.shiro.lang.util.Nameable, org.apache.shiro.realm.Realm

public class OAuthRealm extends org.apache.shiro.realm.AuthenticatingRealm
This Realm will accept logins from trusted oAuth authentication servers Per default we also require the user to be found in bcd_sec_user to not lose control, as bcdAuthc resources only need a session and no permissions! For permissions, which are added in BCD-UI JdbcRealm, entries in bcd_sec_user_settings are anyway necessary This one is an authenticating realm only as such we obtain identity from resource server and let other realms obtain authorization data from elsewhere
  • Field Details

  • Constructor Details

    • OAuthRealm

      public OAuthRealm()
  • Method Details

    • setDisableSslValidation

      public void setDisableSslValidation(boolean disableSslValidation)
    • setAuthenticator

      public void setAuthenticator(OAuthAuthenticatingFilter authenticator)
      Set in shiro.ini We need to set the instance of filter class to determine in realm if that should support processing, in case we have many realms bound with multiple authenticators for given token
      Parameters:
      authenticator -
    • getAuthenticator

      public OAuthAuthenticatingFilter getAuthenticator()
    • setTokenEndpoint

      public void setTokenEndpoint(String tokenEndpoint)
      Set in shiro.ini sets the endpoint to /token API
      Parameters:
      tokenEndpoint -
    • getTokenEndpoint

      public String getTokenEndpoint()
    • setUserInfoEndpoint

      public void setUserInfoEndpoint(String apiEndPoint)
      Set in shiro.ini the API endpoint to obtain information about user basically providing JSON data containing getPrincipalPropertyName() to extract
      Parameters:
      apiEndPoint - The endpoint to get principal's JSON
    • getUserInfoEndpoint

      public String getUserInfoEndpoint()
    • setClientSecret

      public void setClientSecret(String clientSecret)
      Set in shiro.ini secret we need to obtain access token from /token endpoint, used in callTokenEndpoint(OAuthToken, String)
      Parameters:
      clientSecret -
    • setPrincipalPropertyName

      public void setPrincipalPropertyName(String principalPropertyName)
      Overwrite default in shiro.ini this is the property we extract from JSON response and use as a principal
      Parameters:
      principalPropertyName -
    • getPrincipalPropertyName

      public String getPrincipalPropertyName()
    • setFullNamePropertyName

      public void setFullNamePropertyName(String principalNameName)
      Overwrite default in shiro.ini this is the property we extract from JSON response and use as a full name "Jon Doe"
      Parameters:
      principalNameName -
    • getFullNamePropertyName

      public String getFullNamePropertyName()
    • setEmailPropertyName

      public void setEmailPropertyName(String emailPropertyName)
      Overwrite default in shiro.ini this is the property we extract from JSON response and use as email
      Parameters:
      emailPropertyName -
    • getEmailPropertyName

      public String getEmailPropertyName()
    • getSkipBcdSecUserTest

      public boolean getSkipBcdSecUserTest()
    • setSkipBcdSecUserTest

      public void setSkipBcdSecUserTest(boolean skipBcdSecUserTest)
    • supports

      public boolean supports(org.apache.shiro.authc.AuthenticationToken token)
      accepts OAuthToken and only from given authenticator, if provided
      Specified by:
      supports in interface org.apache.shiro.realm.Realm
      Overrides:
      supports in class org.apache.shiro.realm.AuthenticatingRealm
    • doGetAuthenticationInfo

      protected org.apache.shiro.authc.AuthenticationInfo doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken authToken)
      creates access token via callTokenEndpoint(OAuthToken, String) and passes to retrieveUserPrincipal(OAuthToken) then constructs SimpleAuthenticationInfo with returned principal if oauth AND bcd_sec_user exist: - local userId is being used - login_name is the same for local and oauth - fullName we use from oauth if configured (fullNamePropertyName is set), otherwise local - same for email. Whie standard bcd_sec_user does not local email, it may exists if getPrincipleInfo() is overwritten in a project
      Specified by:
      doGetAuthenticationInfo in class org.apache.shiro.realm.AuthenticatingRealm
    • getPrincipleInfo

      protected OAuthRealm.PrincipalInfo getPrincipleInfo(OAuthRealm.OAuthUserInfo ui) throws Exception
      Unless explicitly disabled, we do enforce existence of ui in bcd_sec_user here to avoid everybody getting a session who is known to the remote system but not ours Can also be used as an extension point for example test for an additional flag ncd bcd_sec_user etc by overwriting this class for an oAuth provider in shiro.ini
      Parameters:
      ui -
      Returns:
      null if no information in bcd_sec_user should be or can be found
      Throws:
      Exception
    • assurePrincipleIsAllowed

      protected boolean assurePrincipleIsAllowed(OAuthRealm.OAuthUserInfo providedPrincipal, OAuthRealm.PrincipalInfo localPi) throws Exception
      Unless explicitly disabled, we do enforce existence of principal in bcd_sec_user here to avoid everybody getting a session who is known to the remote system but not ours Can also be used as an extension point for example test for an additional flag ncd bcd_sec_user etc by overwriting this class for an oAuth provider in shiro.ini
      Parameters:
      localPi -
      Returns:
      Throws:
      Exception
    • retrieveUserPrincipal

      protected OAuthRealm.OAuthUserInfo retrieveUserPrincipal(OAuthToken oauthToken) throws Exception
      implements retrieving user principal from resource server First gets the id-token from the token endpoint and then either retrieves it from the token or does an extra call to the info endpoint, if that is configured, which allows extracting more info in case we are overwritten
      Parameters:
      oauthToken - - which is already obtained from authority server and ready to be used as a bearer
      Returns:
      user principal, OAuthUserInfo
      Throws:
      IOException
      Exception
    • getUserPrincipalFromIdToken

      protected OAuthRealm.OAuthUserInfo getUserPrincipalFromIdToken(String accessToken, String origNonce) throws Exception
      Default. Derive name of the principal from the ID token
      Parameters:
      accessToken -
      Returns:
      Throws:
      Exception
    • getUserPrincipalFromUserInfoEndpoint

      protected OAuthRealm.OAuthUserInfo getUserPrincipalFromUserInfoEndpoint(String accessToken) throws Exception
      Useful if overwriting this class to retrieve more properties of the principal than its unique name Derive name of the principal from an extra call to the user info endpoint like https://graph.microsoft.com/v1.0/me/ Make sure the token we received earlier is allowed to access it, i.e. requested scope for example includes https://graph.microsoft.com/user.read
      Parameters:
      accessToken -
      Returns:
      Throws:
      Exception
    • callTokenEndpoint

      protected String callTokenEndpoint(OAuthToken oauthToken, String tokenProperty) throws IOException
      call against oauth2.0 "/token" endpoint to obtain an access token
      Parameters:
      oauthToken -
      Returns:
      The access token
      Throws:
      IOException
    • readJsonProperty

      protected com.google.gson.JsonElement readJsonProperty(String jsonString, String propertyName, boolean isPropertyRequired)
      helper to access plain property of a json string, i.e. readJsonProperty('{ foo:"bar" }', "foo").getAsString() returns "bar"
      Parameters:
      jsonString -
      propertyName -
      isPropertyRequired -
      Returns:
      The property