我有一个简单的POJO作为映射到的web服务,比方说/ public / authenticate:
WebService
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class AuthWS{
@WebMethod
public boolean doAuthenticate(String securityToken) {
....
}
}
此Web服务不会要求身份验证,也不是受保护的资源。
我确实有其他私有web服务映射到路径:/ private / ws / *;
目前我使用的是具有数据库登录模块设置的安全域。它工作正常,但用户首先需要根据向/ j_security_check发布的帖子请求进行身份验证。只有在此步骤之后,用户才能使用其他私人网络服务。
我想在客户端调用此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.
}
}
在我的CustomLoginModule实现JAAS LoginModule以使用自定义逻辑检查securityToken,例如验证它是否使用公钥进行了正确签名。 securityToken包含有关主体的信息。
如果您需要更多详细信息,请随时提出。
感谢。
EDITED
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包含: 公共类CustomCallbackHandler实现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对象进行身份验证的方式是否正确。我不明白为什么会出现这个问题。