IntroductionOne of the core functions that Nimble brings to any host application is authentication and identity services. Nimble utilizes the excellent Apache Shiro system for much of the authentication process. Apache Shiro is a powerful and flexible open-source security framework that cleanly handles authentication, authorization, enterprise session management and cryptography. The following image provided by the Shiro project describes the internal architecture of Shiro.In the case of Nimble we plugin to this framework at several points, most notably by providing authentication and identity realms for Local Accounts, Open ID, Facebook, LDAP and SAML 2. Of course once a user has been able to authenticate via a trusted realm their identity must be made available to the host application. Each of the above realms ensure that the grails.plugins.nimble.UserBase (or its derivative) object is stored in the applications data repository and made available to the users http session. Important authentication and identity domain objectsgrails.plugins.nimble.UserBaseThis is the main source of identity provided by Nimble. The User object itself is deliberately minimalist. Host applications are provided a clean User object which extends this class. You may add any additional data that is appropriate for your host application. It is important to note that the User object may belong to many Roles or Groups and directly assigned permissions as described in the overview of access control in Nimble. From an identity point of view the User object stores a unique but mutable identifier for the user in the username field. This identifier must be unique across all realms, for this reason OpenID and Facebook realms use URI's to identify the user. Care must be taken to ensure there is no clash if both LDAP and Local account realms are utilized as both of these realms generally utilize a faily non-unique format of usernames e.g. 'beddoes' to make it easy for end users to remember. It should be noted that host applications MUST NOT use the username field to identify users. Developers should always reference User objects by the internally assigned id for the User. By doing this users can change their username (for marriages/divorces etc) with ease or even move from a local authentication to externally provided authentication e.g. OpenID. The User object also provides useful information such session activation history. Host applications are provided a clean object when executing the jack-be-nimble script which extends this class. You may add any additional data that is appropriate for your host application. grails.plugins.nimble.ProfileBaseThe profile class provides a range of information about a particular user that is useful in general purpose web situations such as their name, nick name, email address, bio, avatar and so on. Host applications are provided a clean object when executing the jack-be-nimble script which extends this class. You may add any additional data that is appropriate for your host application. The authentication processWhen a request for secured content is made and the user has not previously authenticated the request is redirected to the login action of the AuthController. This action will preserve the URL the user was attempting to access and render the template located at '/templates/nimble/login/login' in the host application. By default this supports local authentication, OpenID and Facebook but implementors may choose to make it represent anything they like. This template will automatically remove functionality as you disable options in config, for example if you disable Facebook Realm that login option will disappear from the default template. To login the user selects a method and provides the appropriate details. Each form will submit to an action in the AuthController that is appropriate for the type of details provided. By default:
Each of these actions may undertake some form of initial processing before creating the token type associated with their authentication realm and forwarding the login request to that realm for verification. If the realm indicates the login was a success (no exceptions are thrown) the user is redirected to the content they were originally attempting to access. Obtaining the logged in userAll realms in Nimble on successful login must publish the active users ID into the http session. For controllers and services Nimble injects authenticatedUser. You can simply refer to this object in your logic. If there is not currently a valid session this object will be null. To access the current user from a elsewhere simply do the following: Don't expect to have the same injected authenticatedUser INSTANCE available between actions/requests. Each request will make available a new instance of authenticatedUser for your use (when called). Should you wish to refer to users across requests store a reference to the id attribute of the User object in use in your application. Logging OutTo logout the user should be redirect to the logout action of AuthController this will terminate their session securely and redirect them to the default page of the application (which if requiring authentication will direct them to login again :) ). |
