ひよっこ。

I want to…

Posts Tagged ‘SpringSecurity’

SpringSecurityでIPアクセス制御を行う

Posted by hikaruworld : 2011 6月 15

SpringSecurityを使っていて、特定のIPアドレス以外からの認証を制御したくなりました。
最初はVoterを拡張して、IPAccessVoter的なものを実装していたんですが、
ドキュメントを読んでみると、15. Expression-Based Access Controlというのを発見しました。

読んでみれば、use-expressions=”true”を設定して、accessを利用すれよいとのこと。
ソンナー、コンナカンタンナホウホウガ。

というわけで、ドキュメントに従って以下のように設定しました。

<http use-expressions="true">
    <intercept-url pattern="/hoge*" access="hasIpAddress('127.0.0.1')"/>
</http>

で、確認してみるとOKー。

気がつくのが遅かったorz…。

以下、余談。

大体こういう制御はプロパティに出しておきたいので、プロパティファイルに押し出して@Valueで値を設定しておきました。
プロパティファイルへのキーがconfigとすると、大体こんな感じになります。

<http use-expressions="true">
    <intercept-url pattern="/hoge*" access="#{config.ipAddress}"/>
</http>

設定ファイルはこんな感じ

ipAddress=hasIpAddress('127.0.0.1')

注意点としてはuse-expressionsを利用した場合、accesssの戻り値はbooleanにする必要があるみたいです。
hasIpAddressを複数指定したい場合は、こんな感じで指定します。

ipAddress=hasIpAddress('127.0.0.1') or hasIpAddress('localhost')

以上です。

広告

Posted in program | タグ: , | Leave a Comment »

SpringSecurtiyのSecurityContextを利用したクラスのテスト方法

Posted by hikaruworld : 2011 1月 26

SpringSecurityを利用するとControllerからもこんな感じで、簡単に主体情報を取得できます。

SecurityContextHolder.getContext().getAuthentication().getPrincipal();

ただし、この実装を利用した場合、
ユニットテスト時は当然主体情報を取得できません。
認証情報がありませんので。。。

そのためテストをする場合は、
その認証情報を以下のように、
TestingAuthenticationTokenとしてSecurityContextHolderに格納してあげると良いとのこと。

// User情報は通常格納する主体情報を利用します。
// SpringSecurityを利用する場合は大体UserDetailsを継承しているかと。
User user = new User() {};

// Test用の認証Tokenに格納します。
// 第1引数に実際のユーザ情報、第2引数に資格情報を設定します。
// 後者は@Securedのテストをするような場合に必要になりますが、詳しくは次回。
Authentication authentication = new TestingAuthenticationToken(principal , null);

// SecurityContextの実装クラスをインスタンス化します。
SecurityContext context = new SecurityContextImpl();
context.setAuthentication(authentication);

// staticメソッドでSecurityContextに設定します。
SecurityContextHolder.setContext(context );

実際にテストで利用する場合は@Before辺りで読むと楽です。

参考:Tapestry 5 with Spring Security – problem with unit tests.

以上です。

Posted in program | タグ: , , , | Leave a Comment »

SpringSecurityのMethodSecurityとFilterSecurityではまる

Posted by hikaruworld : 2011 1月 10

結論は、Interceptorを行うFIlterの実装が異なっていた事でした。

現在SpringSecurityを使って設定する場合には、
階層構造定義を以前設定したように行っています。

ROLE_ADMIN > ROLE_LEADER
ROLE_LEADER > ROLE_USER

ただ、この設定でメソッドレベルアノテーションに@Securedを設定した場合に、
上手く行きませんでした。

@Secured(value = "ROLE_LEADER")
public String hoge() {
	return "hoge";
}

ロギングを有効にして(org.springframework.security -> debug)確認してみると、
org.springframework.security.access.vote.RoleHierarchyVoterと、
org.springframework.security.access.vote.RoleVoterがなぜか呼ばれています。

RoleHierarchyVoterは自信で階層構造を設定しているので、
利用されていて当然なんですが、RoleVoterが謎。

ちょっとデバッグしてみると、
FilterSecurityInterceptorとMethodSecurityInterceptorに注入されています。

つまり、Filterレベル(主として認証)の実装は指定した物を参照しているが、
Methodレベル(主として認可)の実装がデフォルト値が利用されているということでしょうか。

というわけで、こんな感じに設定したら解決しました。

<!-- accessDecisionManagerは任意に設定したアクセス管理のインスタンス -->
<global-method-security secured-annotations="enabled" access-decision-manager-ref="accessDecisionManager"/>

