使用Keycloak在JBoss中部署的应用程序之间共享用户凭据

时间:2016-10-20 07:53:08

标签: java web-services security wildfly keycloak

我有以下情况: 记录用户正在访问Web应用程序的安全部分,该部分显示从安全Web服务获取的数据。

问题: 如何将用户凭据传播到Web服务?我已经关注了Keycloak web site上的教程,因此我可以在EJB中访问用户凭据进行Web服务调用,但它们不会传播到Web服务中。我缺少什么才能获得凭证?

应用程序服务器是Wildfly 10.1,身份提供者Keycloak 2.2.1

Wildfly standalone.xml的一部分:

<extensions>
    <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
    ...
</extensions>
<profile>
    <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
        <secure-deployment name="secappOne.war">
            <SP entityID="secappOne" sslPolicy="EXTERNAL" logoutPage="logout.jsp">
                <Keys>
                    <Key signing="true">
                        <PrivateKeyPem>...</PrivateKeyPem>
                        <CertificatePem>...</CertificatePem>
                    </Key>
                </Keys>
                <IDP entityID="idp" signatureAlgorithm="RSA_SHA256" signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <SingleSignOnService signRequest="true" validateResponseSignature="true" validateAssertionSignature="false" requestBinding="POST" bindingUrl="http://localworker.net:8180/auth/realms/applications/protocol/saml"/>
                    <SingleLogoutService validateRequestSignature="true" validateResponseSignature="true" signRequest="true" signResponse="true" requestBinding="POST" responseBinding="POST" postBindingUrl="http://localworker.net:8180/auth/realms/applications/protocol/saml" redirectBindingUrl="http://localworker.net:8180/auth/realms/applications/protocol/saml"/>
                    <Keys>
                        <Key signing="true">
                            <CertificatePem>...</CertificatePem>
                        </Key>
                    </Keys>
                </IDP>
            </SP>
        </secure-deployment>
    </subsystem>
    <subsystem xmlns="urn:jboss:domain:security:1.2">
        <security-domains>
            <security-domain name="keycloak">
                <authentication>
                    <login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule" flag="required"/>
                </authentication>
            </security-domain>
        </security-domains>
        ...
    </subsystem>
    ...
</profile>

Web应用程序包含一些Web页面和EJB,用于调用Web服务。这被部署为WAR。用户凭证传播到EJB,通过@RolesAllowed(“allMighty”)进行Web服务调用和授权工作正常。

的web.xml:

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>secappOne</display-name>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>

    <security-constraint>
        <display-name>SecurityConstraint</display-name>
        <web-resource-collection>
            <web-resource-name>seccappOneWR</web-resource-name>
            <url-pattern>/secured/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>allMighty</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>KEYCLOAK-SAML</auth-method>
    </login-config>

    <security-role>
        <role-name>allMighty</role-name>
    </security-role>
</web-app>

的JBoss-web.xml中:

<jboss-web>
    <security-domain>keycloak</security-domain>
</jboss-web>

EJB:

@Stateless
@RolesAllowed("allMighty")
public class SimpleDao {
    @WebServiceRef(wsdlLocation = "http://localhost:8080/secwsOne-1.0-SNAPSHOT/SimpleService/SimpleWS?wsdl")
    private SimpleService simpleService;

    public Date getCurrentDate() {
        GetDateResponse response = simpleService.getSimpleSOAP().getDate(new GetDateRequest());
        return response.getDate().toGregorianCalendar().getTime();
    }
}

的JBoss-ejb3.xml:

<?xml version="1.0" encoding="UTF-8"?>
<jboss:ejb-jar
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:s="urn:security:1.1"
    version="3.1" impl-version="2.0">

    <assembly-descriptor>
        <s:security>
            <!-- EJB name or wildcard * is supported -->
            <ejb-name>*</ejb-name>
            <!-- Name of the security domain which is configured in the EJB3 subsystem -->
            <s:security-domain>keycloak</s:security-domain>
        </s:security>
    </assembly-descriptor>
</jboss:ejb-jar>

Web服务是部署为JAR的不同模块中的另一个EJB。

EJB:

@Stateless
@WebService(
    endpointInterface = "com.example.ws.simpleservice.SimplePort",
    targetNamespace = "http://example.com/ws/SimpleService",
    portName = "SimpleSOAP",
    serviceName = "SimpleService",
    wsdlLocation = "wsdl/simple.wsdl")
public class SimpleWS implements SimplePort {

    @Override
    @RolesAllowed("allMighty")
    public GetDateResponse getDate(GetDateRequest request) {
        GetDateResponse response = new GetDateResponse();
        response.setDate(new Date());

        return response;
    }
}

的JBoss-ejb3.xml:

<?xml version="1.0" encoding="UTF-8"?>
<jboss:ejb-jar
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:s="urn:security:1.1"
        version="3.1" impl-version="2.0">

    <assembly-descriptor>
        <s:security>
            <!-- EJB name or wildcard * is supported -->
            <ejb-name>*</ejb-name>
            <!-- Name of the security domain which is configured in the EJB3 subsystem -->
            <s:security-domain>keycloak</s:security-domain>
        </s:security>
    </assembly-descriptor>
</jboss:ejb-jar>

WS调用失败:

09:42:33,770 ERROR [org.jboss.as.ejb3.invocation] (default task-10) WFLYEJB0034: EJB Invocation failed on component SimpleWS for method public com.example.ws.simpleservice.dto.GetDateResponse com.example.ws.SimpleWS.getDate(com.example.ws.simpleservice.dto.GetDateRequest): javax.ejb.EJBAccessException: WFLYEJB0364: Invocation on method: public com.example.ws.simpleservice.dto.GetDateResponse com.example.ws.SimpleWS.getDate(com.example.ws.simpleservice.dto.GetDateRequest) of bean: SimpleWS is not allowed
at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:134)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:66)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:54)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:636)
at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)
at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:195)
at org.jboss.as.webservices.invocation.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:137)
at org.jboss.wsf.stack.cxf.JBossWSInvoker.performInvocation(JBossWSInvoker.java:169)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.invoke(AbstractJAXWSMethodInvoker.java:232)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:85)
at org.jboss.wsf.stack.cxf.JBossWSInvoker.invoke(JBossWSInvoker.java:145)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126)
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)
at org.jboss.wsf.stack.cxf.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:108)
at org.jboss.wsf.stack.cxf.transport.ServletHelper.callRequestHandler(ServletHelper.java:134)
at org.jboss.wsf.stack.cxf.CXFServletExt.invoke(CXFServletExt.java:88)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:212)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.jboss.wsf.stack.cxf.CXFServletExt.service(CXFServletExt.java:136)
at org.jboss.wsf.spi.deployment.WSFServlet.service(WSFServlet.java:140)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:792)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

我还需要做些什么才能通过SOAP调用传递凭据?还有SAML配置吗?

0 个答案:

没有答案