2012-05-30 13 views
8

私たちはjQueryモバイルでモバイルアプリケーションを開発しており、春のセキュリティで正しく設定された春3.1.xバックエンドでプログラム的にユーザーを認証したいと考えています。春のセキュリティ:プログラムでログイン

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

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

これは、ログイン(簡潔にするため削除パスワードチェック)を扱うコントローラのメソッドです:

@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()); 
... 

@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; 
    } 
} 

これは、我々はコンテキストの外にuserdetailsを取得する他の方法であり、

春のセキュリティ設定は:

<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> 

これはに従って動作するはずです春のセキュリティ文書やその他のオンラインリソースへ。何が間違っている可能性があるかに関するアイデア?

+0

SecurityContextHolderのデフォルトの保持ポリシーはThreadLocalです。すべてのリクエストは新しいスレッドで処理されます(実際にはスレッドプールのすべてではありませんが、これは問題ではありません)。スレッドローカルを保持するコンテキストのコピーを所有してください。したがって、ログインメソッドで設定された認証はgetProjectsメソッドではアクセスできません(別のスレッドにあるため)。認証情報をいくつかの場所(たとえばhttpセッション)に保存し、新しい要求がサーバに到着するたびに認証オブジェクトを復元する必要があります(おそらくサーブレットフィルタ) –

+1

Check http://stackoverflow.com/questions/3923296/user-granted -authorities-always-role-anonymous – axtavt

+0

私はaxtavtによってリンクされた優れた答えを使用して、この正確な機能を実装しました。 –

答えて

11

あなたの設定では混乱します。独自のログインコントローラを実装しましたが、Spring Securityのフォームログインを使用しているようです。私は最近、Spring Security + jqueryでajaxログインを実装しました。私自身のコントローラを作成するのではなく、自分のAuthenticationSuccessHandlerとAuthenticationFailureHandlerを実装して、必要なjson応答を返すだけでした。ただ、...そして、あなたが何かのように、フォーム・ログイン要素を設定することができ、各クラスのonAuthenticationSuccessとonAuthenticationFailureメソッドをオーバーライド

<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"/> 

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}"); 
} 

....のような単純なものをSimpleUrlAuthenticationSuccessHandlerとSimpleUrlAuthenticationFailureHandlerを拡張

+0

これは完全に機能しました...ありがとうございます。 – HDave

+0

喜んで私の答えを受け入れるようにマークしてください – hyness

+0

もし私ができれば... – HDave

関連する問題