0

私のアプリケーションは、クロスコンテキスト属性を検索するために使用されることになっているsessionIdと呼ばれるリクエストパラメータを受け取ることになっています。

私はこれを実装するためにSpringSecurityを検討していましたが、AuthenticationProviderの適切な実装はすでにあると思います。

public Authentication authenticate(Authentication authentication) throws AuthenticationException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
ServletContext servletContext = request.getSession().getServletContext();
String sessionId = request.getParameter("sessionId");
if (sessionId != null) {
    ServletContext sc = request.getSession().getServletContext();
    Object obj = sc.getContext("/crosscontext").getAttribute(sessionId);

    if (obj != null) {
        // return new Authentication
    }
} else {
    logger.error("No session id provided in the request");
    return null;
}
if (!GWT.isProdMode()) {
        // return new Authentication
} else {
    logger.error("No session id provided in the request");
    return null;
}
}

ここで、私がやりたいのは、ユーザー名とパスワードの入力を求めないようにSpring Securityを構成し、この認証プロバイダーに到達してauthenticateメソッドを呼び出すようにすることです。

どうすればこれを達成できますか?

4

1 に答える 1

0

セキュリティの設計を確認し、SpringSecurityによってすでに提供されている事前認証されたメカニズムに近いものを探すことで問題を修正しました。

SpringSecurityの2つのコンポーネントを拡張しました。最初のものはAbstractPreAuthenticatedProcessingFilterであり、通常、彼の役割はヘッダーで提供されるプリンシパルを提供することです。私の場合、ヘッダー値を取得し、2つのアプリケーション間で共有されているコンテキストで、そのヘッダーに対応する属性を検索し、それをプリンシパルとして返します。

public class MyApplicationPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {

private static final Logger logger = Logger.getLogger(MyApplicationPreAuthenticatedProcessingFilter.class);

@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {

    if (MyApplicationServerUtil.isProdMode()) {
        String principal = request.getHeader("MY_HEADER");
        String attribute = (String) request.getSession().getServletContext().getContext("/crosscontext").getAttribute(principal);
        logger.info("In PROD mode - Found value in crosscontext: " + attribute);
        return attribute;
    } else {
        logger.debug("In DEV mode - passing through ...");
        return "";
    }
}

@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
    return null;
}

}

もう1つのコンポーネントはAuthenticationProviderで、認証がprodモード(GWT prod)で実行されたときにプリンシパルが含まれているかどうかをチェックします。

public class MyApplicationAuthenticationProvider implements AuthenticationProvider {

private static final Logger logger = Logger.getLogger(MyApplicationAuthenticationProvider.class);

public static final String SESSION_ID = "sessionId";

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

    if (MyApplicationServerUtil.isProdMode()) {
        if (StringUtils.isNotEmpty((String) authentication.getPrincipal())) {
            logger.warn("Found credentials: " + (String) authentication.getPrincipal());
            Authentication customAuth = new CustomAuthentication("ROLE_USER");
            customAuth.setAuthenticated(true);
            return customAuth;
        } else {
            throw new PreAuthenticatedCredentialsNotFoundException("Nothing returned from crosscontext for sessionId attribute ["
                    + (String) authentication.getPrincipal() + "]");
        }
    } else {
        Authentication customAuth = new CustomAuthentication("ROLE_USER");
        customAuth.setAuthenticated(true);
        return customAuth;
    }
}

@Override
public boolean supports(Class<?> authentication) {
    return PreAuthenticatedAuthenticationToken.class.isAssignableFrom(authentication);
}

}

最も安全なアプリケーションではない可能性があることを理解しています。ただし、すでに安全な環境で実行されています。しかし、改善のための提案があれば、大歓迎です!

于 2013-04-02T11:45:56.313 に答える