2014-11-28 2 views

답변

2

다음과 같이 선언적 서비스를 사용하여 구현 한 자체 솔루션이 있습니다.

먼저 org.apache.karaf.jaas.modules.AbstractKarafLoginModule까지 확장되는 LoginModule 구현을 새로 만듭니다.

public class CustomLoginModule extends AbstractKarafLoginModule 
{ 
    public void initialize(Subject subject, CallbackHandler callbackHandler, 
     Map<String, ?> sharedState, Map<String, ?> options) 
    { 
     super.initialize(subject, callbackHandler, options); 
     // Use the `options` parameter for extra information that will be used 
     // inside the module; this is passed from the JaasRealm service 
    } 

    public boolean login() throws LoginException 
    { 
     // prepare callback objects and get the authentication information 

     Callback[] callbacks = new Callback[2]; 
     callbacks[0] = new NameCallback("Username: "); 
     callbacks[1] = new PasswordCallback("Password: ", false); 

     try { 
      callbackHandler.handle(callbacks); 
     } 
     catch (Exception e) { 
      throw new LoginException(e.getMessage()); 
     } 

     user = ((NameCallback) callbacks[0]).getName(); 

     char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword(); 
     if (tmpPassword == null) 
      tmpPassword = new char[0]; 
     String password = new String(tmpPassword); 

     // Do the custom authentication and throw `LoginException` if the user 
     // is not valid. Get the roles and groups that the user is assigned to. 

     // ....... 

     // Add roles and groups along with the user information to the `principals` 

     principals = new HashSet<>(); 
     principals.add(new UserPrincipal(user)); 

     for (String role : roles) 
      principals.add(new RolePrincipal(role)); 
     for (String group: groups) 
      principals.add(new GroupPrincipal(group)); 

     return true; 
    } 

    public boolean abort() throws LoginException 
    { 
     return true; 
    } 

    public boolean logout() throws LoginException 
    { 
     subject.getPrincipals().removeAll(principals); 
     principals.clear(); 
     return true; 
    } 
} 

둘째로; 이 클래스를 새로운 영역의 LoginModule로 사용하려면 새로운 org.apache.karaf.jaas.config.JaasRealm 서비스를 등록하고 자체 로그인 모듈을 설정해야합니다. 이 파일을 CustomLoginModule과 동일한 번들에 넣습니다.

@Component(immediate = true) 
public class CustomJaasRealmService implements JaasRealm 
{ 
    public static final String REALM_NAME = "customRealm"; 

    private AppConfigurationEntry[] configEntries; 

    @Activate 
    public void activate(BundleContext bc) 
    { 
     // create the configuration entry field using ProxyLoginModule class 

     Map<String, Object> options = new HashMap<>(); 
     configEntries = new AppConfigurationEntry[1]; 
     configEntries[0] = new AppConfigurationEntry(ProxyLoginModule.class.getName(), 
      LoginModuleControlFlag.SUFFICIENT, options); 

     // actual LoginModule class name will be passed using the options object 

     options.put(ProxyLoginModule.PROPERTY_MODULE, CustomLoginModule.class.getName()); 

     // put bundle id of the LoginModule and bundlecontext of it 
     // (in this case, it is the same bundle) 
     // This is a neat trick to adapt to OSGI classloader 

     long bundleId = bc.getBundle().getBundleId(); 
     options.put(ProxyLoginModule.PROPERTY_BUNDLE, String.valueOf(bundleId)); 
     options.put(BundleContext.class.getName(), bc); 

     // add extra options if needed; for example, karaf encryption 
     // .... 
    } 

    @Override 
    public AppConfigurationEntry[] getEntries() 
    { 
     return configEntries; 
    } 

    // return the name and the rank of the realm 

    @Override 
    public String getName() 
    { 
     return REALM_NAME; 
    } 

    @Override 
    public int getRank() 
    { 
     return 0; 
    } 
} 
관련 문제