Problem: I would like to get/extract the username/email only from authenticate.getName()... if possible, not by using parsing the string.
authentication.getName() or principal.getName() values:
[username]: org.springframework.security.core.userdetails.User@21463e7a: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities
In this example, I would like to get only the value of Username which is [email protected]
Solution:
Since I only want to get the username/email ([email protected]), and it is returning the whole principal content/text (above), I replaced the value I set in the subject from the pricipal value... to the email value.. and it works now.
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {
String email = auth.getName();
String principal = auth.getPrincipal().toString();
Date expiration = new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME);
String token = Jwts.builder()
.setSubject(email) //from principal to email
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET.getBytes())
.compact();
AuthenticatedUser loginUser = new AuthenticatedUser(email);
loginUser.setToken(token);
String jsonUser = Util.objectToJsonResponseAsString(loginUser, "user");
res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
res.setContentType("application/json");
res.setCharacterEncoding(ConstantUtil.DEFAULT_ENCODING);
res.getWriter().write(jsonUser);
}
I can now get the username/email value using different ways like the one you guys are suggesting... even the one I am currently using. I do not need any special parsing now just to get the email value from the Authentication object.
On my previous non RESTful application using Spring... I can easily get the username using Authentication class injected in the controller method parameter.
Controller:
...
public Ticket getBySwertresNo(Authentication authentication, @PathVariable String swertresNo) {
logger.debug("Inside getBySwertresNo: " + swertresNo);
System.out.println("\n[username]: " + authentication.getName() + "\n");
return m_sugalService.getSwertresInfoBySwertresNo(swertresNo);
}
...
Console:
[username]: [email protected]
Now, on my current project... I used a RESTful approach and after successful authentication, I am returning a token which will be used/injected in the request header. I can login using the token... but when I get the value of authentication.getName()... the return is not just the email address but it contains some other information.
Console (REST + JWT):
[username]: org.springframework.security.core.userdetails.User@21463e7a: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities
I would like to get only the username value which is "[email protected]".
JWT Authentication Filter:
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
String username = req.getParameter("username");
String password = req.getParameter("password");
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
Authentication authentication = authenticationManager.authenticate(authenticationToken);
return authentication;
}
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {
String email = auth.getName();
String principal = auth.getPrincipal().toString();
Date expiration = new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME);
String token = Jwts.builder()
.setSubject(principal)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET.getBytes())
.compact();
AuthenticatedUser loginUser = new AuthenticatedUser(email);
loginUser.setToken(token);
String jsonUser = Util.objectToJsonResponseAsString(loginUser, "user");
res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
res.setContentType("application/json");
res.setCharacterEncoding(ConstantUtil.DEFAULT_ENCODING);
res.getWriter().write(jsonUser);
}
}
JWT Authorization Filter:
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
public JWTAuthorizationFilter(AuthenticationManager authManager) {
super(authManager);
}
@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(SecurityConstants.HEADER_STRING);
if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(SecurityConstants.HEADER_STRING);
if (token != null) {
// parse the token.
String user = Jwts.parser()
.setSigningKey(SecurityConstants.SECRET.getBytes())
.parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX, ""))
.getBody()
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
}
I think you can use authentication.getName
and principal.getName
in the injected controller argument of type Authentication
and Principal
:
@Controller
@RequestMapping("/info")
public class GetNameController {
@RequestMapping(value = "/name", method = RequestMethod.GET)
public String getName(Authentication authentication, Principal principal) {
System.out.println(authentication.getName());
System.out.println("-----------------");
System.out.println(principal.getName());
return "";
}
}
could produce
admin
-----------------
admin
It doesn't matter whether you are using token or basic spring security authentication as far as Authentication/Principal object is concerned.
In case of spring security, you can get your current logged in user by
1. Object user = Authentication authentication
(as you are already doing)
2.
Object user = SecurityContextHolder.getContext().getAuthentication()
.getPrincipal();
In both cases, user
will contains the user object you returning from UserDetailsService.loadUserByUsername(...)
. So using default UserDetailsService
you will get spring security's User
object which contains basic user information like username
, password
etc.
So in case if you are using default spring's UserDetailsService
, then you can get your current logged in user simply by
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication()
.getPrincipal();
String username = userDetails.getUsername();
You can use
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
System.out.println("--------------------------------------------------------------");
JwtUser jwtUser = (JwtUser) auth.getPrincipal();
//Get the username of the logged in user: getPrincipal()
System.out.println("auth.getPrincipal()=>"+jwtUser.getUsername() );
//Get the password of the authenticated user: getCredentials()
System.out.println("auth.getCredentials()=>"+auth.getCredentials());
//Get the assigned roles of the authenticated user: getAuthorities()
System.out.println("auth.getAuthorities()=>"+auth.getAuthorities());
//Get further details of the authenticated user: getDetails()
System.out.println("auth.getDetails()=>"+auth.getDetails());
System.out.println("--------------------------------------------------------------");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With