User: starksm
Date: 01/05/11 12:06:26
Modified: tomcat/src/main/org/jboss/tomcat/security JbossRealm.java
Added: tomcat/src/main/org/jboss/tomcat/security
HypothermicRealm.java JBossSecurityMgrRealm.java
Log:
Updated the tomcat 3.2.1 integration mbean to use the new AbstractWebContainer
mbean and added support for integrated security across web/ejb applications.
Revision Changes Path
1.4 +9 -6
contrib/tomcat/src/main/org/jboss/tomcat/security/JbossRealm.java
Index: JbossRealm.java
===================================================================
RCS file:
/cvsroot/jboss/contrib/tomcat/src/main/org/jboss/tomcat/security/JbossRealm.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- JbossRealm.java 2001/02/24 21:21:08 1.3
+++ JbossRealm.java 2001/05/11 19:06:26 1.4
@@ -12,14 +12,17 @@
import org.jboss.security.SimplePrincipal;
/**
- * This maps Tomcat credintials to jBoss credintials. It can probably be placed
after
- * many other Tomcat realms to map that realm into jBoss.
- * @author <a href="mailto:[EMAIL PROTECTED]">Kevin Lewis</a>
- * @version $Revision: 1.3 $
+ * This maps Tomcat credintials to jBoss credintials. It does not actually
+ * do authenticatation so it needs to be placed after any other realms that
+ * perform authentication so that the credentials can be propagated to JBoss.
+ * If you want a realm that uses the JBoss security layer for authentication
+ * then use the {@link org.jboss.tomcat.security.JBossSecurityMgrRealm
JBossSecurityMgrRealm}
+ * interceptor.
*
- * changed imports to reflect new org.jboss.security structure
+ * @author <a href="mailto:[EMAIL PROTECTED]">Kevin Lewis</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Dewayne McNair</a>
- * @version $Revision: 1.3 $
+ * @author [EMAIL PROTECTED]
+ * @version $Revision: 1.4 $
*
*/
public class JbossRealm extends BaseInterceptor {
1.1
contrib/tomcat/src/main/org/jboss/tomcat/security/HypothermicRealm.java
Index: HypothermicRealm.java
===================================================================
package com.hypothermic.security;
import org.apache.tomcat.core.Request;
import org.apache.tomcat.core.Response;
import org.apache.tomcat.core.Context;
import org.apache.tomcat.util.SecurityTools;
import org.apache.tomcat.core.BaseInterceptor;
import org.jboss.security.SecurityAssociation;
import org.jboss.security.SimplePrincipal;
// This is the location in 2.2
// import org.jboss.security.auth.UsernamePasswordHandler;
// This is the location in 2.3+
import org.jboss.security.auth.callback.UsernamePasswordHandler;
import javax.servlet.http.HttpSession;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
import java.util.Hashtable;
/** An alternate example of integrating with the JBoss JAAS based security manager.
* Integrates Tomcat and Jboss security by redirecting Tomcat authentication and
authorization
* calls to the JBoss JAAS code.
* @author Dain Sundstrom
* @version $Revision: 1.1 $
*/
public class HypothermicRealm extends BaseInterceptor {
private String subjectKey = "j_subject";
private String loginContextName = "other";
private boolean credentialsFromRequest = true;
private boolean allowAnonymousLogin = true;
private String anonymousUsername = "anonymous";
private String anonymousPassword = "anonymous";
/**
* The key that is used to store the Subject in the session attributes.
* @param subjectKey the key
*/
public void setSubjectKey(String subjectKey) {
this.subjectKey = subjectKey;
}
/**
* The name used by JAAS during Login for determining spi
* @param loginContextName the name
*/
public void setLoginContextName(String loginContextName) {
this.loginContextName = loginContextName;
}
/**
* Should the request be checked for credentials.
*/
public void setCredentialsFromRequest(String credentialsFromRequest) {
this.credentialsFromRequest =
Boolean.valueOf(credentialsFromRequest).booleanValue();
}
/**
* Should all request be logged in anonymously
*/
public void setAllowAnonymousLogin(String allowAnonymousLogin) {
this.allowAnonymousLogin =
Boolean.valueOf(allowAnonymousLogin).booleanValue();
}
/**
* The username to use during anonymous login.
*/
public void setAnonymousUsername(String anonymousUsername) {
this.anonymousUsername = anonymousUsername;
}
/**
* The password to use during anonymous login.
*/
public void setAnonymousPassword(String anonymousPassword) {
this.anonymousPassword = anonymousPassword;
}
/**
* Authenticates user uning the JBoss JAAS code.
* @param request the request
* @param response the response
*/
public int authenticate(Request request, Response response){
HttpSession session = request.getSession(true);
session.removeAttribute(subjectKey);
// get the username and password
Hashtable credentials = getCredentials(request);
String username = (String)credentials.get("username");
String password = (String)credentials.get("password");
if(username != null && password != null) {
try {
// attempt to login via JAAS
CallbackHandler handler = new
UsernamePasswordHandler(username, password.toCharArray());
LoginContext loginContext = new
LoginContext(loginContextName, handler);
loginContext.login();
Subject subject = loginContext.getSubject();
if(subject != null) {
// we are logged in
// save the subject in the session
session.setAttribute(subjectKey, subject);
// set the remote user
request.setRemoteUser(username);
// set the auth method to way every was
expected in the context...
Context ctx = request.getContext();
if (ctx != null) {
request.setAuthType(ctx.getAuthMethod());
}
// Set the security association in JBoss
SecurityAssociation.setPrincipal( new
SimplePrincipal( username ) );
SecurityAssociation.setCredential(
password.toCharArray() );
}
} catch(LoginException e) {
// Login Failed
e.printStackTrace();
}
}
return 0;
}
/**
* Determines if the user is a member of the requested roles. This
authorization if
* checked with the JBoss JAAS code.
* @param request the request
* @param response the response
* @param roles the roles of which the user must belong.
*/
public int authorize( Request request, Response response, String roles[] ) {
// if we are not authenticated, there is nothing to do.
String user = request.getRemoteUser();
if(user==null) {
return 401;
}
// if no roles are needed we are done
if(roles==null || roles.length==0) {
return 0;
}
// Get the Subject that was set during authentication.
HttpSession session = request.getSession(true);
Subject subject = (Subject)session.getAttribute(subjectKey);
if(subject == null) {
return 401;
}
// Get the roles to which this subject belongs.
String userRoles[] = getRoles(subject);
// Set the roles in the request.
request.setUserRoles(userRoles);
// Does this user belong to the proper roles?
if(SecurityTools.haveRole(userRoles, roles)) {
return 0;
}
// too bad not authorized
return 401;
}
/**
* Attempt to retrieve the user's credentials from the usual Tomcat
* locations, and if that fails, attempt to get them directly from the request.
* @param request the request
*/
protected Hashtable getCredentials(Request request) {
Hashtable credentials;
credentials = getCredentialsFromTomcat(request);
if(credentials != null) {
return credentials;
}
credentials = getCredentialsFromRequest(request);
if(credentials != null) {
return credentials;
}
credentials = getAnonymousCredentials();
if(credentials != null) {
return credentials;
}
// too bad, return a valid hashtable with no entries
return new Hashtable();
}
protected Hashtable getCredentialsFromTomcat(Request request) {
Hashtable credentials = new Hashtable();
SecurityTools.credentials(request, credentials);
String username = (String)credentials.get("username");
String password = (String)credentials.get("password");
if(username != null && password != null) {
System.out.println("Cool Got Credentials From Tomcat");
return credentials;
}
return null;
}
protected Hashtable getCredentialsFromRequest(Request request) {
if(credentialsFromRequest) {
String username = request.getParameter("j_username");
String password = request.getParameter("j_password");
if(username != null && password != null) {
Hashtable credentials = new Hashtable();
credentials.put("username", username);
credentials.put("password", password);
HttpSession session = request.getSession(true);
session.setAttribute( "j_username", username);
session.setAttribute( "j_password", password);
System.out.println("Cool Got Credentials From
Request");
return credentials;
}
}
return null;
}
protected Hashtable getAnonymousCredentials() {
if(allowAnonymousLogin) {
if(anonymousUsername != null && anonymousPassword != null) {
Hashtable credentials = new Hashtable();
credentials.put("username", anonymousUsername);
credentials.put("password", anonymousPassword);
System.out.println("Cool Got Anonymous Credentials");
return credentials;
}
}
return null;
}
/**
* Get the names of every role of which the subject is a member.
* @param subject the subect
*/
protected String[] getRoles(Subject subject) {
Set groups = subject.getPrincipals(Group.class);
Iterator iterator = groups.iterator();
while(iterator.hasNext()) {
Group group = (Group) iterator.next();
if("Roles".equals(group.getName())) {
return getRoles(group);
}
}
return new String[0];
}
/**
* Get the names of every group of which the group is a member.
* @param group the group
*/
protected String[] getRoles(Group group) {
Set roleSet = new HashSet();
getRoles(group, roleSet);
// convert Set to String[];
String[] roles = new String[roleSet.size()];
roles = (String[])roleSet.toArray(roles);
return roles;
}
/**
* Adds the names of every group of which the group is a member to the set.
* @param group the group
* @param roleSet the set of group names
*/
protected void getRoles(Group group, Set roleSet) {
Enumeration enum = group.members();
while(enum.hasMoreElements()) {
Principal principal = (Principal)enum.nextElement();
if(principal instanceof Group) {
getRoles((Group)principal, roleSet);
} else {
roleSet.add(principal.getName());
}
}
}
}
1.1
contrib/tomcat/src/main/org/jboss/tomcat/security/JBossSecurityMgrRealm.java
Index: JBossSecurityMgrRealm.java
===================================================================
package org.jboss.tomcat.security;
import java.security.Principal;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.HashSet;
import java.util.Set;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.security.auth.Subject;
import org.apache.log4j.Category;
import org.apache.tomcat.core.BaseInterceptor;
import org.apache.tomcat.core.Context;
import org.apache.tomcat.core.Request;
import org.apache.tomcat.core.Response;
import org.apache.tomcat.util.SecurityTools;
import org.jboss.security.EJBSecurityManager;
import org.jboss.security.RealmMapping;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.SecurityAssociation;
import org.jboss.security.SubjectSecurityManager;
/** This is a request interceptor for authentication/authorization of users
that uses the JBossSX security framework. It relieas on the JNDI ENC
namespace setup by the AbstractWebContainer. In particular, it uses the
java:comp/env/security subcontext to access the security manager interfaces
for authorization and authenticaton.
@see org.jboss.web.AbstractWebContainer
@see org.jboss.security.EJBSecurityManager
@see org.jboss.security.RealmMapping
@see org.jboss.security.SimplePrincipal
@see org.jboss.security.SecurityAssociation
@see org.jboss.security.SubjectSecurityManager
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class JBossSecurityMgrRealm extends BaseInterceptor
{
static Category category =
Category.getInstance(JBossSecurityMgrRealm.class.getName());
public String subjectAttributeName = "j_subject";
public boolean useJAAS = false;
/** A flag to indicate if the security manager implements the
SubjectSecurityManager
rather than EJBSecurityManager. When true, the authenticated Subject is obtained
from the SubjectSecurityManager and placed into the request under the
subjectAttributeName attribute.
*/
public void setUseJAAS(boolean useJAAS)
{
this.useJAAS = useJAAS;
}
/** The name of the request attribute under with the authenticated JAAS
Subject is stored on successful authentication.
*/
public void setSubjectAttributeName(String subjectAttributeName)
{
this.subjectAttributeName = subjectAttributeName;
}
public int authenticate(Request request, Response response)
{
/* Get the username credentials from the request. We dont check
that they are null as the security domain may consider this
a valid indication of an unauthenticated user requesting
anonymous access.
*/
Hashtable credentialMap = new Hashtable();
SecurityTools.credentials(request, credentialMap);
String username = (String) credentialMap.get("username");
String password = (String) credentialMap.get("password");
/* Make sure the thread context class loader it set ot the servlet
class loader. The Jdk12Interceptor should be handling this but
it does not do it for the authenticate/authorize phases of a
request.
*/
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ClassLoader scl = request.getContext().getServletLoader().getClassLoader();
if( category.isDebugEnabled() )
{
category.debug("Authenticating access, username: " + username + " "
+request);
category.debug("ClassLoader: "+cl.toString()+':'+cl.hashCode());
category.debug("Servlet ClassLoader: "+scl.toString()+':'+cl.hashCode());
}
try
{
if( scl != cl )
Thread.currentThread().setContextClassLoader(scl);
// Get the JBoss security manager from the ENC context
InitialContext iniCtx = new InitialContext();
EJBSecurityManager securityMgr = (EJBSecurityManager)
iniCtx.lookup("java:comp/env/security/securityMgr");
SimplePrincipal principal = new SimplePrincipal(username);
if( securityMgr.isValid(principal, password) )
{
request.setRemoteUser(username);
Context ctx = request.getContext();
if (ctx != null)
request.setAuthType(ctx.getAuthMethod());
category.debug("User: "+username+" is authenticated");
SecurityAssociation.setPrincipal(principal);
SecurityAssociation.setCredential(password.toCharArray());
if( useJAAS == true && securityMgr instanceof SubjectSecurityManager
)
{
SubjectSecurityManager subjectMgr = (SubjectSecurityManager)
securityMgr;
Subject subject = subjectMgr.getActiveSubject();
request.setAttribute(subjectAttributeName, subject);
}
}
else
{
category.debug("User: "+username+" is NOT authenticated");
}
}
catch(NamingException e)
{
category.error("Error during authenticate", e);
}
finally
{
if( scl != cl )
Thread.currentThread().setContextClassLoader(cl);
}
return 0;
}
public int authorize(Request request, Response response, String roles[])
{
if( roles==null || roles.length==0 )
{
// request doesn't need authentication
return 0;
}
String username = request.getRemoteUser();
if( username == null )
return 401;
/* Make sure the thread context class loader it set ot the servlet
class loader. The Jdk12Interceptor should be handling this but
it does not do it for the authenticate/authorize phases of a
request.
*/
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ClassLoader scl = request.getContext().getServletLoader().getClassLoader();
if( category.isDebugEnabled() )
{
category.debug("Authorizing access, username: " + username + " "
+request);
category.debug("ClassLoader: "+cl.toString()+':'+cl.hashCode());
category.debug("Servlet ClassLoader: "+scl.toString()+':'+cl.hashCode());
}
int code = 0;
try
{
if( scl != cl )
Thread.currentThread().setContextClassLoader(scl);
// Get the JBoss security manager from the ENC context
InitialContext iniCtx = new InitialContext();
RealmMapping securityMgr = (RealmMapping)
iniCtx.lookup("java:comp/env/security/realmMapping");
SimplePrincipal principal = new SimplePrincipal(username);
Set requiredRoles = new HashSet(Arrays.asList(roles));
if( securityMgr.doesUserHaveRole(principal, requiredRoles) )
{
// Need to get roles from the security mgr. Needs updated
interface...
String userRoles[] = {};
request.setUserRoles( userRoles );
category.debug("User: "+username+" is authorized");
}
else
{
category.debug("User: "+username+" is not authorized");
code = 401;
}
}
catch(NamingException e)
{
category.error("Error during authorize", e);
code = 401;
}
finally
{
if( scl != cl )
Thread.currentThread().setContextClassLoader(cl);
}
return code;
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development