Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force re-authentication of credentials in Spring Security?

I would like to force a re-authentication of credentials before allowing execution of particularly sensitive actions in my web application, such as adding a signature to a set of data.

The scenario is that the user is already logged in, clicks to add their signature on the data, and gets presented with fields to enter their credentials which then get passed along to the server for authentication. Failure would not affect the login state, simply deny the action.

I am using the Grails spring-security plugin and authenticating against LDAP (spring-security-ldap) but I'm assuming a solution would be independent of these exact details.

I have the username and password values on the server-side (controller/servlet), how do I authenticate these new credentials?

like image 915
MarquisDeMizzle Avatar asked Jun 16 '14 23:06

MarquisDeMizzle


People also ask

How do I manually set an authenticated user in Spring Security?

To, let's manually trigger authentication and then set the resulting Authentication object into the current SecurityContext used by the framework to hold the currently logged-in user: UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(user, pass); Authentication auth = authManager.

What is SecurityContextHolder getContext () getAuthentication ()?

The HttpServletRequest.getUserPrincipal() will return the result of SecurityContextHolder.getContext().getAuthentication() . This means it is an Authentication which is typically an instance of UsernamePasswordAuthenticationToken when using username and password based authentication.


1 Answers

You can reuse your user credentials and Spring Security infrastructure in your controller without manipulating the current authentication. Basically, your application requests via a simple form username and password and validates it with the authenticationManager. Depending on the outcome you can proceed with your application logic or do something else.

This example shows the usage of authenticationManager inside an Spring MVC Controller. Unfortunately, I'm not a Grails user. To give you an example that works this example is using Java and Spring MVC. JSPs are omitted for the sake of brevity.

A complete example can be found here (under Approval page).

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

@Controller
@RequestMapping("approval")
public class ApprovalController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @RequestMapping(value="confirm.do", method = RequestMethod.GET)
    public String get() {
        return "approval/confirm";
    }

    @RequestMapping(value="confirm.do", method = RequestMethod.POST)
    public String post(@ModelAttribute ApprovalRequestForm form, Map<String, Object> model, Authentication authentication) {
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(form.getUsername(), form.getPassword());
        Authentication authenticate = authenticationManager.authenticate(token);

        if(authenticate.isAuthenticated() && isCurrentUser(authentication, authenticate)) {
            //do your business
            return "approval/success";
        }

        model.put("reason", "credentials doesn't belong to current user");
        return "approval/denied";
    }

    private boolean isCurrentUser(Authentication left, Authentication right) {
        return left.getPrincipal().equals(right.getPrincipal());
    }

    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception exception) {
        ModelAndView model = new ModelAndView("approval/denied");
        model.addObject("reason", exception.getMessage());
        return model;
    }

    public static class ApprovalRequestForm {
        private String username;
        private String password;

        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
}
like image 95
ksokol Avatar answered Oct 29 '22 17:10

ksokol