私はSpringフレームワークとSpring MVCを使ってRESTエンドポイントを作成するWebアプリケーションを持っています。認証は、Java EEセキュリティ(特にActive Directoryに基づくWildfly 9のセキュリティレルム)を使用してコンテナによって提供され、ロールはアプリケーションデータベースからロードされます。通常のサーブレットAPIを使用してユーザーの詳細を利用できるようにするために、フィルタによってリクエストラッパーが適用されています。JSR-250(@RolesAllowed)アノテーションの使用Spring MVCとコンテナ認証
のweb.xml:
<web-app ... version="3.1">
<security-constraint>
<web-resource-collection>
<web-resource-name>Unauthenticated Resources</web-resource-name>
<url-pattern>/favicon.ico</url-pattern>
<url-pattern>/NoAccess.html</url-pattern>
<url-pattern>/login</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/font/*</url-pattern>
<url-pattern>/images/*</url-pattern>
<url-pattern>/js/*</url-pattern>
<url-pattern>/lib/*</url-pattern>
<url-pattern>/partials/*</url-pattern>
</web-resource-collection>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>All Resources</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>App Realm</realm-name>
<form-login-config>
<form-login-page>/Login.jsp</form-login-page>
<form-error-page>/NoAccess.html</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>*</role-name>
</security-role>
</web-app>
SecurityFilter.java
@WebFilter(urlPatterns = { "*" })
public class SecurityFilter implements Filter {
...
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// Don't wrap unauthenticated requests
if (httpRequest.getRemoteUser() == null) {
chain.doFilter(httpRequest, httpResponse);
return;
}
Person user = this.personRepository.findByLogin(httpRequest.getRemoteUser());
if (user != null) {
List<String> roles = this.personRepository.getRoles(user.getId());
HttpServletRequest wrappedRequest = new RequestWrapper(httpRequest, user, roles);
chain.doFilter(wrappedRequest, httpResponse);
} else {
httpResponse.sendRedirect(httpRequest.getContextPath() + "/NoAccess.html");
}
}
}
認証が動作し、コントローラ内、私はrequest.getUserPrincipal()
とrequest.isUserInRole("SYSTEM_ADMIN")
を行うことができますし、彼らが正常に戻ります。今私はアプリケーションに権限を追加したいと思います。私はJSR-250 @RolesPermitted
注釈を使用してコントローラのメソッドに承認ルールを適用したいと思います。私は別の設定ファイル/クラスにすべてのルールをリストする必要はありません。コントローラの例:もちろん
@RestController
@RequestMapping("/people")
public class PersonController {
...
@RolesAllowed({Role.SYSTEM_ADMIN, Role.DEPARTMENT_ADMIN, Role.SYSTEM_AUDITOR, Role.AUDITOR})
@RequestMapping
public List<Person> listPeople(HttpServletRequest request) {
return this.personRepository.getPeople();
}
}
これは自分自身で何もしないので、私は@EnableWebSecurity
と@EnableGlobalMethodSecurity(jsr250Enabled = true)
で設定クラスを追加しました。そのリソースにヒットしたら、エラーorg.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
が出ます。十分に公正なので、私はhttps://gist.github.com/virgium03/86938e43219bc28632d0の例に従っていますが、私は同じエラーが発生し続けます。フィルタがフィルタチェーンに追加されることはないと考えられます。
私は多くのチュートリアルとその記事を読んだことがありますが、それらはすべて同じことを言っているし、私にとってはうまくいきません。私が紛失している単純なものがなければなりません。結局のところ、すべての情報は、Spring Securityが承認決定を下すためのものです。それは可能(可能性がありますか?)私はここで簡単な何かを欠いている。すべてのヘルプは非常に高く評価されています!
編集
私は春のセキュリティコンテキストを移入するために私SecurityFilter
クラスに次のコードを追加しています。それは動作しますが、私はこれが理想的な解決策ではないと感じています。
List<GrantedAuthority> authorities = roles.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
PreAuthenticatedAuthenticationToken auth = new PreAuthenticatedAuthenticationToken(user, "", authorities);
auth.setDetails(new WebAuthenticationDetails(wrappedRequest));
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
しかし、J2eePreAuthenticatedProcessingFilterのソースを見ると、HttpRequestから認証オブジェクトを作成し、それを(AbstractPreAuthenticatedProcessingFilterを介して)セキュリティコンテキストに置くことを示しています。これが私が必要とするものではありませんか? – Doughnuts
私はJ2eePreAuthenticatedProcessingFilterのソースを見て、それは認証オブジェクトを作成していません。 HttpRequestからユーザープリンシパルを返すだけです。 –
https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java(J2eePreAuthenticatedProcessingFilterのスーパークラス) – Doughnuts