问题: 如果可能,我只想从 authenticate.getName()… 获取/提取用户名/电子邮件,而不是使用解析字符串。
authentication.getName() 或 principal.getName() 值:
[username]: org.springframework.security.core.userdetails.User@21463e7a: Username: butitoy@iyotbihagay.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities
在此示例中,我只想获取用户名的值,即 butitoy@iyotbihagay.com
解决方案:
因为我只想获取用户名/电子邮件 (butitoy@iyotbihagay.com),并且它正在返回整个主要内容/文本(以上),所以我将我在主题中设置的值从 pricipal value… 替换为电子邮件价值.. 现在可以使用了。
@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);
}
我现在可以使用不同的方式获取用户名/电子邮件值,就像你们建议的那样……甚至是我目前正在使用的方式。我现在不需要任何特殊的解析就可以从 Authentication 对象中获取电子邮件值。
在我以前使用 Spring 的非 RESTful 应用程序中…我可以使用注入控制器方法参数中的身份验证类轻松获取用户名。
控制器:
...
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);
}
...
安慰:
[username]: butitoy@iyotbihagay.com
现在,在我当前的项目中……我使用了 RESTful 方法,在成功验证后,我返回一个将在请求标头中使用/注入的令牌。我可以使用令牌登录…但是当我获得 authentication.getName() 的值时…返回的不仅仅是电子邮件地址,还包含一些其他信息。
控制台(REST + JWT):
[username]: org.springframework.security.core.userdetails.User@21463e7a: Username: butitoy@iyotbihagay.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities
我只想获得“butitoy@iyotbihagay.com”的用户名值。
JWT 身份验证过滤器:
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 授权过滤器:
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;
}
}
原文由 Borgy Manotoy 发布,翻译遵循 CC BY-SA 4.0 许可协议
I think you can use
authentication.getName
andprincipal.getName
in the injected controller argument of typeAuthentication
andPrincipal
:可以生产