Springboot通过控制器从身份验证中获取用户名

新手上路,请多包涵

问题: 如果可能,我只想从 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 许可协议

阅读 448
1 个回答

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

可以生产

admin
-----------------
admin

原文由 Richard H.M 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题