4

Spring Security のサンプル PreAuthentication Filter for WebSphere が動作している人はいますか (WebSpherePreAuthenticatedProcessingFilter)? それに関するドキュメントはほとんどなく、私はそれを釘付けにすることはできません。動作していて、構成の例を喜んで提供してくれる人を探しています。Spring 3.1 および WAS 7 または 8 に最適です。

「ちょっと」機能しているように見える構成が整っています。WebSphere で認証し、アプリで URL をヒットできますが、ブラウザーは次のメッセージを返します。

エラー 500: java.lang.RuntimeException: ユーザーのグループを検索中に例外が発生しました

次のような例外スタック トレースを取得します。

java.lang.RuntimeException: Error while invoking method java.lang.reflect.Method.getGroupsForUser([UNAUTHENTICATED])
    at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.invokeMethod(DefaultWASUsernameAndGroupsExtractor.java:147) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE]
    at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(DefaultWASUsernameAndGroupsExtractor.java:115) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE]
    at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(
...

Caused by: java.lang.reflect.InvocationTargetException: null
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60) ~[na:1.6.0]
...

Caused by: com.ibm.websphere.security.EntryNotFoundException: null
    at com.ibm.ws.wim.registry.util.MembershipBridge.getGroupsForUser(MembershipBridge.java:293) ~[com.ibm.ws.runtime.wim.core.jar:201207200704]
...

[12/28/12 14:05:15:879 CST] 00000055 LocalTranCoor E   WLTC0017E: Resources rolled back due to setRollbackOnly() being called.
[12/28/12 14:05:15:879 CST] 00000055 webapp        E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[ServletNameNotFound]: java.lang.RuntimeException: Exception occured while looking up groups for user
    at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(DefaultWASUsernameAndGroupsExtractor.java:123)
    at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(DefaultWASUsernameAndGroupsExtractor.java:94)
...

私の web.xml ファイルは次のとおりです。

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    classpath*:/applicationContext-jcr.xml,
    classpath*:/applicationContext-security.xml
  </param-value>
</context-param>


<filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>

  <filter>
      <filter-name>filterChainProxy</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>

<!--  
<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
-->

<filter-mapping>
  <filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 
<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
 -->

  <filter-mapping>
    <filter-name>filterChainProxy</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- ====================================================================== -->
<!-- S E R V L E T S -->
<!-- ====================================================================== -->
<servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet>
  <servlet-name>ViewStatusMessages</servlet-name>
  <servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
</servlet>

<!-- ====================================================================== -->
<!-- S E R V L E T    M A P P I N G S -->
<!-- ====================================================================== -->

<servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/app/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>ViewStatusMessages</servlet-name>
  <url-pattern>/lbClassicStatus</url-pattern>
</servlet-mapping>

<!-- ====================================================================== -->
<!-- W E L C O M E    F I L E S -->
<!-- ====================================================================== -->
<welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<!-- Use if configuring for JNDI Datasource on J2EE Server -->
<resource-ref id="ResourceRef_LDP_Datasource">
  <description>Resource reference to the LDP datasource.</description>
  <!-- DB2 -->

  <res-ref-name>jdbc/ldpdbDS</res-ref-name>

  <!-- MS SQL -->
  <!-- 
  <res-ref-name>jdbc/ldpdbMSSQLDS</res-ref-name>
   -->
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
  <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<!-- 
  security-constraint reference:
  http://s170.codeinspot.com/q/3419721

  OK, I figured this out. The problem is that even though I had J2EE security setup in Websphere and was authenticated, 
  my web.xml contained no security constraints. Because of this, Websphere was not supplying the principal for my requests. 
  This is apparently an intentional feature. If you are not accessing a protected URL, you should not need the pre-authentication information. 
  To overcome this, I added a security constraint to my web.xml, which allowed ALL users to access the resources. 
  Effectively, the resources were not secured, but still - there was a constraint now.

  This tricks the Websphere into filling in the user principal information in the request.
  -->

<security-constraint>
    <web-resource-collection>
        <web-resource-name>All areas</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>
</security-constraint>

私の Spring セキュリティ コンテキスト XML ファイルは次のとおりです。

<!-- 
<sec:http use-expressions="true">
    <sec:intercept-url pattern="/**" access="denyAll" />
    <sec:form-login />
</sec:http>
   -->
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
  <sec:filter-chain-map path-type="ant">
    <!-- 
        <sec:filter-chain pattern="/**" filters="sif,webspherePreAuthFilter,logoutFilter,etf,fsi"/>
         -->
    <sec:filter-chain pattern="/**" filters="webspherePreAuthFilter,logoutFilter,etf,fsi"/>
  </sec:filter-chain-map>
