このアプリケーションはWebサービスを介して独自の認証システムを使用しているため、ユーザーの役割を管理する必要がある新しいプロジェクトで作業しています。したがって、私が行う必要があるのは、各ユーザーロールを検証することだけです。データベースにユーザーIDが存在する場合、それ以外の場合に入力できるユーザーIDは拒否されます。つまり、パスワードやログインページ(Webサービスによって実行される)はなく、ユーザーIDの検証とその役割の取得だけです。
私の理解に従ってこれを実装するために概念実証を行いました。これは、関連するドキュメントを読んだ後のことです。重要なのは、これが期待どおりに機能していないということです。この例をあなたと共有しましょう。
セキュリティ設定
<?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.1.xsd">
<security:http use-expressions="true" entry-point-ref="http403ForbiddenEntryPoint">
<security:anonymous enabled="false" />
<security:intercept-url pattern="index.jsp" access="permitAll" />
<security:intercept-url pattern="home.html" access="hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="excel.html" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="denied.jsp" access="permitAll" />
<security:custom-filter position="PRE_AUTH_FILTER" ref="meivFilter" />
</security:http>
<bean id="http403ForbiddenEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="meivFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="Host" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.
preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
</property>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="preauthAuthProvider" />
</security:authentication-manager>
<bean id="userDetailsService" class="com.gm.gpsc.meiv.security.UserServiceImpl" />
</beans>
注:テストするために、ご覧のとおり、RequestHeaderAuthenticationFilterでprincipalRequestHeader属性として使用します。これは、デフォルトのヘッダー値として存在するHostヘッダー値です。テストのためだけに。将来、ヘッダーから値を読み取る予定だからです。
これは、ユーザーロールを取得するために行ったuserDetailServiceです。
public class UserServiceImpl implements UserDetailsService {
private boolean accountNonExpired = true;
private boolean accountNonLocked = true;
private boolean credentialsNonExpired = true;
private boolean enabled = true;
@Override
public UserDetails loadUserByUsername(String userId)
throws UsernameNotFoundException {
GrantedAuthority[] grantedAuthority = new GrantedAuthority[1];
grantedAuthority[0] = new GrantedAuthorityImpl("ROLE_USER");
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(grantedAuthority[0]);
return new User(userId, "x",enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
}
}
この例を実行すると、設定が正常に読み込まれ、最初のパターンであるhome.htmlに到達しようとすると、そのページに到達できますが、これは間違っています。これは、私のルールによれば、ROLE_USERがあり、上記のようにROLE_ADMINが必要です。
2番目のパターンについてもアクセスできますが、その場合はROLE_USERがルールとして含まれているため、これは理にかなっています。
最初の状況では、home.htmlを/home.htmlに変更すると、403Accessが拒否されました。しかし、2番目のオプションexcelに同じパターンを使用すると、それは/excel.htmlを意味し、同じエラー(403)が発生します。
これは、ログファイルから取得したエラーです。
DEBUG | 2012-09-30 03:55:09,738 | FilterChainProxy | /index.jsp at position 1 of 7 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG | 2012-09-30 03:55:09,739 | HttpSessionSecurityContextRepository | No HttpSession currently exists
DEBUG | 2012-09-30 03:55:09,739 | HttpSessionSecurityContextRepository | No SecurityContext was available from the HttpSession: null. A new one will be created.
DEBUG | 2012-09-30 03:55:09,744 | FilterChainProxy | /index.jsp at position 2 of 7 in additional filter chain; firing Filter: 'RequestHeaderAuthenticationFilter'
DEBUG | 2012-09-30 03:55:09,744 | RequestHeaderAuthenticationFilter | Checking secure context token: null
DEBUG | 2012-09-30 03:55:09,744 | HttpSessionSecurityContextRepository | SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG | 2012-09-30 03:55:09,744 | SecurityContextPersistenceFilter | SecurityContextHolder now cleared, as request processing completed
30/09/2012 03:55:09 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() para servlet jsp lanzó excepción
org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: MYID header not found in request.
ここで何が起こっているのかわかりません。誰かが私が間違っているところを説明してくれるかもしれません。
私はこれにとても混乱していて、どこにも行かずにドキュメントを読むのにうんざりしているので、あなたの助けに感謝します。