deltaspike-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Shane Bryzak <sbry...@redhat.com>
Subject [DISCUSS] Identity API
Date Sun, 12 Feb 2012 22:33:18 GMT
I've created an umbrella issue to track the work we do on the security 
module [1], and the first task is to review and discuss the Identity 
API.  This API forms the core of the security module, and all other 
features build on top of it to implement a complete security framework.

The Identity interface represents an individual, current user of an 
application and its implementation must be session-scoped to provide 
security services for the entirety of a user's session.  I'm going to 
paste the (slightly modified) code from Seam as it's mostly well 
documented, and so we have a baseline from which to further discuss:

public interface Identity {
public static final String RESPONSE_LOGIN_SUCCESS = "success";
public static final String RESPONSE_LOGIN_FAILED = "failed";
public static final String RESPONSE_LOGIN_EXCEPTION = "exception";
/**
* Simple check that returns true if the user is logged in, without 
attempting to authenticate
*
* @return true if the user is logged in
*/
@Secures
@LoggedIn
boolean isLoggedIn();
/**
* Returns true if the currently authenticated user has provided their 
correct credentials
* within the verification window configured by the application.
*
* @return
*/
boolean isVerified();
/**
* Will attempt to authenticate quietly if the user's credentials are set 
and they haven't
* authenticated already. A quiet authentication doesn't throw any 
exceptions if authentication
* fails.
*
* @return true if the user is logged in, false otherwise
*/
boolean tryLogin();
/**
* Returns the currently authenticated user
*
* @return
*/
User getUser();

/**
* Attempts to authenticate the user. This method raises the following 
events in response
* to whether authentication is successful or not. The following events 
may be raised
* during the call to login():
* <p/>
* org.apache.deltaspike.security.events.LoggedInEvent - raised when 
authentication is successful
* org.apache.deltaspike.security.events.LoginFailedEvent - raised when 
authentication fails
* org.apache.deltaspike.security.events.AlreadyLoggedInEvent - raised if 
the user is already authenticated
*
* @return String returns RESPONSE_LOGIN_SUCCESS if user is authenticated,
* RESPONSE_LOGIN_FAILED if authentication failed, or
* RESPONSE_LOGIN_EXCEPTION if an exception occurred during 
authentication. These response
* codes may be used to control user navigation. For deferred 
authentication methods, such as Open ID
* the login() method will return an immediate result of 
RESPONSE_LOGIN_FAILED (and subsequently fire
* a LoginFailedEvent) however in these conditions it is the 
responsibility of the Authenticator
* implementation to take over the authentication process, for example by 
redirecting the user to
* another authentication service.
*
*/
String login();
/**
* Attempts a quiet login, suppressing any login exceptions and not creating
* any faces messages. This method is intended to be used primarily as an
* internal API call, however has been made public for convenience.
*/
void quietLogin();
/**
* Logs out the currently authenticated user
*/
void logout();
/**
* Checks if the authenticated user is a member of the specified role.
*
* @param role String The name of the role to check * @param group String 
the name of the group in which the role exists
* @return boolean True if the user is a member of the specified role
*/
boolean hasRole(String role, String group);
/**
* Adds a role to the authenticated user. If the user is not logged in,
* the role will be added to a list of roles that will be granted to the
* user upon successful authentication, but only during the authentication
* process.
*
* @param role The name of the role to add * @param group The name of the 
group in which to create the role
*/
boolean addRole(String role, String group);
/**
* Checks if the authenticated user is a member of the specified group
*
* @param name The name of the group
* @return true if the user is a member of the group
*/
boolean inGroup(String name);
/**
* Adds the user to the specified group. See hasRole() for semantics in
* relationship to the authenticated status of the user.
*
* @param name The name of the group
* @return true if the group was successfully added
*/
boolean addGroup(String name);
/**
* Removes the currently authenticated user from the specified group
*
* @param name The name of the group
*/
void removeGroup(String name);
/**
* Removes a role from the authenticated user
*
* @param role The name of the role to remove
*/
void removeRole(String role, String group);
/**
* Checks that the current authenticated user is a member of
* the specified role.
*
* @param role String The name of the role to check
* @throws AuthorizationException if the authenticated user is not a 
member of the role
*/
void checkRole(String role, String group);
/**
* @param group
* @param groupType
*/
void checkGroup(String group);
     /**
* Returns an immutable set containing all the current user's granted roles
*
* @return
*/
Set<Role> getRoles();
/**
* Returns an immutable set containing all the current user's group 
memberships
*
* @return
*/
Set<Group> getGroups();
}


Some particular points to review:

1. Should we attempt to use the security classes provided by Java SE, 
such as Principal, Subject, etc or use our own User API - this will 
affect what is returned by the getUser() method above.  Keep in note 
that we will have at least a simple User/Role/Group API as part of 
Identity Management.  In Seam 2 we originally used the built-in Java 
classes (which made more sense because the authentication process was 
based on JAAS), however in Seam 3 (where we removed JAAS because it 
doesn't support asynchronous authentication as required by OpenID etc) 
we based the security module on the PicketLink User API.  IMHO, this is 
not a critical choice either way - the Java security classes have the 
advantage of being familiar to many users, while on the flipside if we 
provide our own User API we have the flexibility of being able to extend 
it in the future.  So both options have their own advantages.

2. The addRole() and addGroup() methods are intended to be only used 
during the authentication process to grant particular user memberships 
for the duration of their session only.  A few users have found this a 
little confusing, as they were using identity management, and expected 
these methods to grant a permanent membership for the user.  One 
solution may be to simply rename these methods to addSessionRole() and 
addSessionGroup() - thoughts?

3. We're touching a little bit on the authorization API here also with 
the hasRole() / inGroup() methods.  I'll provide a quick description of 
these core security API concepts here:

* User - represents an individual user of an application.  Can either be 
human or non-human, and can represent either a user managed locally 
(i.e. through the IDM API) or an externally authenticated User, such as 
one that has logged in with OpenID.
* Group - a collection of users and other groups.  The intent is that 
privileges can be either assigned to individual users, groups or roles.  
Groups have a hierarchical structure and can be a member of zero or more 
other groups.
* Role - represent a particular real life role of a user.  Roles are 
defined as a three-way relationship between user, group and role type.  
For example, user "Bob" might be an "accounts clerk" (the role type) at 
"head office" (the group).  It is also possible for a user to have a 
role in a group, without being a member of that group.



[1] https://issues.apache.org/jira/browse/DELTASPIKE-76
[2] 
https://github.com/seam/security/blob/develop/api/src/main/java/org/jboss/seam/security/Identity.java



Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message