提问者:小点点

如何将承载令牌存储到线程中。当前委托人


我必须在线程中保存一个令牌。CurrentPrincipal,以便随后将其传递给外部API,以免在此类应用程序中携带令牌。我检查令牌是否正确有效:

public class MyAuthenticationFilter : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext filterContext)
    {
        var authorization = filterContext.Request.Headers.Authorization;

        if (authorization == null || authorization.Scheme != "Bearer" || string.IsNullOrEmpty(authorization.Parameter))
        {
            filterContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
            return;
        }

        var principal = ValidateToken(authorization.Parameter);

        if (!principal.Identity.IsAuthenticated)
        {
            filterContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        }

        Thread.CurrentPrincipal = principal;

        if (filterContext.RequestContext != null)
        {
            filterContext.RequestContext.Principal = principal;
        }
    }

    public ClaimsPrincipal ValidateToken(string token)
    {
        SecurityToken securityToken;
        return new JwtSecurityTokenHandler().ValidateToken(token, GetTokenValidationParameters(), out securityToken);
    }

    #region Private Methods
    private static TokenValidationParameters GetTokenValidationParameters()
    {

        var identityServerUrl = StatiConfigurationService.Instance.GetValue("url");
        var client = new HttpClient();
        var res = client.GetAsync(identityServerUrl + "/.well-known/openid-configuration/jwks").GetAwaiter().GetResult();
        var keyList = new JsonWebKeySet(res.Content.ReadAsStringAsync().GetAwaiter().GetResult()).GetSigningKeys();

        var validation = new TokenValidationParameters()
        {
            ValidateIssuerSigningKey = true,
            ValidateIssuer = false,
            TokenDecryptionKeys = keyList,
            IssuerSigningKeys = keyList,
            RequireSignedTokens = true,
            RequireExpirationTime = true,
            ValidateLifetime = true,
            ValidIssuer = identityServerUrl,
            ValidAudience = "Vendor.Api",
            ValidateAudience = true,
        };
        return validation;
    }
    #endregion

}

有什么办法可以保存我的令牌吗?


共1个答案

匿名用户

我在代币使用方面也有问题。。。

我在做JWT和Spring保安...

当我从邮递员那里运行它时,我收到了这样一条信息:

缺少所需的请求正文:公共org.springframework.http.响应实体

我的json正文:

"usuario": "yenny.muller",
"usuarioConexion": "yenny.muller",
"contraseniaConexion": "ymuller12345"

这是我的代码:

public class JWTAuthorizationFilter extends OncePerRequestFilter {

    private final String HEADER = "Authorization";
    private final String SESSION = "sesion";
    private final String PREFIX = "Bearer ";
    private final String SECRET = "mySecretKey";
    public static final long EXPIRATION_TIME = 900_000; // 15 mins

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        try {
            boolean resultado_checktoken = checkJWTToken(httpRequest, httpResponse);
            if (resultado_checktoken) {
                Claims claims = validateToken(request);
                if (claims.get("authorities") != null) {
                    setUpSpringAuthentication(claims);
                } else {
                    SecurityContextHolder.clearContext();
                }
            } else {
                SecurityContextHolder.clearContext();
            }
            chain.doFilter(request, response);
        } catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException e) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
            return;
        }
    }

    private Claims validateToken(HttpServletRequest request) {
        //String jwtToken = request.getHeader(HEADER).replace(PREFIX, "");
        String jwtToken="";
        try {
            jwtToken = this.getBodySession(request);
        } catch (IOException e) {
            e.printStackTrace();
        };
        return Jwts.parser().setSigningKey(SECRET.getBytes()).parseClaimsJws(jwtToken).getBody();
    }
    
    /**
     * Authentication method in Spring flow
     * 
     * @param claims
     */
    private void setUpSpringAuthentication(Claims claims) {
        @SuppressWarnings("unchecked")
        List<String> authorities = (List<String>) claims.get("authorities");
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(claims.getSubject(), null,
                authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
        SecurityContextHolder.getContext().setAuthentication(auth);
    }

    private boolean checkJWTToken(HttpServletRequest request, HttpServletResponse res) throws IOException {
        String authenticationHeader = "";
        authenticationHeader = this.getBodySession(request);
        if (authenticationHeader == null || !authenticationHeader.startsWith(PREFIX))
            return false;
        return true;
    }

    public String getBodySession(HttpServletRequest request) throws IOException {
        String sbody = "";
        HttpServletRequest servletRequest = new ContentCachingRequestWrapper(request);
        //servletRequest.getParameterMap();
        sbody = servletRequest.getReader().lines().collect(Collectors.joining());
        String Field = SESSION;
        String scampo = "";
        if (sbody.contains(Field)) {
            scampo = sbody.substring(sbody.indexOf(Field), sbody.indexOf("\n", sbody.indexOf(Field)))
                    .replace(Field + "\": \"", "").replace("\"", "").replace(",", "");
        }
        System.out.println("sbody: " + sbody + " sesion: " + scampo);
        return scampo;
    }
}