私たちは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>
これはに従って動作するはずです春のセキュリティ文書やその他のオンラインリソースへ。何が間違っている可能性があるかに関するアイデア?
SecurityContextHolderのデフォルトの保持ポリシーはThreadLocalです。すべてのリクエストは新しいスレッドで処理されます(実際にはスレッドプールのすべてではありませんが、これは問題ではありません)。スレッドローカルを保持するコンテキストのコピーを所有してください。したがって、ログインメソッドで設定された認証はgetProjectsメソッドではアクセスできません(別のスレッドにあるため)。認証情報をいくつかの場所(たとえばhttpセッション)に保存し、新しい要求がサーバに到着するたびに認証オブジェクトを復元する必要があります(おそらくサーブレットフィルタ) –
Check http://stackoverflow.com/questions/3923296/user-granted -authorities-always-role-anonymous – axtavt
私はaxtavtによってリンクされた優れた答えを使用して、この正確な機能を実装しました。 –