うーん。Springの空気読みっぷりを読まなかった自分が悪いなぁと、痛感。

以上です。

Posted in program | タグ: , , | Leave a Comment »

SpringSecurity3で権限の階層構造を定義する

Posted by hikaruworld : 2010 12月 24

参考ページ

バージョンはSpringSecurity3.0.5です。

SpringSecurityでは、認証と認可の設定を比較的簡易に設定することが可能ですが、
実際に運用する場合、権限を包括するような設定を行いたくなります。
つまり、以下のように、上位の権限が下位の権限を包括するようなケースです。
管理者 > ユーザ > ゲスト

この仕組みはRoleHierarchyVoterを利用することで設定することが可能です。

認証の仕組みに関して

Springにおける認可の仕組みを簡単に書いておきます。
※MethodSecurtiyのAccessDecisionManagerの認証処理のみです。

特定のユーザで認証処理が通った場合、そのユーザの持つ権限で
該当画面にアクセスできるか認可の処理が実行されます。
その遷移は以下の絵のようになります。

つまり、

  1. 特定ユーザでアクセスする
  2. 1.のもつユーザ権限が該当画面に適切か投票処理(Voter)が行われる。
    Voterが複数ある場合はそれぞれ認可処理が検証される
  3. 2で実行された投票処理の結果をAccessDecisionManagerで判定する。
    AccessDecisionManagerはデフォルトでは、3パターン(いずれか一つがOK,全てOK,Voter単位での多数決)準備されており、任意に設定可能
  4. 3の結果問題なければ画面が表示され、問題あれば403が返される。
  5. 実際の構成

    サンプルプロジェクトはここにUPしています。

    以下、セキュリティ設定のみ抜粋しています。

    <bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    	<property name="hierarchy">
    		<value>
    			ROLE_ADMIN > ROLE_USER
    			ROLE_USER > ROLE_GUEST
    		</value>
    	</property>
    </bean>
    <bean id="roleHierarchyVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
    	<constructor-arg ref="roleHierarchy" />
    </bean>
    
    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
    	<property name="decisionVoters">
    		<list>
    			<ref bean="roleHierarchyVoter"/>
    			<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
    		</list>
    	</property>
    </bean>
    

    今回はROLE_ADMIN > ROLE_USER > ROLE_GUESTと階層構造で権限を持たせています。
    まずは、accessDecisionManagerにUnanimousBased(いずれか一つのVoterがOKであればよい)を設定しています。
    そのdecisionVotersとして、AuthenticatedVoterとRoleHierarchyVoterを定義しています。

    RoleHierarchyVoterはコンストラクタインジェクションを用いてRolehierarchyImplを定義しています。

    //org.springframework.security.access.vote.RoleHierarchyVoter
        private RoleHierarchy roleHierarchy = null;
    
        public RoleHierarchyVoter(RoleHierarchy roleHierarchy) {
            Assert.notNull(roleHierarchy, "RoleHierarchy must not be null");
            this.roleHierarchy = roleHierarchy;
        }
        /**
         * Calls the <tt>RoleHierarchy</tt> to obtain the complete set of user authorities.
         */
        @Override
        Collection<GrantedAuthority> extractAuthorities(Authentication authentication) {
            return roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
        }
    }
    

    RoleHierarchyVoterが実際に認証処理い利用されるのがRoleHierarchyのため、
    この値をRoleHierarchyImplを定義して、プロパティとしてhierarchyを定義します。
    hierarchyは > で各権限を列挙します。

    おまけ

    なお、IS_AUTHENTICATED_FULLYや、
    IS_AUTHENTICATED_ANONYMOUSLYを
    認証処理で利用している場合は、AuthenticatedVoterも
    Voterに入れてあげる必要があります。

    入れてあげないと、

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0’: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Unsupported configuration attributes: [IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_ANONYMOUSLY]

    といった感じで怒られます。
    これは、ここにもあるようにこれらの定義がAuthenticatedVoterで定義されているためです。

    // org.springframework.security.access.vote.AuthenticatedVoter
    
    //~ Static fields/initializers =====================================================================================
    
    public static final String IS_AUTHENTICATED_FULLY
                      = "IS_AUTHENTICATED_FULLY";
    public static final String IS_AUTHENTICATED_REMEMBERED
                      = "IS_AUTHENTICATED_REMEMBERED";
    public static final String IS_AUTHENTICATED_ANONYMOUSLY
                      = "IS_AUTHENTICATED_ANONYMOUSLY";
    

    以上です。

Posted in program | タグ: , , , | Leave a Comment »