All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.picketbox.plugins.PicketBoxProcessor Maven / Gradle / Ivy

Go to download

PicketBox is a cross cutting project that handles security for Java projects.

There is a newer version: 5.1.0.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors. 
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.picketbox.plugins;

import java.security.Principal;
import java.security.PrivilegedActionException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.security.auth.Subject;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginException;

import org.jboss.security.AuthenticationManager;
import org.jboss.security.AuthorizationManager;
import org.jboss.security.PicketBoxMessages;
import org.jboss.security.SecurityConstants;
import org.jboss.security.SecurityContext;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.annotation.Authentication;
import org.jboss.security.annotation.Authorization;
import org.jboss.security.annotation.Module;
import org.jboss.security.annotation.ModuleOption;
import org.jboss.security.annotation.ModuleOption.VALUE_TYPE;
import org.jboss.security.annotation.SecurityAudit;
import org.jboss.security.annotation.SecurityConfig;
import org.jboss.security.annotation.SecurityDomain;
import org.jboss.security.annotation.SecurityMapping;
import org.jboss.security.audit.config.AuditProviderEntry;
import org.jboss.security.auth.login.AuthenticationInfo;
import org.jboss.security.authorization.AuthorizationContext;
import org.jboss.security.authorization.AuthorizationException;
import org.jboss.security.authorization.config.AuthorizationModuleEntry;
import org.jboss.security.callbacks.SecurityContextCallbackHandler;
import org.jboss.security.config.ApplicationPolicy;
import org.jboss.security.config.ApplicationPolicyRegistration;
import org.jboss.security.config.AuditInfo;
import org.jboss.security.config.AuthorizationInfo;
import org.jboss.security.config.ControlFlag;
import org.jboss.security.config.MappingInfo;
import org.jboss.security.identity.RoleGroup;
import org.jboss.security.mapping.config.MappingModuleEntry;
import org.picketbox.config.PicketBoxConfiguration;
import org.picketbox.core.authorization.resources.POJOResource;
import org.picketbox.exceptions.PicketBoxProcessingException;
import org.picketbox.factories.SecurityFactory;

