我们具有基于Web的表单登录身份验证功能j_securtiy_check。我们想通过程序化登录身份验证来更改它。使servlet验证传递给它的用户名和密码的正确方法是什么?该Servlet显然没有受到保护。
j_securtiy_check
我们一直在尝试使用server.xml Realm:
<Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="UserDatabase" userTable="app_user" userNameCol="login_name" userCredCol="password_value" userRoleTable="user_perm" roleNameCol="permission_name" allRolesMode="authOnly" digest="MD5" />
这样做的原因是,我们有一个Java Webstart客户端,该客户端将登录信息发送到不受保护的loginServlet。该Servlet当前针对JOSSO单一登录服务进行身份验证,但我希望删除此服务,并对启动程序使用简单的tomcat7身份验证。然后最终迁移到OpenAM。如果我可以以编程方式生成JSSESSIONIDSSO值并将其填充到cookie中。
这是我发现的一些代码。这是调用身份验证的正确方法吗?
ApplicationContextFacade acf = (ApplicationContextFacade) this.getServletContext(); Field privateField = ApplicationContextFacade.class.getDeclaredField("context"); privateField.setAccessible(true); ApplicationContext appContext = (ApplicationContext) privateField.get(acf); Field privateField2 = ApplicationContext.class.getDeclaredField("context"); privateField2.setAccessible(true); StandardContext stdContext = (StandardContext) privateField2.get(appContext); Realm realm = stdContext.getRealm(); Principal principal = realm.authenticate(loginBean.getUsername(), loginBean.getPassword()); if (principal == null) { return 0; } GenericPrincipal genericPrincipal = (GenericPrincipal) principal; System.out.println ("genericPrincipal=" + genericPrincipal.toString());
我注意到这已不再是最新的。最终的解决方案是使用OpenAM提供的Java SDK。
这是起点:http : //openam.forgerock.org/openam- documentation/openam-doc-source/doc/dev-guide/index/chap- jdk.html
1)将此SDK随附的所有jar文件添加到您的Web应用程序。2)更改您的servlet(或重型客户端),使其具有以下代码:
private void addLoginCallbackMessage(LoginCredentialsBean loginBean, Callback [] callbacks) throws UnsupportedCallbackException { int i = 0; try { for (i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof TextOutputCallback) { handleTextOutputCallback((TextOutputCallback) callbacks[i]); } else if (callbacks[i] instanceof NameCallback) { handleNameCallback(loginBean.getUsername(), (NameCallback) callbacks[i]); } else if (callbacks[i] instanceof PasswordCallback) { handlePasswordCallback(loginBean.getPassword(), (PasswordCallback) callbacks[i]); } else if (callbacks[i] instanceof TextInputCallback) { handleTextInputCallback((TextInputCallback) callbacks[i]); } else if (callbacks[i] instanceof ChoiceCallback) { handleChoiceCallback((ChoiceCallback) callbacks[i]); } } } catch (IOException e) { e.printStackTrace(); throw new UnsupportedCallbackException(callbacks[i], e.getMessage()); } } private void handleTextOutputCallback(TextOutputCallback toc) { System.out.println("Got TextOutputCallback"); // display the message according to the specified type switch (toc.getMessageType()) { case TextOutputCallback.INFORMATION: System.out.println(toc.getMessage()); break; case TextOutputCallback.ERROR: System.out.println("ERROR: " + toc.getMessage()); break; case TextOutputCallback.WARNING: System.out.println("WARNING: " + toc.getMessage()); break; default: System.out.println("Unsupported message type: " + toc.getMessageType()); } } private void handleNameCallback(String name, NameCallback nc) throws IOException { nc.setName(name); } private void handleTextInputCallback(TextInputCallback tic) throws IOException { // not supported for server side // prompt for text input } private void handlePasswordCallback(String password, PasswordCallback pc) throws IOException { // prompt the user for sensitive information pc.setPassword(password.toCharArray()); } private void handleChoiceCallback(ChoiceCallback cc) throws IOException { // not supported for server side // ignore the provided defaultValue /* System.out.print(cc.getPrompt()); String [] strChoices = cc.getChoices(); for (int j = 0; j < strChoices.length; j++) { System.out.print("choice[" + j + "] : " + strChoices[j]); } System.out.flush(); cc.setSelectedIndex(Integer.parseInt((new BufferedReader (new InputStreamReader(System.in))).readLine())); */ } private void doLogin () { // ... lots of other logic here // TODO: Make this into modules with this one being for OpenAM if (_useOpenAM) { String orgName = "/"; String moduleName = "DataStore"; String locale = "en_US"; AuthContext lc = new AuthContext(orgName); AuthContext.IndexType indexType = AuthContext.IndexType.MODULE_INSTANCE; lc.login(indexType, moduleName, locale); boolean succeed = false; Callback [] callbacks = null; // get information requested from module while (lc.hasMoreRequirements()) { callbacks = lc.getRequirements(); if (callbacks != null) { addLoginCallbackMessage(loginBean, callbacks); lc.submitRequirements(callbacks); } } if (lc.getStatus() == AuthContext.Status.SUCCESS) { try { System.out.println("Login succeeded."); openAMSessionId = lc.getAuthIdentifier(); System.out.println("lc.getAuthIdentifier()=" + openAMSessionId); System.out.println("lc.getSuccessURL()=" + lc.getSuccessURL()); System.out.println("lc.getSSOToken().getAuthLevel()=" + lc.getSSOToken().getAuthLevel()); System.out.println("lc.getSSOToken().getAuthType()=" + lc.getSSOToken().getAuthType()); System.out.println("lc.getSSOToken().getHostName()=" + lc.getSSOToken().getHostName()); System.out.println("lc.getSSOToken().getIdleTime()=" + lc.getSSOToken().getIdleTime()); System.out.println("lc.getSSOToken().getMaxIdleTime()=" + lc.getSSOToken().getMaxIdleTime()); System.out.println("lc.getSSOToken().getMaxSessionTime()=" + lc.getSSOToken().getMaxSessionTime()); System.out.println("lc.getSSOToken().getTimeLeft()=" + lc.getSSOToken().getTimeLeft()); System.out.println("lc.getSSOToken().getIPAddress()=" + lc.getSSOToken().getIPAddress()); System.out.println("lc.getSSOToken().getTokenID()=" + lc.getSSOToken().getTokenID().toString()); System.out.println("lc.getSSOToken().getPrincipal()=" + lc.getSSOToken().getPrincipal().toString()); } catch (Exception e) { e.printStackTrace(); } succeed = true; } else if (lc.getStatus() == AuthContext.Status.FAILED) { System.out.println("Login failed."); } else { System.out.println("Unknown status: " + lc.getStatus()); } System.out.println( "OpenAM login success=" + succeed); } }
上面的代码中重要的是变量openAMSessionId。最后,有了新的OpenAM单一登录会话ID,您可以将其传递给所有受保护的客户端应用程序,以使用户不会受到登录方面的挑战。
我希望这有帮助。
-dklotz