</bean>
<!-- 
  <bean id="sif" class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
  <bean id="sif" class="org.springframework.security.web.context.SecurityContextIntegrationFilter"/>
-->
<sec:authentication-manager alias="authenticationManager">
  <sec:authentication-provider ref="preAuthenticatedAuthenticationProvider"/>
</sec:authentication-manager>
<bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
  <property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService"/>
</bean>
<bean id="preAuthenticatedUserDetailsService" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService"/>
<!-- 
  This AbstractPreAuthenticatedProcessingFilter implementation is based on WebSphere authentication. 
  It will use the WebSphere RunAs user principal name as the pre-authenticated principal.
  -->
<bean id="webspherePreAuthFilter" class="org.springframework.security.web.authentication.preauth.websphere.WebSpherePreAuthenticatedProcessingFilter">
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="authenticationDetailsSource" ref="authenticationDetailsSource"/>
</bean>
<bean id="preAuthenticatedProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
  <constructor-arg value="/"/>
  <constructor-arg>
    <list>
      <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
    </list>
  </constructor-arg>
</bean>
<!-- 
  This AuthenticationDetailsSource implementation will set the pre-authenticated granted authorities based on the WebSphere 
  groups for the current WebSphere user, mapped using the configured Attributes2GrantedAuthoritiesMapper.

  This AuthenticationDetailsSource implementation, when configured with a MutableGrantedAuthoritiesContainer, 
  will set the pre-authenticated granted authorities based on the WebSphere groups for the current WebSphere user, 
  mapped using the configured Attributes2GrantedAuthoritiesMapper. 

  By default, this class is configured to build instances of the PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails class.
  -->
<bean id="authenticationDetailsSource" class="org.springframework.security.web.authentication.preauth.websphere.WebSpherePreAuthenticatedWebAuthenticationDetailsSource">
  <property name="webSphereGroups2GrantedAuthoritiesMapper" ref="websphereUserGroups2GrantedAuthoritiesMapper"/>
</bean>
<bean id="websphereUserGroups2GrantedAuthoritiesMapper" class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
  <property name="convertAttributeToUpperCase" value="true"/>
</bean>
<bean id="webXmlResource" class="org.springframework.web.context.support.ServletContextResource">
  <constructor-arg ref="servletContext"/>
  <constructor-arg value="/WEB-INF/web.xml"/>
</bean>
<bean id="servletContext" class="org.springframework.web.context.support.ServletContextFactoryBean"/>
<bean id="etf" class="org.springframework.security.web.access.ExceptionTranslationFilter">
  <property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint"/>
</bean>
<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
  <property name="allowIfAllAbstainDecisions" value="false"/>
  <property name="decisionVoters">
    <list>
      <ref bean="roleVoter"/>
    </list>
  </property>
</bean>
<!-- See: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-web-filters.html -->
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
  <property name="securityMetadataSource">
    <sec:filter-security-metadata-source>
      <sec:intercept-url pattern="/**" access="ROLE_LDP_ADMINS"/>
    </sec:filter-security-metadata-source>
  </property>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<!-- 
Simply put, the filter wraps the current httprequest with one that delegates request.isUserInRole() and request.getRemoteUser() to acegi. 
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter">
  <property name="wrapperClass" value="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper"/>
</bean>
-->
4

2 に答える 2

2

機能する構成はありませんが、アドバイスがあります

  • Spring Security デバッグ ロギングを有効にする
  • にできるだけ近づけてデバッグするとMembershipBridge.getGroupsForUser、渡されたユーザー名がnullのように感じます

私の直感に基づいて、事前認証されたユーザーの名前が渡されていないと思われます。数年前にこれを持っていたことを漠然と覚えています-そのコードを掘り下げる必要があります。

于 2012-12-28T20:37:45.787 に答える
1

何らかの理由で、WebSphere は次の制約定義を持つリソースの認証を必要とせず、事前認証は行われません。

<auth-constraint>
    <role-name>*</role-name>
</auth-constraint>

不明なプリンシパルのグループを決定しようとすると、後の段階で失敗します。

リソースをデフォルトのグループ Users で保護し、すべてのユーザーをそれにマッピングしました。

<security-constraint>
    <web-resource-collection>
        <web-resource-name>AuthTest</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>     
    <auth-constraint>
        <role-name>User</role-name>
    </auth-constraint>    
</security-constraint>

<security-role>
    <role-name>User</role-name>
</security-role>

私はこの役割を望んでおらず、そのメンバーを管理していないため、これは一種の回避策ですが、今のところこれですべてです。

于 2015-10-23T14:23:15.227 に答える