12

SpringSecurity3.1を使用してLDAP認証を実装しました。そのための私のsecurity.xmlファイルは以下に掲載されています。

ユーザーが「ホワイトリスト」(データベーステーブルに保持されている)のIPアドレスからサイトにアクセスした場合、そのユーザーはSpring 3.1で自動的に認証され、リダイレクトされてからサイトにリダイレクトされるように、認証プロセスを変更する必要があります。ログイン画面(私の考えではなく、そう言われました)。

ユーザーがホワイトリストに登録されているIPアドレスのいずれにも属していない場合は、ログインページでLDAP認証を強制的に実行する必要があります。

SpringとSpringSecurityは初めてなので、Spring 3.1リファレンスドキュメントにアクセスして、セクションIをすべて読みました。そこで、特別な認証が必要な場合は、 セクションIIのアーキテクチャと実装を読む必要があるというアドバイスを読みました。私はそれを非常にゆっくりと行い、メモを取りました。

しかし、私はこれらすべてに慣れていないので、自分が何をする必要があるのか​​、そしてそれを実行するための最も賢い方法は何であるのかを完全に理解しているとは言えません。


更新3:スケルトンコードを機能させることができました。これが最終的に作成されたファイルです。


IPアドレスで認証するためのカスタムAuthenticationProvider実装

// Authentication Provider To Authenticate By IP Address With Allowed IPs
// Stored in a db table


package acme.com.controller.security;

//import acme.com.controller.security.CustomUserInfoHolder;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;

import org.apache.log4j.Logger;


public class CustomIPAddressAuthenticationProvider implements AuthenticationProvider
{

    private static final Logger logger = Logger.getLogger(CustomIPAddressAuthenticationProvider.class);
    private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();


    @Override
    public Authentication authenticate(Authentication authentication)
    throws AuthenticationException {


        WebAuthenticationDetails wad = null;
        String userIPAddress         = null;
        boolean isAuthenticatedByIP  = false;

        // Get the IP address of the user tyring to use the site
        wad = (WebAuthenticationDetails) authentication.getDetails();
        userIPAddress = wad.getRemoteAddress();


        logger.debug("userIPAddress == " + userIPAddress);

        // Compare the user's IP Address with the IP address in the database
        // stored in the USERS_AUTHENTICATED_BY_IP table & joined to the
        // USERS tabe to make sure the IP Address has a current user
        //isAuthenticatedByIP =  someDataObject.hasIPAddress(userIPAddress);
        isAuthenticatedByIP = true;


        // Authenticated, the user's IP address matches one in the database
        if (isAuthenticatedByIP)
        {

            logger.debug("isAuthenticatedByIP is true, IP Addresses match");
            UserDetails user = null;


            UsernamePasswordAuthenticationToken result = null;

            result = new UsernamePasswordAuthenticationToken("John Principal",
                                                              "PlaceholderPWE"); 

            result.setDetails(authentication.getDetails());

            return result;
        }


        // Authentication didn't happen, return null to signal that the 
        // AuthenticationManager should move on to the next Authentication provider
        return null;
    }


    @Override
    public boolean supports(Class<? extends Object> authentication)
    {
        // copied it from AbstractUserDetailsAuthenticationProvider
        return(UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }

}

私の*-security.xmlファイル

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:s="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.1.xsd">

    <s:http pattern="/login*" security="none"/>
    <s:http pattern="/search*" security="none"/>
    <s:http pattern="/css/**" security="none"/>
    <s:http pattern="/js/**" security="none"/>
    <s:http pattern="/images/**" security="none"/>




    <s:http auto-config="true" use-expressions="true">
        <s:intercept-url pattern="/**" access="isAuthenticated()" />

        <s:form-login login-page="/login"
          authentication-failure-url="/loginfailed" />
        <s:logout logout-success-url="/logout" />
    </s:http>



    <s:ldap-server url = "ldap://ldap-itc.smen.acme.com:636/o=acme.com"/>


    <bean id="customIPAddressAuthenticationProvider" class="com.acme.controller.security.CustomIPAddressAuthenticationProvider" />


    <s:authentication-manager>
        <!-- Proposed: Custom Authentication Provider: Try To Authenticate BY IP Address First, IF NOT, Authenticate WiTh THE LDAP Authentication Provider -->
        <s:authentication-provider ref="customIPAddressAuthenticationProvider" />
        <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People"/>
    </s:authentication-manager>


</beans>
4

1 に答える 1

4

あなたのアプローチはかなり健全に思えます。Springは成功する結果が得られるまで各AuthenticationProviderを試すと考えているので、あなたの場合はLDAPプロバイダーの前にIPベースのプロバイダーを定義します。

設定によっては、authentication.getDetails()呼び出しでWebAuthenticationDetailsオブジェクトを取得できない場合があります。この場合は、SpringのRequestContextListenerまたはRequestContextFilterをweb.xmlに追加する必要があります。その後、RequestContextHolderクラスを使用してRequestContextHolder.getRequestAttributes()を呼び出すことにより、送信元IPアドレスを取得できます。

AuthenticationProviderを実装するだけでよく、UserDetailsS​​ervice、UserDetails、またはAuthenticationクラスを実装する必要はありません。ユーザーのIPアドレスを介してユーザーを認証できない場合は、nullを返す必要があります。この場合、SpringはLDAPプロバイダーを試します。何らかの理由でLDAPに試行を渡したくない場合は、AuthenticationExceptionをスローする必要があります。これにより、プロセスが停止し、最終的にユーザーに403エラーが発生します。

これがお役に立てば幸いです:)

于 2012-04-18T18:33:53.423 に答える