/**
 * 

Process the security annotations on a POJO.

*

* Additionally, there are various useful methods such as {@code #getCallerPrincipal()} to * get the authenticated principal, {@code #getCallerSubject()} to get the authenticated * subject and {@code #getCallerRoles()} to get the roles for the authenticated subject. *

* @since Feb 16, 2010 */ public class PicketBoxProcessor { private Principal principal = null; private Object credential = null; public PicketBoxProcessor() { } /** *

* Set the user name/ Credential *

* *

* In the case of X509 certificates, they can be passed * as the Credential into this method. *

* * @param userName * @param credential */ public void setSecurityInfo(String userName, Object credential) { this.principal = new SimplePrincipal(userName); this.credential = credential; } /** * Get the authenticated principal * @return * @throws PicketBoxProcessingException */ public Principal getCallerPrincipal() throws PicketBoxProcessingException { Principal principal = null; SecurityContext securityContext = null; try { securityContext = SecurityActions.getSecurityContext(); } catch (PrivilegedActionException pae) { throw new PicketBoxProcessingException(pae.getCause()); } if(securityContext != null) principal = securityContext.getUtil().getUserPrincipal(); return principal; } /** * Get the caller roles * @return * @throws PicketBoxProcessingException */ public RoleGroup getCallerRoles() throws PicketBoxProcessingException { RoleGroup roleGroup = null; SecurityContext securityContext = null; try { securityContext = SecurityActions.getSecurityContext(); } catch (PrivilegedActionException pae) { throw new PicketBoxProcessingException(pae.getCause()); } if(securityContext != null) roleGroup = securityContext.getUtil().getRoles(); return roleGroup; } /** * Get the caller subject * @return * @throws PicketBoxProcessingException */ public Subject getCallerSubject() throws PicketBoxProcessingException { Subject subject = new Subject(); SecurityContext securityContext = null; try { securityContext = SecurityActions.getSecurityContext(); } catch (PrivilegedActionException pae) { throw new PicketBoxProcessingException(pae.getCause()); } if(securityContext != null) subject = securityContext.getUtil().getSubject(); return subject; } /** * Process the POJO for security annotations * @param pojo * @throws PicketBoxProcessingException * @throws LoginException */ public void process(Object pojo) throws LoginException, PicketBoxProcessingException { String securityDomain = SecurityConstants.DEFAULT_APPLICATION_POLICY; Class objectClass = pojo.getClass(); SecurityDomain securityDomainAnnotation = objectClass.getAnnotation(SecurityDomain.class); if(securityDomainAnnotation != null) securityDomain = securityDomainAnnotation.value(); SecurityFactory.prepare(); try { boolean needAuthorization = false; SecurityConfig securityConfig = objectClass.getAnnotation(SecurityConfig.class); Authentication authenticationAnnotation = objectClass.getAnnotation(Authentication.class); if(securityConfig == null && authenticationAnnotation == null) throw PicketBoxMessages.MESSAGES.invalidSecurityAnnotationConfig(); if(securityConfig != null) { PicketBoxConfiguration idtrustConfig = new PicketBoxConfiguration(); idtrustConfig.load(securityConfig.fileName()); } else { ApplicationPolicyRegistration apr = (ApplicationPolicyRegistration) Configuration.getConfiguration(); ApplicationPolicy aPolicy = new ApplicationPolicy(securityDomain); AuthenticationInfo authenticationInfo = getAuthenticationInfo(authenticationAnnotation, securityDomain); aPolicy.setAuthenticationInfo(authenticationInfo ); Authorization authorizationAnnotation = objectClass.getAnnotation(Authorization.class); SecurityAudit auditAnnotation = objectClass.getAnnotation(SecurityAudit.class); SecurityMapping mappingAnnotation = objectClass.getAnnotation(SecurityMapping.class); if(authorizationAnnotation != null) { AuthorizationInfo authorizationInfo = getAuthorizationInfo(authorizationAnnotation, securityDomain); aPolicy.setAuthorizationInfo(authorizationInfo); needAuthorization = true; } if(auditAnnotation != null) { AuditInfo auditInfo = getAuditInfo(auditAnnotation, securityDomain); aPolicy.setAuditInfo(auditInfo); } if(mappingAnnotation != null) { MappingInfo mappingInfo = getMappingInfo(mappingAnnotation, securityDomain); List entries = mappingInfo.getModuleEntries(); for(MappingModuleEntry entry: entries) { aPolicy.setMappingInfo(entry.getMappingModuleType(), mappingInfo); } } apr.addApplicationPolicy(securityDomain, aPolicy); } SecurityContext securityContext = SecurityActions.createSecurityContext(securityDomain); SecurityActions.setSecurityContext(securityContext); AuthenticationManager authMgr = SecurityFactory.getAuthenticationManager(securityDomain); Subject subject = new Subject(); boolean valid = authMgr.isValid(principal, credential, subject); if(!valid) throw new LoginException(PicketBoxMessages.MESSAGES.authenticationFailedMessage()); SecurityActions.register(securityContext, principal, credential, subject); AuthorizationManager authzMgr = SecurityFactory.getAuthorizationManager(securityDomain); SecurityContextCallbackHandler cbh = new SecurityContextCallbackHandler(securityContext); //We try to get the roles of the current authenticated subject. This internally will also //apply the role mapping logic if it is configured at the security domain level RoleGroup roles = authzMgr.getSubjectRoles(subject, cbh); if(roles == null) throw new PicketBoxProcessingException(PicketBoxMessages.MESSAGES.nullRolesInSubjectMessage()); if(needAuthorization) { int permit = authzMgr.authorize(new POJOResource(pojo), subject, roles); if(permit != AuthorizationContext.PERMIT) throw new AuthorizationException(PicketBoxMessages.MESSAGES.authorizationFailedMessage()); } } catch(PrivilegedActionException pae) { throw new PicketBoxProcessingException(pae.getCause()); } catch (AuthorizationException e) { throw new PicketBoxProcessingException(e); } catch (Exception e) { throw new PicketBoxProcessingException(e); } finally { SecurityFactory.release(); } } private MappingInfo getMappingInfo(SecurityMapping mappingAnnotation, String securityDomain) { MappingInfo mappingInfo = new MappingInfo(securityDomain); Module[] modules = mappingAnnotation.modules(); if(modules != null) { for(Module module: modules) { String code = module.code().getCanonicalName(); String type = module.type(); Map map = new HashMap(); ModuleOption[] options = module.options(); if(options != null) { for(ModuleOption option : options) { String key = option.key(); String value = option.value(); VALUE_TYPE valueType = option.valueType(); if(key != null && key.length() > 0 && valueType == ModuleOption.VALUE_TYPE.JAVA_PROPERTIES) { StringTokenizer st = new StringTokenizer(value,"="); String prop1 = st.nextToken(); String prop2 = st.nextToken(); Properties properties = new Properties(); properties.put(prop1, prop2); map.put(key, properties); } else if(key != null && key.length() > 0) map.put(key, value); } } MappingModuleEntry entry = new MappingModuleEntry(code, map, type); mappingInfo.add(entry); } } return mappingInfo; } private AuditInfo getAuditInfo(SecurityAudit auditAnnotation, String securityDomain) { AuditInfo auditInfo = new AuditInfo(securityDomain); Module[] modules = auditAnnotation.modules(); if(modules != null) { for(Module module: modules) { String code = module.code().getCanonicalName(); Map map = new HashMap(); ModuleOption[] options = module.options(); if(options != null) { for(ModuleOption option : options) { String key = option.key(); String value = option.value(); if(key != null && key.length() > 0) map.put(key, value); } } AuditProviderEntry entry = new AuditProviderEntry(code, map); auditInfo.add(entry); } } return auditInfo; } private AuthorizationInfo getAuthorizationInfo(Authorization authorizationAnnotation, String securityDomain) { AuthorizationInfo authorizationInfo = new AuthorizationInfo(securityDomain); Module[] modules = authorizationAnnotation.modules(); if(modules != null) { for(Module module: modules) { String code = module.code().getCanonicalName(); String flag = module.flag(); Map map = new HashMap(); ModuleOption[] options = module.options(); if(options != null) { for(ModuleOption option : options) { String key = option.key(); String value = option.value(); if(key != null && key.length() > 0) map.put(key, value); } } AuthorizationModuleEntry entry = new AuthorizationModuleEntry(code, map); entry.setControlFlag(ControlFlag.valueOf(flag)); authorizationInfo.add(entry); } } return authorizationInfo; } private AuthenticationInfo getAuthenticationInfo(Authentication auth, String securityDomainName) { AuthenticationInfo authInfo = new AuthenticationInfo(securityDomainName); Module[] modules = auth.modules(); if(modules != null) { for(Module module: modules) { String code = module.code().getCanonicalName(); String flag = module.flag(); Map map = new HashMap(); ModuleOption[] options = module.options(); if(options != null) { for(ModuleOption option : options) { String key = option.key(); String value = option.value(); if(key != null && key.length() > 0) map.put(key, value); } } AppConfigurationEntry entry = new AppConfigurationEntry(code, getFlag(flag), map); authInfo.addAppConfigurationEntry(entry); } } return authInfo; } private AppConfigurationEntry.LoginModuleControlFlag getFlag(String flag) { if("REQUIRED".equalsIgnoreCase(flag)) return LoginModuleControlFlag.REQUIRED; if("REQUISITE".equalsIgnoreCase(flag)) return LoginModuleControlFlag.REQUISITE; if("SUFFICIENT".equalsIgnoreCase(flag)) return LoginModuleControlFlag.SUFFICIENT; return LoginModuleControlFlag.OPTIONAL; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy