简体   繁体   English

Spring安全性:以编程方式登录

[英]Spring security: programmatically log in

We're developing a mobile app with jQuery mobile and want to authenticate the user programmatically on a spring 3.1.x backend correctly set up with spring security. 我们正在开发一个带有jQuery mobile的移动应用程序,并且想要在spring 3.1.x后端以编程方式对用户进行身份验证,并使用spring security进行正确设置。

A POST request is sent to the backend (using jQuery's $.post) containing a username and password, the server then verifies if the credentials are correct and log in the user. POST请求被发送到包含用户名和密码的后端(使用jQuery的$ .post),然后服务器验证凭据是否正确并登录用户。

The server seems to correctly set the authentication in SecurityContext, however when we make a second request to the server (a $.get to a page that requires login) the security details don't seem to be remembered and an anonymous token seems to be in the context. 服务器似乎在SecurityContext中正确设置了身份验证,但是当我们向服务器发出第二个请求($ .get到需要登录的页面)时,安全细节似乎不会被记住,并且匿名令牌似乎是在上下文中。

This is the method in the controller that handles the login (password check removed for brevity): 这是控制器中处理登录的方法(为简洁起见,删除了密码检查):

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

This is the other method in which we get the userdetails out of the context: 这是我们从上下文中获取用户详细信息的另一种方法:

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

Spring security configuration: Spring安全配置:

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

This should work according to the spring security documentation and other online resources. 这应该根据spring安全文档和其他在线资源工作。 Any ideas on what could be wrong? 关于什么可能出错的任何想法?

I'm confused by your configuration. 我对你的配置感到困惑。 You have implemented your own login controller, but you appear to be using Spring Security's form-login. 您已经实现了自己的登录控制器,但您似乎正在使用Spring Security的表单登录。 I have recently implemented ajax login with Spring Security + jquery. 我最近使用Spring Security + jquery实现了ajax登录。 Instead of writing my own controller, I simply implemented my own AuthenticationSuccessHandler and AuthenticationFailureHandler to return the json responses I needed. 我只是实现了自己的AuthenticationSuccessHandler和AuthenticationFailureHandler来返回我需要的json响应,而不是编写自己的控制器。 Just extend SimpleUrlAuthenticationSuccessHandler and SimpleUrlAuthenticationFailureHandler overriding the onAuthenticationSuccess and onAuthenticationFailure methods in each class, something as simple as.... 只需扩展SimpleUrlAuthenticationSuccessHandler和SimpleUrlAuthenticationFailureHandler,覆盖每个类中的onAuthenticationSuccess和onAuthenticationFailure方法,就像....

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

Then you can configure the form-login element with something like... 然后你可以使用类似的东西配置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"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM