8

jQueryモバイルを使用してモバイルアプリを開発しており、Springセキュリティで正しく設定されたSpring 3.1.xバックエンドでプログラムでユーザーを認証したいと考えています。

ユーザー名とパスワードを含む POST 要求が (jQuery の $.post を使用して) バックエンドに送信され、サーバーは資格情報が正しいかどうかを確認し、ユーザーをログインさせます。

サーバーは SecurityContext で認証を正しく設定しているように見えますが、サーバーに 2 番目の要求 (ログインが必要なページへの $.get) を行うと、セキュリティの詳細が記憶されていないようで、匿名トークンが記憶されているようです。文脈で。

これは、ログインを処理するコントローラー内のメソッドです (簡潔にするためにパスワード チェックは削除されています)。

@RequestMapping(value = "/login", method = RequestMethod.POST, produces = "application/json")
@ResponseBody
public Map<String, String> login(@RequestParam String username, @RequestParam String password, HttpServletRequest request) {
    Map<String, String> response = new HashMap<String, String>();

    User u = userService.findByAccountName(username);

    if (u != null && u.hasRole("inspector")) {
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
        try {
            Authentication auth = authenticationManager.authenticate(token);
            SecurityContextHolder.getContext().setAuthentication(auth);

            response.put("status", "true");
            return response;
        } catch (BadCredentialsException ex) {
            response.put("status", "false");
            response.put("error", "Bad credentials");
            return response;
        }
    } else {
        response.put("status", "false");
        response.put("error", "Invalid role");
        return response;
    }
}

これは、コンテキストからユーザーの詳細を取得するもう 1 つの方法です。

@RequestMapping(value = "/project", method = RequestMethod.GET)
@ResponseBody
public String getProjects(HttpSession session) {

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    User u = userService.findByAccountName(((UserDetails) authentication.getPrincipal()).getUsername());
...

春のセキュリティ構成:

<global-method-security pre-post-annotations="enabled"/>
<http use-expressions="true" auto-config="true">

    <form-login login-processing-url="/static/j_spring_security_check" login-page="/"
                authentication-failure-url="/?login_error=t"/>

    ...
    <intercept-url pattern="/api/**" access="permitAll"/>
    ...
    <remember-me key="biKey" token-validity-seconds="2419200"/>
    <logout logout-url="/logout"/>
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="udm">
        <password-encoder hash="md5"/>
    </authentication-provider>
</authentication-manager>

これは、春のセキュリティ ドキュメントおよびその他のオンライン リソースに従って機能するはずです。何が間違っている可能性がありますか?

4

1 に答える 1

11

私はあなたの構成に混乱しています。独自のログイン コントローラーを実装しましたが、Spring Security のフォーム ログインを使用しているようです。最近、Spring Security + jquery を使用して ajax ログインを実装しました。独自のコントローラーを作成する代わりに、独自の AuthenticationSuccessHandler と AuthenticationFailureHandler を実装して、必要な json 応答を返しました。各クラスの onAuthenticationSuccess および onAuthenticationFailure メソッドをオーバーライドする SimpleUrlAuthenticationSuccessHandler および SimpleUrlAuthenticationFailureHandler を拡張するだけです。

public void onAuthenticationSuccess(HttpServletRequest request,
        HttpServletResponse response, Authentication authentication)
        throws IOException, ServletException {
    response.getWriter().println("{\"success\": true}");
}

public void onAuthenticationFailure(HttpServletRequest request,
        HttpServletResponse response, AuthenticationException exception)
        throws IOException, ServletException {
    response.getWriter().println("{\"success\": false}");
}

次に、 form-login 要素を次のように構成できます...

<form-login login-processing-url="/static/j_spring_security_check" login-page="/"
            authentication-success-handler-ref="ajaxAuthenticationSuccessHandler"
            authentication-failure-handler-ref="ajaxAuthenticationFailureHandler"
            authentication-failure-url="/?login_error=t"/>
于 2012-06-05T15:35:04.420 に答える