OAM 및 SP에서 JIT 사용자정의 사용자 프로비전이 계속됨
이 문서에서는 OAM/SP에서 사용자 정의 사용자 프로비저닝 모듈을 빌드하는 방법을 보여줍니다. 본 과정은 이러한 모듈을 개발하는 방법을 설명하는 OAM Developer's Guide(16장)를 기반으로 합니다.
이 문서에서는 다음과 같은 방법에 중점을 둡니다.
-
플러그인 구현
-
컴파일
-
패키지화
-
OAM에 플러그인 업로드
-
새로 업로드된 플러그인을 사용하도록 OAM 구성
이 예제에서는 OAM Developer's Guide에 나열된 예제 코드를 사용합니다.
사용자정의 사용자 프로비저닝 모듈
사용자 프로비저닝 프레임워크에서는 프레임워크에 의해 정의된 인터페이스를 구현하는 사용자 정의 플러그인을 구현할 수 있습니다.
사용자 정의 사용자 프로비전 플러그인은 다음으로 구성됩니다.
-
사용자정의 사용자 프로비전 플러그인을 구현하는 하나 이상의 Java 클래스입니다. 클래스 중 하나는
oracle.security.fed.plugins.fed.provisioning.OIFUserProvisioningPlugin클래스를 확장합니다. -
Java 클래스를 설명하는
MANIFEST.MF파일입니다. -
플러그인을 설명하는 XML 파일입니다.
이러한 세 가지 요소는 JAR 파일에 번들로 제공되며 JAR 파일은 OAM 관리 콘솔을 통해 OAM 서버에 업로드됩니다. 업로드 및 활성화되면 OAM/SP에서 런타임에 사용할 수 있습니다.
Java 클래스
사용자 정의 사용자 프로비저닝 모듈을 구현하는 클래스는 다음을 준수해야 합니다.
-
oracle.security.fed.plugins.fed.provisioning.OIFUserProvisioningPlugin클래스를 확장합니다. -
public
ExecutionStatusprocess(UserContextcontext) throwsUserProvisioningException메소드를 구현합니다. -
이 메소드는 유저 레코드를 생성해야 할 때 호출됩니다.
-
상태(failure 또는 success)를 반환해야 합니다.
-
이 예에서는
UserContext에 포함된 사용자 데이터에 필요한 정보가 있는지 확인합니다. -
LDAP 서버에 대한 접속을 엽니다.
-
유저 레코드 생성
-
public String
getPluginName()은 사용자 정의 사용자 프로비전 모듈의 이름을 반환합니다. -
이 예에서는
CustomProvisioningPlugin를 반환합니다. -
public String
getDescription()은 사용자 정의 사용자 프로비전 모듈에 대한 설명을 반환합니다. -
이 예에서는
Custom Provisioning Plugin를 반환합니다. -
public Map
<String, MonitoringData> getMonitoringData()은 User Provisioning 흐름에서 사용되지 않습니다. -
이 예제에서는 null을 반환합니다.
-
공용 부울
getMonitoringStatus()은 사용자 프로비전 플로우에서 사용되지 않습니다. -
이 예제에서는 false를 반환합니다.
-
public int
getRevision()은 매니페스트 파일에 지정된 버전과 동일한 값이어야 합니다. -
이 예제에서는 10을 반환합니다.
-
public void
setMonitoringStatus(boolean status)는 사용자 프로비전 플로우에서 사용되지 않습니다. -
이 예에서는 이 메소드가 비어 있습니다.
-
클래스는
org.osgi.framework.BundleActivator인터페이스와 다음 메소드를 구현해야 합니다.-
public void start(BundleContext arg0)는 예외를 발생시킵니다.
-
이 예에서는 이 메소드가 비어 있습니다.
-
-
public void stop(BundleContext arg0)에서 예외가 발생합니다.
-
이 예에서는 이 메소드가 비어 있습니다.
-
선택적으로 플러그인이 플러그인 설정에서 구성 데이터를 읽어야 하는 경우
initialize()메소드를 구현할 수 있습니다. -
public ExecutionStatus 초기화(PluginConfig 구성)
-
예제에서 이 메소드는 플러그인 구성의 설정 항목에서 사용자 기본 DN을 읽습니다.
USER_BASE_DN
다음 코드는 CustomerUserProvisioning이라는 사용자 정의 플러그인의 예입니다.
package userprov;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.Context;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.InitialDirContext;
import oracle.security.am.plugin.ExecutionStatus;
import oracle.security.am.plugin.MonitoringData;
import oracle.security.am.plugin.PluginConfig;
import oracle.security.fed.plugins.fed.provisioning.OIFUserProvisioningPlugin;
import oracle.security.fed.plugins.fed.provisioning.UserContext;
import oracle.security.fed.plugins.fed.provisioning.UserProvisioningException;
public class CustomUserProvisioning extends OIFUserProvisioningPlugin implements
org.osgi.framework.BundleActivator
{
private String userBaseDN = null;
public ExecutionStatus initialize(PluginConfig config)
{
ExecutionStatus status = super.initialize(config);
if (status.getStatus() == ExecutionStatus.SUCCESS.getStatus())
userBaseDN = (String)config.getParameter("USER_BASE_DN");
return status;
}
public ExecutionStatus process(UserContext context) throws UserProvisioningException
{
try
{
// get user data
// after OIF/SP processing of the attributes sent by the IdP, we expect
// givenname, sn, mail as well as fed.nameidvalue which contains
// the userid
Map assertionAbributes = context.getAttributes();
Collection collection = (Collection)assertionAbributes.get("givenname");
String firstname = (String)(collection.size() > 0 ? collection.iterator().next() : null);
collection = (Collection)assertionAbributes.get("sn");
String lastname = (String)(collection.size() > 0 ? collection.iterator().next() : null);
collection = (Collection)assertionAbributes.get("mail");
String email = (String)(collection.size() > 0 ? collection.iterator().next() : null);
collection = (Collection)assertionAbributes.get("fed.nameidvalue"); String userid = (String)(collection.size() > 0 ?
collection.iterator().next() : null);
// check that the required attributes are present. If not, return an error
if (firstname == null || firstname.length() == 0 || lastname == null || lastname.length() == 0 || email == null || email.length() == 0 ||
userid == null || userid.length() == 0)
{
// failure
return ExecutionStatus.FAILURE;
}
String ldap = "ldap://adc00pcc.us.oracle.com:11389";
String username = "cn=orcladmin"; String password = "welcome1";
// connects to the LDAP directory
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldap);
if (ldap.toLowerCase().startsWith("ldaps"))
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.REFERRAL, "follow"); env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
InitialDirContext ldapContext = new
InitialDirContext(env);
// create the user entry
BasicAttributes attributes = new
BasicAttributes();
// object classes
BasicAttribute objClassAbr = new
BasicAttribute("objectClass");
objClassAbr.add("person");
objClassAbr.add("organizationalPerson");
objClassAbr.add("inetOrgPerson");
objClassAbr.add("top");
attributes.put(objClassAbr);
// uid abr
attributes.put(new BasicAttribute("uid", userid));
// first name
attributes.put(new BasicAttribute("givenname", firstname));
// last name
attributes.put(new BasicAttribute("sn", lastname));
// email
attributes.put(new BasicAttribute("mail", email));
// DN: cn will be set to userID
String dn = "cn=" + userid + (userBaseDN != null && userBaseDN.length() \> 0 ? "," + userBaseDN : "");
// create the user record
ldapContext.createSubcontext(dn, attributes);
// return success
return ExecutionStatus.SUCCESS;
}
catch (Exception ex)
{
ex.printStackTrace();
return ExecutionStatus.FAILURE;
}
}
public String getPluginName()
{
return "CustomProvisioningPlugin";
}
public String getDescription()
{
return "Custom Provisioning Plugin";
}
public Map<String, MonitoringData> getMonitoringData()
{
return null;
}
public boolean getMonitoringStatus()
{
return false;
}
public int getRevision()
{
return 10;
}
public void setMonitoringStatus(boolean status)
{
}
public void start(BundleContext arg0) throws Exception
{
}
public void stop(BundleContext arg0) throws Exception
{
}
}
플러그인 등록 파일
사용자 정의 사용자 프로비전 플러그인은 다음과 같은 플러그인 XML 파일에 정의되어야 합니다.
<Plugin type="User Provisioning">
<author>uid=admin</author>
<email>admin@example</email>
<creationDate>08:00:00,2014-01-15</creationDate>
<description>Custom Provisioning Plugin</description>
<configuration>
<AbributeValuePair>
<Attribute type="string" length="100">USER_BASE_DN</Abribute> <mandatory>false</mandatory>
<instanceOverride>false</instanceOverride>
<globalUIOverride>false</globalUIOverride>
<value> </value>
</AbributeValuePair>
</configuration>
</Plugin>
중요 참고 사항: XML 파일은 플러그인을 구현하는 클래스(이 경우
CustomUserProvisioning.xml)와 동일한 이름을 가져야 합니다.
자세한 내용은 OAM Developer's Guide를 참조하십시오.
Manifest 파일
사용자 정의 사용자 프로비전 플러그인을 JAR 파일로 패키지화하기 전에 다음과 같은 MANIFEST.MF를 정의해야 합니다.
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: CustomUserProvisioning
Bundle-SymbolicName: CustomUserProvisioning
Bundle-Version: 10
Bundle-Activator: userprov.CustomUserProvisioning Import-Package: org.osgi.framework;version="1.3.0",oracle.security.fed
.plugins.fed.provisioning,javax.naming,javax.naming.directory,oracle. security.am.plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
자세한 내용은 OAM Developer's Guide를 참조하십시오.
주: 매니페스트 파일은 플러그인에 사용된 모든 패키지를 나열하는 ImportPackage 등록 정보를 포함해야 합니다.
플러그인 작성
컴파일 중
OAM 배치에서 다음 JAR 파일을 컴파일에 사용해야 합니다.
-
felix.jar
-
오암 plugin.jar
-
fed.jar
이러한 파일은 다음 위치에 있습니다.
-
felix.jar:
$IAM_HOME/oam/server/lib/plugin/felix.jar -
oam-plugin.jar:
$IAM_HOME/oam/server/lib/plugin/oam-plugin.jar -
fed.jar:
$DOMAIN_HOME/servers/MANAGED_INSTANCE_NAME/tmp/_WL_user/oam_server/RANDOM_STRING/APP-INF/lib에서RANDOM_STRING가 임의 문자가 있는 디렉토리 이름(예: 테스트 설치의 경우 88g74i)입니다. 예제에서는 CustomerUserProvisioning.java 파일을src/userprov폴더에 배치합니다. bash-4.1$ ls -lsrc/userprov/total 8-rw-r--r-- 1 root root 4717 Mar 1 11:42 CustomUserProvisioning.java
컴파일하려면 다음 명령을 실행합니다.
$JDK_HOME/bin/javac -cp $IAM_HOME/oam/server/lib/plugin/felix.jar:$IAM_HOME/oam/server/lib/plugin/oam-plugin.jar:/tmp/oam-server/APPINF/lib/fed.jar src/userprov/*.java
커스텀 플러그인 패키지화
이전 섹션에 나열된 콘텐츠를 기반으로 현재 디렉토리에 MANIFEST.MF를 생성하고 이전 섹션에 나열된 플러그인 정의를 포함하는 src 디렉토리를 CustomUserProvisioning.xmlin했습니다.
find
.
./MANIFEST.MF
./src
./src/userprov
./src/userprov/CustomUserProvisioning.class
./src/userprov/CustomUserProvisioning.java ./src/CustomUserProvisioning.xml
플러그인 및 필요한 파일을 포함하는 CustomUserProvisioning.jar JAR 파일을 생성하려면 다음 명령을 실행합니다.
jar cfvm CustomUserProvisioning.jar MANIFEST.MF -C src/ .
added manifest adding: userprov/(in = 0) (out= 0)(stored 0%) adding: userprov/CustomUserProvisioning.class(in =3991) (out= 1954)(de_ated 51%)
adding: userprov/CustomUserProvisioning.java(in =4717) (out= 1401)(de_ated 70%)
adding: CustomUserProvisioning.xml(in = 486) (out= 266)(de_ated 45%)
그러면 CustomUserProvisioning.jar가 생성됩니다. 파일 내용을 보려면 다음과 같이 하십시오.
unzip -l CustomUserProvisioning.jar 아카이브: CustomUserProvisioning.jar
| 길이 | 일자 | 시간 | 이름 |
|---|---|---|---|
| 0 | 03-01-2014 | 14:32 | 메타 정보 |
| 404 | 03-01-2014 | 14:32 | 메타 정보/MANIFEST.MF |
| 0 | 03-01-2014 | 12:10 | 사용자프로브/ |
| 3991 | 03-01-2014 | 12:10 | 사용자프로브/CustomUserProvisioning.class |
| 4717 | 03-01-2014 | 11:42 | 사용자프로브/CustomUserProvisioning.java |
| 486 | 03-01-2014 | 14:04 | CustomUserProvisioning.xml |
| 9598 | 6 파일 |
중요: JAR 파일은 플러그인을 구현하는 클래스(이 경우 CustomUserProvisioning.jar)와 동일한 이름을 가져야 합니다.
사용자정의 프로비저닝 모듈 배포
다음 단계를 수행하여 OAM에 사용자 정의 사용자 프로비전 플러그인을 배치합니다.
-
OAM 관리 콘솔(
http(s)://oam-admin-host:oam-adminport/oamconsole)로 이동합니다. -
Access Manager, Plugins로 이동합니다.
-
플러그인 임포트를 누릅니다.
-
플러그인 JAR 파일(이 예제에서는
CustomUserProvisioning.jar)을 선택합니다.

플러그인이 업로드됨 상태임:

플러그인을 런타임 OAM 서버에 배포하고 활성화해야 합니다.
-
플러그인을 선택합니다.
-
Distribute Selected를 누릅니다.
-
플러그인의 Activation Status(활성화 상태) 탭에는 플러그인 상태가 표시됩니다.

플러그인을 활성화해야 합니다.
-
플러그인을 선택합니다.
-
Activate Selected를 누릅니다.
-
플러그인의 Activation Status(활성화 상태) 탭에는 플러그인 상태가 표시됩니다.

마지막으로 플러그인은 사용자 기본 DN에 대해 구성되어야 합니다. 다음 단계를 수행하십시오.
-
플러그인을 선택합니다.
-
플러그인의 구성 매개변수 탭을 누릅니다.
-
사용자 기본 DN(예: 사용 중인 디렉토리: ou=users,dc=us,dc=oracle,dc=com)을 입력합니다.
-
저장을 누릅니다.

사용자 정의 사용자 프로비전 모듈 사용
OAM에서 유저 프로비저닝(provisioning) 활성화
OAM/SP에서 사용자 프로비전을 사용/사용 안함으로 설정하려면 다음 단계를 수행하십시오.
-
$IAM_ORACLE_HOME/common/bin/wlst.sh를 실행하여 WLST 환경을 입력합니다. -
WLS 관리 서버(
connect())에 연결합니다. -
도메인 런타임 분기(
domainRuntime())로 이동합니다. -
userprovisioningenabled속성을 다음으로 업데이트합니다. -
OAM/SP에서 사용자 프로비전 사용:
putBooleanProperty("/fedserverconfig /userprovisioningenabled", "true") -
OAM/SP에서 사용자 프로비전 사용 안함:
putBooleanProperty("/fedserverconfig /userprovisioningenabled", "false") -
WLST 환경
exit()를 종료합니다.
커스텀 플러그인을 사용하도록 OAM 구성
사용자정의 플러그인을 사용하도록 OAM/SP를 구성하려면 다음 단계를 수행하십시오.
-
$IAM_ORACLE_HOME/common/bin/wlst.sh를 실행하여 WLST 환경을 입력합니다. -
WLS 관리 서버(
connect())에 연결합니다. -
도메인 런타임 분기(
domainRuntime())로 이동합니다. -
다음으로
userprovisioningplugin속성을 업데이트합니다. 사용자정의 플러그인을 사용하도록 OAM을 구성하고 속성을 플러그인 이름으로 설정합니다(예:CustomUserProvisioning).putStringProperty("/fedserverconfig/userprovisioningplugin","CustomUserProvisioning") -
내장 User Provisioning 모듈을 사용하도록 OAM 구성:
putStringProperty("/fedserverconfig /userprovisioningplugin","FedUserProvisioningPlugin") -
WLST 환경
exit()를 종료합니다.
설정 테스트
이전에 구성한 것과 동일한 SAML 2.0 Federation 설정을 사용합니다. 여기서 각 항목은 다음과 같습니다.
-
OAM은 서비스 제공자 역할을 합니다.
-
IdP(
AcmeIdP)는 다음과 함께 SAML 검증을 전송합니다.-
NameID가userID로 설정됨 -
속성 전송됨
-
사용자의 전자 메일 주소로 설정된 전자 메일
-
사용자의 이름으로 설정된 fname
-
-
사용자의 성으로 설정된 surname
-
사용자의 마지막 직책으로 설정된 직책
-
다음 IdP 속성 프로파일로 구성된 OAM/SP
-
fname을 givenname에 매핑합니다.
-
SN에 성 매핑
-
메일에 전자메일 매핑
-
사용자 앨리스는 IdP에서 사용되지만 앨리스에 대한 사용자 계정은 OAM/SP에 존재하지 않습니다.
-
userID: 앨리스
-
이메일: alice@oracle.com
-
이름: Alice
-
last name: 애플릿
-
title: 관리자
-
원격 IdP 파트너가 있는 SAML 2.0 통합 SSO 중 IdP에서 다시 전송된 검증이 있는 XML SAML 응답은 다음과 같습니다.
<samlp:Response ..>
<saml:Issuer ...>http://acme.com/idp</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ...>
<saml:Issuer ...>http://acme.com/idp</saml:Issuer>
<dsig:Signature ...>
...
</dsig:Signature>
<saml:Subject>
<saml:NameID ...>alice</saml:NameID>
...
</saml:Subject>
<saml:Conditions ...>
...
</saml:Conditions>
<saml:AuthnStatement ...>
...
</saml:AuthnStatement>
<saml:AbributeStatement ...>
<saml:Attribute Name="email" ...>
<saml:AbributeValue ...>alice@oracle.com</saml:AbributeValue>
</saml:Abribute>
<saml:Attribute Name="title" ...>
<saml:AbributeValue ...>manager</saml:AbributeValue>
</saml:Abribute>
<saml:Attribute Name="surname" ...>
<saml:AbributeValue ...>Appleton</saml:AbributeValue>
</saml:Abribute>
<saml:Attribute Name="fname" ...>
<saml:AbributeValue ...>Alice</saml:AbributeValue>
</saml:Abribute>
</saml:AbributeStatement>
</saml:Assertion>
</samlp:Response>
OAM/SP에 의한 SAML 2.0 검증 처리 결과에는 변환된 속성과 NameID가 표시됩니다.

테스트
통합 SSO 후에 앨리스에 대한 사용자 레코드가 생성되었습니다.
- dn: uid=alice,ou=users,dc=us,dc=oracle,dc=com
- mail: alice@oracle.com
- givenName: 앨리스
- objectClass: person
- objectClass: inetOrgPerson
- objectClass: organizationalPerson
- objectClass: 맨 위
- uid: alice
- cn: alice
- n: alice
- sn: 애플릿
추가 학습 자원
docs.oracle.com/learn의 다른 실습을 탐색하거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 접근할 수 있습니다. 또한 education.oracle.com/learning-explorer를 방문하여 Oracle Learning Explorer로 전환할 수 있습니다.
제품 설명서는 Oracle Help Center를 참조하십시오.
JIT Custom User Provisioning in OAM and SP Continued
F60939-01
September 2022
Copyright © 2022, Oracle and/or its affiliates.