Реализация Spring Security CAS в веб-сервисе

Нашей команде было поручено каким-то образом защитить веб-службу, теперь у нас есть другое веб-приложение, защищенное с помощью SpringSecurity CAS, и мы думали, что это также сработает для защиты веб-службы. Идея заключается в том, что если пользователь входит в одно из веб-приложений через сервер CAS, при вызове веб-службы он увидит, что этот пользователь уже аутентифицирован, и позволит ему использовать его. Мы не совсем уверены, что это правильный способ сделать это, поскольку было много разговоров об использовании HMAC или Oauth 2.0, но мы подумали о CAS, потому что это то, что используют все остальные.

Вот что у меня есть после этого урока:

http://www.oudmaijer.com/2009/12/28/spring-3-spring-security-3-cas-3-3-4-integration/

пом.xml

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>3.0.0.RELEASE</version>
    <optional>false</optional>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>3.0.0.RELEASE</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-cas-client</artifactId>
    <version>3.0.0.RELEASE</version>
    <optional>false</optional>
</dependency>

веб.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>webservice</display-name>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
    <servlet-name>service</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>service</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Start Spring CAS integration -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext-security.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- End Spring CAS integration -->

applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<!--
    Enable security, let the casAuthenticationEntryPoint handle all intercepted urls.
    The CAS_FILTER needs to be in the right position within the filter chain.
-->
<security:http entry-point-ref="casAuthenticationEntryPoint" auto-config="true">
    <security:intercept-url pattern="/**" access="ROLE_USER"></security:intercept-url>
    <security:custom-filter position="CAS_FILTER" ref="casAuthenticationFilter"></security:custom-filter>
</security:http>

<!--
    Required for the casProcessingFilter, so define it explicitly set and
    specify an Id Even though the authenticationManager is created by
    default when namespace based config is used.
-->
<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="casAuthenticationProvider"></security:authentication-provider>
</security:authentication-manager>

<!--
    This section is used to configure CAS. The service is the
    actual redirect that will be triggered after the CAS login sequence.
-->
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
    <property name="service" value="http://localhost:8080/service/j_spring_cas_security_check"></property>
    <property name="sendRenew" value="false"></property>
</bean> 

    <!--
    The CAS filter handles the redirect from the CAS server and starts the ticket validation.
-->
<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager"></property>
</bean>

<!--
    The entryPoint intercepts all the CAS authentication requests.
    It redirects to the CAS loginUrl for the CAS login page.
-->
<bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
    <property name="loginUrl" value=""></property>
    <property name="serviceProperties" ref="serviceProperties"></property>
</bean>

<!--
    Handles the CAS ticket processing.
 -->
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
    <property name="userDetailsService" ref="userService"></property>
    <property name="serviceProperties" ref="serviceProperties"></property>
    <property name="ticketValidator">
        <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
            <constructor-arg index="0" value=""></constructor-arg>
        </bean>
    </property>
    <property name="key" value="cas"></property>
</bean>

<!--
    The users available for this application.
-->
<security:user-service id="userService">
    <security:user name="user" password="user" authorities="ROLE_USER"></security:user>
</security:user-service>    

Not sure what is missing or what's going on, but when I start up my tomcat server in eclipse, I get an error such as:

ERROR 2012-04-25 09:24:33 Context initialization failed
java.lang.NoClassDefFoundError: org/springframework/core/convert/support/PropertyTypeDescriptor
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:722)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:410)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.lang.ClassNotFoundException: org.springframework.core.convert.support.PropertyTypeDescriptor
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316)
... 29 more
Apr 25, 2012 9:24:33 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class  org.springframework.web.context.ContextLoaderListener 
java.lang.NoClassDefFoundError: org/springframework/core/convert/support/PropertyTypeDescriptor
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:722)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:410)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.lang.ClassNotFoundException: org.springframework.core.convert.support.PropertyTypeDescriptor
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316)
... 29 more
Apr 25, 2012 9:24:33 AM org.apache.catalina.core.StandardContext start
SEVERE: Error listenerStart
Apr 25, 2012 9:24:33 AM org.apache.catalina.core.StandardContext start
SEVERE: Context [/bannernotifications] startup failed due to previous errors
Apr 25, 2012 9:24:33 AM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
Apr 25, 2012 9:24:33 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Apr 25, 2012 9:24:33 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Apr 25, 2012 9:24:33 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/15  config=null
Apr 25, 2012 9:24:33 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 855 ms

Извините, что так длинно, но я просто хотел рассказать как можно больше.

Как указал @ smp7d, CAS может быть не лучшим вариантом для этого. Я нашел это,

Защита REST и JSON

это именно то, что представляет собой этот веб-сервис, RESTful и обслуживающий JSON, он будет размещен внутри и доступен только внутри. Теперь я думаю, что вопрос перешел от использования CAS к тому, что нам следует использовать, что такое стандарт?

Спасибо


person idonaldson    schedule 25.04.2012    source источник


Ответы (1)


Кажется, вы просите справочный материал...

Я могу сказать вам, что я сомневаюсь, что это существует в настоящее время, когда я выполнил подобную интеграцию, мне пришлось просмотреть код, чтобы действительно понять, как правильно настроить его для нашей среды. (Поскольку все это с открытым исходным кодом, это не должно быть проблемой для вас.) Затем мы создали внутреннюю документацию на основе того, что узнали. Это будет один из тех случаев, когда вам нужно воздержаться от попыток собрать работающую реализацию из существующей конфигурации. Кто-то должен полностью понимать, что происходит на самом деле.

Что касается веб-службы, которая участвует в аутентификации CAS, вам потребуется реализовать что-то вроде Restlet: https://wiki.jasig.org/display/CASUM/RESTful+API

Я предлагаю вам тщательно оценить вашу систему, чтобы решить, действительно ли она нуждается в таком решении. Если ваши вызовы «веб-службы» поступают из браузера, CAS будет обрабатывать их с помощью обычной настройки (хотя вам придется проявить творческий подход, чтобы обрабатывать случаи без проверки подлинности, поскольку вы не будете перенаправляться на страницу входа).

person smp7d    schedule 25.04.2012