3

我有一个简单的 POJO 作为映射到的 web 服务,可以说 /public/authenticate :

 WebService
 @SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
 public class AuthWS{

   @WebMethod
   public boolean doAuthenticate(String securityToken) {
    ....
   }
}

此 Web 服务不需要身份验证,也不是受保护的资源。

我确实有其他私有网络服务映射到路径:/private/ws/*;

目前,我使用具有数据库登录模块设置的安全域。它工作正常,但用户首先需要通过基于向 /j_security_check 发出发布请求的 Web 表单进行身份验证。只有经过此步骤,用户才能使用其他私有 Web 服务。

我想在客户端调用此 doAuthenticate 方法后以编程方式执行身份验证。以便客户端能够调用其他 /private/ws/* webservice 方法。

我将输入我想要实现的目标:

@WebService
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class AuthWS{

@WebMethod
public boolean doAuthenticate(String securityToken) {
      SomeSecurityManager manager= SomeSecurityManager.getDefaultManager()
      Map<String,Object> map = new HashMap<String, Object>();
      map.put("MY_CUSTOM_SECURITY_TOKEN",securityToken);
      manager.doLogin(map);
    // after webservice method returns, client should now be able to invoke other private webservice
    // this means that the manager should associate with this session an authenticated user.
    // in order that authorization to work.
  }
}

还有我的 CustomLoginModule :

class CustomLogModule implements LoginModule {

  ...
   public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
       // store what's needed
   } 


  public boolean login(){ 
    // get securityToken send from the SomeSecurityManager and validate it.
    // get user information from that token and store into Subject object.
  } 
}

在我的实现 JAAS LoginModule 的 CustomLoginModule 中,使用自定义逻辑检查 securityToken,例如验证它是否使用公钥正确签名。该 securityToken 包含有关主体的信息。

如果您需要更多详细信息,请随时询问。

谢谢。

已编辑

1.) 与 module.xml 一起创建 custom-login-module.jar

<module xmlns="urn:jboss:module:1.1" name="custom.login.module">
    <resources>
        <resource-root path="custom-login-module.jar"/>
    </resources>


    <dependencies>
        <module name="org.picketbox"/>
        <module name="javax.api"/>
        <module name="org.slf4j"/>
    </dependencies>
</module>

2.) 将 custom-login-module.jar 和 module.xml 添加到 jboss-as-7.1.1.Final\modules\custom\login\module

3.) custom-login-module.jar 包含: public class CustomCallbackHandler implements CallbackHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomCallbackHandler.class);
    private String token;

    public CustomCallbackHandler(String token) {
        this.token= token;
    }

    public String getToken() {
        return token;
    }

    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof TokenCallback) {
                ((TokenCallback) callback).setToken(token);
            }
        }
    }
}

public class TokenCallback implements Callback {
 private static final Logger LOGGER = LoggerFactory.getLogger(TokenCallback.class);
 private String token;

 public TokenCallback() {
 }

 public String getToken() {
     return token;
 }

 public void setToken(String token) {
     LOGGER.info("Setting token = " + token);
     this.token = token;
 }
}

public class CustomLoginModule extends AbstractServerLoginModule {
 private static final Logger LOGGER = LoggerFactory.getLogger(CustomLoginModule.class);

 @Override
 public boolean login() throws LoginException {
     LOGGER.info("Doing login()");
     boolean login = super.login();
     super.loginOk = true;
     return login;
 }

 @Override
 protected Principal getIdentity() {
     return new UserPrincipal("some user");
 }

 @Override
 protected Group[] getRoleSets() throws LoginException {
     return new Group[]{new MyGroup()}; // that and has name 'dummy'
 }
}

这些只是虚拟实现。

我的 Web 应用程序是从 .war 存档中部署的。它包含以下内容:jboss-web.xml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE jboss-web
    PUBLIC -//JBoss//DTD Web Application 2.3V2//EN
    http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd>
 <jboss-web>
    <security-domain>custom-auth</security-domain>
 </jboss-web>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     id="WebApp_ID" version="2.5">
    <display-name>WebApp</display-name>
    <session-config>
        <session-timeout>120</session-timeout>
    </session-config>
    <security-constraint>
        <web-resource-collection>
           <web-resource-name>All resources</web-resource-name>
           <description>Protects all private resources</description>
           <url-pattern>/private/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>dummy</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <security-role>
        <role-name>dummy</role-name>
    </security-role>

    <servlet>
        <servlet-name>Private</servlet-name>
        <servlet-class>com.company.private.PrivateWs</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Private</servlet-name>
        <url-pattern>/private/PrivateWs</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>AuthWS</servlet-name>
        <servlet-class>com.company.auth.AuthWS</servlet-class>
    </servlet>
     <servlet-mapping>
        <servlet-name>AuthWS</servlet-name>
        <url-pattern>/AuthWS</url-pattern>
    </servlet-mapping>
</web-app>

@WebService
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class AuthWS{
private static final Logger LOGGER = LoggerFactory.getLogger(AuthWS.class);


@WebMethod
public boolean doAuthenticate(String token) {
    tryProgrammaticLogin(token);
    return true;
}


private void tryProgrammaticLogin(String token) {
    LoginContext loginContext = null;
    try {
        loginContext = new LoginContext("custom-auth", new CustomCallbackHandler(token));
        loginContext.login();
    } catch (LoginException e) {
        LOGGER.info("Some problem occured when trying to custom login.", e);
    }
}
}

从我的 ws 客户端调用 doAuthenticate 有效,但问题是在尝试 ProgrammaticLogin 后发生异常。而且客户无法访问 PrivateWS。

17:33:40,901 INFO  [com.mycompany.AuthWS] (http--0.0.0.0-8080-1) Some problem occured when trying to custom login.: javax.security.auth.login.LoginException: Login Failure: all modules ignored
      at javax.security.auth.login.LoginContext.invoke(LoginContext.java:921) [rt.jar:1.6.0_26]
      at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186) [rt.jar:1.6.0_26]
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683) [rt.jar:1.6.0_26]
      at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.6.0_26]
      at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) [rt.jar:1.6.0_26]
      at javax.security.auth.login.LoginContext.login(LoginContext.java:579) [rt.jar:1.6.0_26]

jboss 配置目录中的standalone.xml 包含:

<security-domain name="custom-auth">
    <authentication>
         <login-module code="com.mycompany.CustomLoginModule" flag="required" module="custom.login.module"/>
    </authentication>
</security-domain>

请告诉我通过创建新的 LoginContext 对象进行身份验证的方式是否正确。我不明白为什么会出现这个问题。

4

0 回答 0