Reputation: 439
I'm just a beginner to Spring
and Spring Security
. Here I'm creating a Spring MVC
application with Spring Security
. I just want to save authenticated username into a database. Using following form I'm getting the logged username. But I don't know how to save that username using path=""
attribute.
This is the form
<form:form modelAttribute="reservation">
<div>
<label for="name">Name</label>
<sec:authentication var="user" property="principal" />
<sec:authorize access="isAuthenticated()">
${user.username}
</sec:authorize>
</div>
<div>
<label for="emailAddress">Email</label>
<form:input path="emailAddress"/>
</div>
Here is the controller
@RequestMapping(value="/flight-reservation", method={RequestMethod.POST})
public String doReservation(@Valid @ModelAttribute("reservation") FlightReservation reservation ,BindingResult result){
if(result.hasErrors()){
return "flight-reservation";
}
reservationService.save(reservation);
return "redirect://flight-reservation.html?ok=true";
}
I can save email
using path="emailAddress"
But my question is how to save that logged username
using path
of something else. I appreciate your help.
Upvotes: 0
Views: 364
Reputation: 148890
Thanks to Spring security integration in Spring MVC, you directly get principal as a controller parameter:
@RequestMapping(value="/flight-reservation", method={RequestMethod.POST})
public String doReservation(@Valid @ModelAttribute("reservation") FlightReservation reservation,
BindingResult result, @AuthenticationPrincipal Principal principal){
// use principal (Authentication.getPrincipal) to extract user name and use it
....
This one is valid since Spring Security 3.2 If you use an older version, you must use the SecurityContextHolder
:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Principal principal = authentication == null ? null : authentication.getPrincipal();
Assuming that your authentication object returns a UserDetails
, you could use it that way:
@RequestMapping(value="/flight-reservation", method={RequestMethod.POST})
public String doReservation(@Valid @ModelAttribute("reservation")
FlightReservation reservation ,BindingResult result,
@AuthenticationPrincipal UserDetails details){
if(result.hasErrors()){
return "flight-reservation";
}
reservation.setUser(details.getUserName); // adapt it to your real classes...
reservationService.save(reservation);
return "redirect://flight-reservation.html?ok=true";
}
That mean you use ${user.username}
in the JSP to display current authenticated user name, but you get it directly from Spring security in your controller, store it in your reservation
object that already contains the other fields initialized via the form and pass the object containing th user name (or whatever it contains representing the authenticated user) to the service. That way, Spring security guarantees that the user written in the database is the authenticated user even it somenone tries to send a forged request.
Alternatively, Spring Framework Reference explicitely says that you can pass a Principal
parameter to a @RequestMapping
annotated method, and the parameter will recieve the currently authenticated user
. In fact you get request.getUserPrincipal
that was populated with the Spring Security Authentication
So you can simply write:
@RequestMapping(value="/flight-reservation", method={RequestMethod.POST})
public String doReservation(@Valid @ModelAttribute("reservation") FlightReservation reservation,
BindingResult result, Principal principal){
Authentication auth = (Authentication) principal;
or directly as Authentication
implements Principal
@RequestMapping(value="/flight-reservation", method={RequestMethod.POST})
public String doReservation(@Valid @ModelAttribute("reservation") FlightReservation reservation,
BindingResult result, Authentication auth){
and get the user name from there.
Upvotes: 1